Protractor : In a particular page, none of the protractor actions are working - protractor

My protractor script is working fine until a page where reveal.js package is used. I am not sure if that is the reason it causes the scripts to fail, but otherwise the code base is same as the other pages where my scripts works fine.
Note: I tried most of the protractor actions (click, highlight, waitForElement, toContain, etc), none of them worked. I could only click the links by inserting jQuery in my script.
CODE:
let HighlightElement = function (el) {
return browser.executeScript("arguments[0].setAttribute('style', arguments[1]);", el.getWebElement(), "color: Red; border: 1px solid red;").
then(function (resp) {
browser.sleep(2000);
return el;
}, function (err) { });
}
let waitUntilElementPresent = function (visibilityOfObject, maxWaitTime) {
var EC = protractor.ExpectedConditions;
browser.manage().timeouts().implicitlyWait(2);
browser.wait(function () {
browser.manage().timeouts().implicitlyWait(3);
return visibilityOfObject.isDisplayed()
.then(
function (isDisplayed) {
browser.wait(EC.visibilityOf(visibilityOfObject), maxWaitTime, "Element taking more time to load");
browser.manage().timeouts().implicitlyWait(3);
return isDisplayed;
},
function (error) {
return false;
});
}, 100000);
}
ACTUAL CODE:
var homepage = new homePageObj();
utilities.waitUntilElementPresent(homepage.waitScreenText); //here the script is failing. It is just a simple script and it used to work in other pages but it doesn’t work only in some of the pages
utilities.HighlightElement(homepage.waitScreenText);
utilities.HighlightElement(homepage.startButton);
homepage.startButton.click();
Error:
Failed: Wait timed out after 120062ms
Using below jQuery I am able to click, but we need to give wait time explicitly for each and every java script that we use, which is time consuming. I am beginner in automation, Kindly help me with a solution.
browser.executeScript("document.getElementsByClassName('cc-button')[0].click()");

My code started running after proving "browser.waitForAngularEnabled(false)" at the start of the script.

Related

In protractor, I want the code to handle based on if OTP triggers and if not, I can login to the home page or any page and cont do the work

