in my recent test I need to first login and take some actions on an non angular page (https://www.qa.dealertrack.com/default1.aspx)
then switch to an angular page and finish the test.
In conf I have
global.driver = browser.driver;
My page object looks like:
var LogInPage = function() {
this.loginUrl = 'https://www.qa.dealertrack.com/default1.aspx';
this.id = browser.driver.findElement(by.name('username'));
this.password = browser.driver.findElement(by.name('password'));
this.loginButton = browser.driver.findElement(by.name('login'));
this.logIn = function(id, password) {
// maximize window
driver.manage().window().maximize();
// log in
driver.get('https://www.qa.dealertrack.com/default1.aspx');
this.id.sendKeys(id);
this.password.sendKeys(password);
this.loginButton.click();
}
};
My test looks like:
describe('Sample Test - Log In', function() {
var loginPage = require('../pages/LogInPage.js');
/**
* Disable waiting for AngularJS for none Angular page
*/
beforeEach(function() {
isAngularSite(false);
});
it('logging in', function() {
loginPage.logIn('xxx', 'xxx');
})
})
However, even before getting to the site, protractor throws error NoSuchElementError: no such element: Unable to locate element:{'method':'name','selector':'username'}
But when I commented out all the element variables and related lines, only left
driver.get(this/loginUrl);
It worked. Why would browser.driver.get works but browser.driver.findElement does not?
This is my first question on Stackoverflow. Thank everyone!!
Before login you need to set
browser.driver.ignoreSynchronization=true;
So it shold be like
browser.driver.ignoreSynchronization=true;
login();
browser.driver.ignoreSynchronization=false;
I tried to removed all the elements I declared outside my functions in page object. Instead of that, I just hard code the elements in the function. And it worked.
Related
I'm new with Protractor and jasmine framework to test an AngularJS Application.
I whould like to reuse some of my scenarios, like Login feature can call in all scenarios of my suite.
This is my login_test.js
module.exports = function(testName, testFn) {
const loginPage = pages.login;
const mainPage = pages.main;
var protractor;
describe('common Login suite', function() {
browser.ignoreSynchronization = true;
beforeEach(function() {
});
afterAll(function() {
browser.manage().deleteAllCookies();
});
it(testName, function() {
browser.get('http://localhost:9000/');
loginPage.typeUserName('bxxxxx');
loginPage.typePassword('xxxxxx');
loginPage.clickLogin();
});
});
}
And here I have the remote_terminal feature, here I need call Login feature to perfom login in my scenario.
var loginSuite = require('./login_test.js');
loginSuite('login Suite terminal feature', function(browser) {
describe('description', function() {
console.log('describe');
it('it', function() {
console.log('it');
});
});
});
But when this spec (remote_terminal) is called to run I got this message on my console
Started
Spec started
.
common Login suite
✓ login Suite terminal feature
As you can see the describe and IT in the remote_terminal spec aren't ran.
Demo:
http://pavelbogomolenko.github.io/dry-principles-with-protractor.html
You can use pageObjects to achieve reusable code accross your test,
Let us create a new js file for login page as login_page.js as below,
var login_page = function(){
this.performLogin = function(){
//add code for performing login operation.
}
}
module.exports = new login_page();
Now you can import the login_page.js in all 'specs' and can call the performLogin() method whenever required.
Look at the example spec.js below,
describe("Test pageobject code",function(){
var login_page = require("login_page.js");
beforeAll(function(){
login_page.performLogin();
})
it("simple test to perform after login action is performed",function()
//do whatever you want to test
})
})
I've just started to use Protractor. I created several page objects and everything is working fine till now. I log in to a page and I'm being redirected to the myaccount page.
On that page, I got the following error:
Error while waiting for Protractor to sync with the page: "window.angular is undefined.
My code is here:
var myaccount = function(){
//some function but everything is commented out
};
module.exports = new myaccount();
Here is my login test as well:
this.loginSuccess = function(){
userName.sendKeys(params.registration.email);
password.sendKeys(params.registration.password);
submitButton.click();
};
After the click, myaccount page appears but the protractor throws the mentioned error.
Could somebody help me with this?
window.angular is undefined means you are trying to make protractor go to a page that is not angular
See the answer from mcalthrop here: https://github.com/angular/protractor/issues/610
Can use like
var newpage = new RegExp('welcome', 'i');
submitButton.click();
waitForUrlToChangeTo(newpage).then(function () {
expect(browser.getTitle()).toEqual('Welcome!');
});
/**
* #name waitForUrlToChangeTo
* #description Wait until the URL changes to match a provided regex
* #param {RegExp} urlRegex wait until the URL changes to match this regex
* #returns {!webdriver.promise.Promise} Promise
*/
function waitForUrlToChangeTo(urlRegex) {
var currentUrl;
return browser.getCurrentUrl().then(function storeCurrentUrl(url) {
currentUrl = url;
}
).then(function waitForUrlToChangeTo() {
return browser.wait(function waitForUrlToChangeTo() {
return browser.getCurrentUrl().then(function compareCurrentUrl(url) {
return urlRegex.test(url);
});
});
}
);
}
i'm new with protractor.. i need you'r help..
my code go like this..
describe('Protractor Demo Charts', function () {
var url = 'https://angularjs.org/';
it('should get the value of attribute d', function () {
browser.get(url);
element(by.css('.btn-warning')).click().then(function(text){
expect(browser.getCurrentUrl()).toContain('0BxgtL8yFJbacQmpCc1NMV3d5dnM');
}
);
});
});
my problem is that browser.getCurrentUrl() still return me the base url (the page that i came from 'https://angularjs.org/' )
how can i get the new Url (the URL AFTER the click )?
May you should wait until the page has been loaded.
Try this way :
describe('Protractor Demo Charts', function () {
var url = 'https://angularjs.org/';
it('should get the value of attribute d', function () {
browser.get(url);
browser.sleep(2000);
$('.btn-warning').click();
expect(browser.getCurrentUrl()).toContain('0BxgtL8yFJbacQmpCc1NMV3d5dnM');
});
});
From the doc:
Protractor will ensure that commands will automatically run in sync. For example, in the following code, element(by.model(...)).click() will run before browser2.$('.css').click():
browser.get('http://www.angularjs.org');
browser2.get('http://localhost:1234');
browser.sleep(5000);
element(by.model(...)).click();
browser2.$('.css').click();
I'm evaluating using Casper.js to do functional/acceptance testing for my app. The biggest problem I've seen so far is that my app is an SPA that uses handlebars templates (which are compiled to JS) The pages of my app are nothing more than a shell with an empty div where the markup will be injected via JS.
I've messed around with Casper a little and tried using its waitFor functions. All I can seem to get from it are my main empty page before any of the markup is injected. I've tried waitForSelector but it just times out after 5 seconds. Should I try increasing the timeout? The page typically loads in a browser very quickly, so it seems like there may be another issue.
I'm using Yadda along with Casper for step definitions:
module.exports.init = function() {
var dictionary = new Dictionary()
.define('LOCALE', /(fr|es|ie)/)
.define('NUM', /(\d+)/);
var tiles;
function getTiles() {
return document.querySelectorAll('.m-product-tile');
}
function getFirstTile(collection) {
return Array.prototype.slice.call(collection)[0];
}
var library = English.library(dictionary)
.given('product tiles', function() {
casper.open('http://www.example.com/#/search?keywords=ipods&resultIndex=1&resultsPerPage=24');
casper.then(function() {
// casper.capture('test.png');
casper.echo(casper.getHTML());
casper.waitForSelector('.m-product-tile', function() {
tiles = getTiles();
});
});
})
.when('I tap a tile', function() {
casper.then(function() {
casper.echo(tiles); //nodelist
var tile = Array.prototype.slice.call(tiles)[0];
casper.echo(tile); //undefined!
var pid = tile.getAttribute('data-pid');
})
})
.then('I am taken to a product page', function() {
});
return library;
};
Any Angular, Backbone, Ember folks running into issues like this?
I'm trying to create some tests for my app, using protractor.
The browser.get is ok, and when my page is loaded and my app bootstraped, the first test is running.
it('should go to the where and when page', function() {
var nextButton = element(by.id('cg_btnValidationQuoi'));
expect(nextButton.getText()).toBe('Suivant');
}
This cause a timedout.
it('should go to the where and when page', function() {
var nextButton = element(by.id('cg_btnValidationQuoi'));
nextButton.click()
}
Cause "Error: No element found using locator: By.id("cg_btnValidationQuoi")"
it('should go to the where and when page', function() {
var nextButton = element(by.id('cg_btnValidationQuoi'));
expect(nextButton.getInnerHtml()).toBe('Suivant');
}
Cause :
Message:
Expected '
Suivant
' to be 'Suivant'.
Does it sound like anything that anybody knows?
toBe() checks to see if its the exact same object (string). I'd suggest using toEqual() and see if it works. More info in this SO Answer