Reputation: 573
Have problem under beforeEach function in my test class.
Click on the usersTab sometimes works fine, and sometimes returns StaleElementReferenceException
.
Have tried protractor.ExpectedConditions
like presenceOf
or visibilityOf
or elementToBeClickable
but none worked in 100%.
I think that is caused by asynchronous and sometimes browser firstly want to click and afterwards wait - is it possible ?
Any idea how to handle it ?
var OnePage = require('../pages/one_page.js');
var SecondPage = require('../pages/second_page.js');
describe('Test', function () {
var onePage;
var secondPage;
var EC = protractor.ExpectedConditions;
beforeEach(function () {
browser.ignoreSynchronization = true;
onePage = new OnePage();
browser.wait(EC.presenceOf(onaPage.userLogin), 5000);
onePage.setUser('login@login');
onePage.setPassword('password');
onePage.login();
secondPage = new SecondPage();
browser.wait(EC.visibilityOf(secondPage.usersTab), 10000);
usersPage.usersTab.click();
});
I am using jasmine:2
and protractor:2.2.0
.
Upvotes: 0
Views: 914
Reputation: 546
When I first started to build my Test Suite I ran into a similar issue and it took me a while to track down a solution. When you initialize the Page Object using a standard var
in your beforeEach
function it can hold on to an old instance when the 2nd or higher test is run. No idea how long it typically takes or what really triggered the hiccup in my tests, it was always random for me. The only way I could solve this was to use the this
keyword in my beforeEach
function like the example below. When the beforeEach
function is executed the instance is correctly renewed in each test.
NOTE: In my conf.js file under onPrepare
I have the following function setup to tell Protractor if the page that follows is an Angular page or not:
global.isAngularSite = function(flag) {
browser.ignoreSynchronization = !flag;
};
var OnePage = require('../pages/one_page.js');
var SecondPage = require('../pages/second_page.js');
describe('Test', function () {
beforeEach(function () {
isAngularSite(true);
this.onePage = new OnePage();
this.secondPage = new SecondPage();
this.ec = protractor.ExpectedConditions;
browser.wait(this.ec.presenceOf(this.onePage.userLogin), 5000);
this.onePage.setUser('login@login');
this.onePage.setPassword('password');
this.onePage.login();
browser.wait(this.ec.visibilityOf(this.secondPage.usersTab), 10000);
usersPage.usersTab.click();
});
it('', function() {
});
});
Upvotes: 1
Reputation: 6962
Try chaining the actions with each other so that they execute serially once the first one is completed resolving its promise. Here's how -
beforeEach(function () {
browser.ignoreSynchronization = true;
onePage = new OnePage();
browser.wait(EC.presenceOf(onaPage.userLogin), 5000).then(function(){
onePage.setUser('login@login');
onePage.setPassword('password');
onePage.login();
});
secondPage = new SecondPage();
browser.wait(EC.visibilityOf(usersPage.usersTab), 10000).then(function(){
usersPage.usersTab.click().then(function(){
//If you want to verify something after click, do it here.
browser.sleep(500);
});
});
});
If you want the second page actions to be done only after first one, then chain them together.
browser.wait(EC.presenceOf(onaPage.userLogin), 5000).then(function(){
//Actions of OnePage
}).then(function(){
//Actions of second page
secondPage = new SecondPage();
browser.wait(EC.visibilityOf(usersPage.usersTab), 10000).then(function(){
usersPage.usersTab.click().then(function(){
//If you want to verify something after click, do it here.
browser.sleep(500);
});
});
});
Hope this helps.
Upvotes: 0