I am new to coding and as well as to protractor.
In protractor, I want the code to handle based on if OTP triggers go and retrieve OTP and if not, login to the home page or any page and continue to do the actions in the home page. I was trying to do an if else check with
I tried as like below
browser.getcurrentUrl().toEqual().then function()
{
statements;
},
I don't think it works. Can someone help?
below is my code snippet.
Basically i was trying to check the url, if it contains specific texts in it, I dont want anything to perform further execution want to exit out of execution. If the url doesnt contain anything specified I want to proceed with further execution.
The if condition is working fine. but not the else part.
var HomePages = require('../Pages/HomePage.js');
var EC = protractor.ExpectedConditions;
describe(‘Check_url function’, function() {
browser.wait(EC.urlContains(’some url’),2000).then(result => {
if (result) {
console.log('Sorry!!!!!!!, Encountered PassCode Authentication Process.
Execution cant be proceed further');
} else {
HomePages.profile();
browser.driver.sleep(300);
}
});
});
//////////////////////////
HomePages.js -
'use strict';
module.exports = {
Homepage: {
usrname: element(by.className('profile-name')),
usricon: element(by.css('[title="profile"]')),
Cli_id: element(by.css('[title=“Client ID"]'))
},
profile: function() {
this.click_Profile();
},
click_Profile: function() {
var angular3 = this.Homepage;
angular3.usricon.click();
},

Protractor - Ignore Synchronisation flag

I have started doing a POC on Protractor as our e2e automation testing tool.
Our application is designed in angular which makes it a perfect fit.
However, I need to login via google which is a non-angular website and therefore at the start of my test I state
browser.ignoreSynchronization = true;
Then I go to
'https://accounts.google.com/ServiceLogin'
Enter my google credentials and click on signin
At this point I try to go to my application's URL, which is an angular application so I was hoping to turn
browser.ignoreSynchronization = false;
All the the above steps are part of a beforeEach so that I can login before each test
But when I turn ignoreSynchronization to false, all my tests start failing.
On the other hand, if I don't turn it to false, I am compelled to use a lot of browser.sleeps as Protractor is still treating it as a non-angular app and does not wait for angular to load fully
I have also tried to put the ignoreSynchronization = false in each individual test as opposed to beforeEach but even then all my tests start failing.
Below is my beforeEach code
browser.ignoreSynchronization = true;
browser.driver.manage().window().setSize(1280, 1024);
browser.get(googlelogin);
email.sendKeys('username');
next.click();
browser.wait(EC.visibilityOf(pwd), 5000);
pwd.sendKeys('pwd');
signin.click();
browser.ignoreSynchronization = false;
browser.driver.get(tdurl);
Few things to fix:
wait for the "click" to go through
use browser.get() on the Angular Page
Here are the modifications:
signin.click().then(function () {
browser.ignoreSynchronization = false;
browser.get(tdurl);
browser.waitForAngular(); // might not be necessary
});
You may also add a wait with an Expected Condition to wait for the login step to be completed - say, wait for a specific URL, or page title, or an element on the page.
Reconciliation_verifyExapanedDatainExpanedRow: function (HeaderName, texttobepresent) {
browser.waitForAngular().then(function () {
var EC = protractor.ExpectedConditions;
var columnHeaderActive = GUtils.$locatorXpath('//p-datatable//span[contains(text(),"' + HeaderName + '")]/..//span[#class="ui-cell-data"][contains(.,\'' + texttobepresent + '\')]');
browser.wait(EC.presenceOf(GUtils.$element(columnHeaderActive)), GUtils.shortDynamicWait()).then(function () {
console.log('PASS');
}, function (err) {
console.log('FAIL');
});
});
},

Protractor how to wait for options

I have code like this:
element(by.model("roleSelection.role")).element(by.cssContainingText('option', newRole)).click();//.then(function() {console.log('role click')})//;
where the options is loaded via a call to the server.
I can wait for the first element by doing this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
return present;
});}, 8000);
and it seems to work. But how can I wait until the "sub-element" is clickable.
I have tried this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
if (present) {
var elm = element(by.model("roleSelection.role"));
return elm.isElementPresent(by.cssContainingText('option', newRole)).then(function(subpresent) {
return subpresent;
});
}
}); }, 8000);
Have you tried clickable? Something along these lines
var EC = protractor.ExpectedConditions;
var select = element(by.model("roleSelection.role"))
var isClickable = EC.elementToBeClickable(select);
browser.wait(isClickable,5000); //now options should have been loaded by now
Well, try to this: https://angular.github.io/protractor/#/api?view=ExpectedConditions.prototype.elementToBeClickable
But, Please keep in mind, Protractor is suitable for angular webpages and interactions, and animations. For example ng-animate. So, it is not sure to working for example jquery, or other animates.
In this way:
onPrepare: function () {
// disable animations when testing to speed things up
var disableNgAnimate = function () {
angular.module('disableNgAnimate', []).run(function ($animate) {
$animate.enabled(false);
});
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
}
Or you can switch in script way in browser.executeScript().
Please see this link. It works only jquery animations.
If you not have animate problems. Use setTimeout() JS function.

How to wait the page to test is loaded in non angular site?

I've tried this:
browser.wait(function () {
return browser.executeScript('return document.readyState==="complete" &&' +
' jQuery !== undefined && jQuery.active==0;').then(function (text) {
return text === true;
});
}, 30000);
If jQuery.active==0 then page is completely loaded. This should work for sites with JQuery and non angular pages.
However, I have many problems of instability to test for non angular sites.
How to fix this?
By default protractor waits until the page is loaded completely. If you are facing any error then it is because protractor is waiting for the default time to be completed, that you have specified in your conf.js file to wait until page loads. Change the value to wait a for longer time if you think your app is slow -
// How long to wait for a page to load.
getPageTimeout: 10000, //Increase this time to whatever you think is better
You can also increase the defaultTimeoutInterval to make protractor wait a little longer before the test fails -
jasmineNodeOpts: {
// Default time to wait in ms before a test fails.
defaultTimeoutInterval: 30000
},
If you want to wait for any particular element, then you can do so by using wait() function. Probably waiting for last element to load is the best way to test it. Here's how -
var EC = protractor.ExpectedConditions;
var lastElement = element(LOCATOR_OF_LAST_ELEMENT);
browser.wait(EC.visibilityOf(lastElement), 10000).then(function(){ //Alternatively change the visibilityOf to presenceOf to check for the element's presence only
//Perform operation on the last element
});
Hope it helps.
I use ExpectedConditions to wait for, and verify page loads. I walk through it a bit on my site, and example code on GitHub. Here's the gist...
Base Page: (gets extended by all page objects)
// wait for & verify correct page is loaded
this.at = function() {
var that = this;
return browser.wait(function() {
// call the page's pageLoaded method
return that.pageLoaded();
}, 5000);
};
// navigate to a page
this.to = function() {
browser.get(this.url, 5000);
// wait and verify we're on the expected page
return this.at();
};
...
Page Object:
var QsHomePage = function() {
this.url = 'http://qualityshepherd.com';
// pageLoaded uses Expected Conditions `and()`, that allows us to use
// any number of functions to wait for, and test we're on a given page
this.pageLoaded = this.and(
this.hasText($('h1.site-title'), 'Quality Shepherd')
...
};
QsHomePage.prototype = basePage; // extend basePage
module.exports = new QsHomePage();
The page object may contain a url (if direct access is possible), and a pageLoaded property that returns the ExepectedCondition function that we use to prove the page is loaded (and the right page).
Usage:
describe('Quality Shepherd blog', function() {
beforeEach(function() {
// go to page
qsHomePage.to();
});
it('home link should navigate home', function() {
qsHomePage.homeLink.click();
// wait and verify we're on expected page
expect(qsHomePage.at()).toBe(true);
});
});
Calling at() calls the ExpectedCondidion (which can be be an and() or an or(), etc...).
Hope this helps...

Waiting for Ionic Loading dialogs with Protractor

There are similar questions (linked below) but none solves this problem. I'm writing Protractor tests for an Ionic Project. I need to execute tests at times when an Ionic Loading dialog appears and disappears.
I've created a repo with the bare bones of the app and the tests that need to be made. Solve this and you solve the problem (I describe the problem below): https://github.com/TmanTman/StackoverflowQ. Just adapt the path to your Chrome for your system in conf.js.
To simulate an asynchronous Ionic Loading dialog I just add this to the controller in a blank Ionic project:
$interval( function() {
$ionicLoading.show({
template: 'Async ionicLoading',
duration: 5000
});
}, 5000 , 1);
})
I need to get protractor to wait for the dialog to appear, do some tests, wait for the dialog to disappear, and then do some more tests. My latest attempt in my test file is:
it('should only test when ionicLoading appears', function() {
browser.wait(function(){
return element(by.css('.loading-container.visible.active')).isPresent();
}, 10000);
var ionicLoadingText = element(by.css('.loading-container.visible.active')).getText();
expect(ionicLoadingText).toEqual('Async IonicLoading');
})
it('should only test once ionicLoading disappears', function() {
browser.wait(function() {
var deferred = protractor.promise.defer();
var q = element(by.css('.loading-container.visible.active')).isPresent()
q.then( function (isPresent) {
deferred.fulfill(!isPresent);
});
return deferred.promise;
});
expect(1).toEqual(1);
})
I'm trying to avoid using synchronous sleep function, as my code is highly asynchronous. I've tried countless variations but I can't get it to work. Links I've used for info includes:
Protractor blocking wait
Asynchronous Testing with Protractor's ControlFlow
Protractor wait for isElementPresent and click on waited element fails
The problem is two-fold:
1) From what I can deduce, the duration property of the $ionicLoading method is implemented with a timeout function. Protractor does not work well with $timeout. So instead of using the duration property, the $ionicLoading dialog can be hidden with a $interval call (adapting the code from the question):
$interval( function() {
$ionicLoading.show({
template: 'Async IonicLoading'
});
$interval( function() {
$ionicLoading.hide();
}, 5000, 1)
}, 5000 , 1);
2) The code to detect the asynchronous change is the following:
it('should only test when ionicLoading appears', function() {
browser.wait(function() {
var deferred = protractor.promise.defer();
var q = element(by.css('.loading-container.visible.active')).isPresent()
q.then( function (isPresent) {
deferred.fulfill(isPresent);
});
return deferred.promise;
}, 10000);
var ionicLoadingText = element(by.css('.loading-container.visible.active')).getText();
expect(ionicLoadingText).toEqual('Async IonicLoading');
})
it('should only test once ionicLoading disappears', function() {
browser.wait(function() {
var deferred = protractor.promise.defer();
var q = element(by.css('.loading-container.visible.active')).isPresent()
q.then( function (isPresent) {
deferred.fulfill(!isPresent);
});
return deferred.promise;
}, 10000);
expect(1).toEqual(1);
})
Then both tests pass.