what does isPresent() in protractor testing actually do? - angularjs

whether the isPresent() provides true
only when the element is present in the page
or
only when the element is visible in the page (while scroll down)
If it checks only the element is present in the page, whether there is any other method to provide true only when the element is visible.Kindly provide some input.
Edit:1
I had a scrolling problem while loading a page.ie(while loading the page it will scroll down to the middle of my page)
So I am using a scroll service which will load the page correctly from the top.
The point is while using scroll service the protractor test should pass and fail when not using it.
Now when using the scroll service all the elements will be visible,I using the isPresent() which is returning true
And when not using the scroll service some elements will not be visible due to scroll down,but still I am using the same element which is not visible with the isPresent() which is also returning true.

isPresent() returns a Promise not true or false.
If you want to check if an element is present, you actually have to look at the value that the promise resolves to:
element(anyFinder).isPresent().then(function(isPresent) {
if ( isPresent) {
// The element is present
} else {
// The element is not present
}
});

Related

How do I prevent errors when clicking an element on the page but not scrolled into view in nightwatch.js?

I am writing a test for an element on the page, but not scrolled into view. Whenever I use pageObject.click("#MyElement) on the element, it throws this error:
Error while running .clickElement() protocol action: element click intercepted: Element is not clickable at point (621, 929)
The element will then scroll into view after the error is thrown. Not sure what is happening here.
I have tried using pageObject.moveToElement("#selector").waitForElementVisible("#selector"), but it does not work.
When this happens to me, I usually scroll the targeted element into the view first, then proceed to do my actions and/or assertions on it.
We'll use the execute method:
browser.element('css selector', <targetElemSelector>, (result) => {
browser.execute('arguments[0].scrollIntoView({behavior: "instant", block: "center", inline: "center"})', [result.value]);
browser.click(result.value.ELEMENT);
});
This approach also gives you a lot of flexibility with positioning your targeted element via scrollIntoView's attributes: you can lock the element at the top, the bottom, or center like in the example. This is especially useful for when you have to avoid overlapping of marketing popups, chatbots, GDPR notifications, etc.

How can I run a function immediately after the CSS is set?

Target: I need to decide the bottom position of an element once the page loads.
What I tried: componentDidMount() life cycle method, which turned out to run after only the HTML markup is set, so the position value was wrong because the layout wasn't implemented yet.
Solved it with JS window.onload.
The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets images - mdn

AngularJS testing with Protractor - chaining promises- How to wait for animation to complete?

I am currently developing an automated test suite for an AngularJS application developed by my company. I have already designed & developed a number of test cases, which are running & passing/ failing as expected.
However, with the test that I am currently developing, I seem to have run into an issue when chaining promises, and am unable to solve it... The test script as it stands is:
it('should navigate to the browser page', function() {
console.log("Start browser page test");
browser.waitForAngularEnabled(false);
browser.wait(EC.visibilityOf(pagesMenuBtn), 10000).then(
browser.actions().mouseMove(pagesMenuBtn).perform().then(
//expect(pageBrowserBtn.isDisplayed()).toBeTruthy();
browser.wait(EC.visibilityOf(pageBrowserBtn), 12000).then(
pageBrowserBtn.click().then(
function() {
console.log("Browser menu button clicked");
//browser.pause();
}).then(
browser.wait(EC.visibilityOf(browserPageTagsLink), 20000).then(
function(){
console.log("End browser page test (then call)");
expect(browser.getCurrentUrl()).toBe(VM + '/#/pages/browser');
}
)
)
)
)
);
});
When I run my test script (I have a number of other tests that run before this one), the first few run & pass successfully, then when this test starts to execute, the console shows:
Started
....Start browser page test
Browser menu button clicked
F
Failures:
1) App should navigate to the browser page
Message:
Failed: Wait timed out after 20010ms
Stack:
TimeoutError: Wait timed out after 20010ms
at WebDriverError (C:\Users\path\selenium-webdriver\lib\error.js:27:5)
So from the output displayed in the console, it's clear that the test executes correctly as far as the console.log("Browser menu button clicked); statement, which indicates that a click has been performed on the menu button as I intend (i.e. the menu button clicked is displayed on a popup menu that is only shown when the cursor is hovering over the pagesMenuBtn element, so that indicates that the line
browser.wait(EC.visibilityOf(pageBrowserBtn), 12000).then(
is executed correctly).
Since the console.log("Browser menu button clicked"); statement is also displayed in the console, that indicates that the
pageBrowserBtn.click().then(
is also executed correctly.
But for some reason, the test is then timing out after the 20 seconds it waits for the browserPageTagsLink element to be displayed.
This browserPageTagsLink element is just a hyperlink element displayed on the 'Browser' page that my test is trying to navigate to- I am waiting for it to be visible so that I know that the page has loaded before I check that the URL is correct...
But as I watch what's happening in the browser window where these tests are run, and what's displayed in the console while my tests are running, the script seems to 'get stuck'/ pause/ 'hang' for a while after the Browser menu button clicked message is displayed in the console, and I can see from watching the browser window that this button was never actually clicked- the popup menu where this button is displayed is shown very briefly: the line browser.actions().mouseMove(pagesMenuBtn).perform() is causing the cursor to hover over the button required to show the sub-menu, but it seems that the click is performed before the sub-menu element has fully finished loading (there is some animation on the element- it appears to 'fade into view'), but I think that the click is happening before the element has fully finished loading, and so it's possibly not registering correctly?
How can I cause my test to wait for the animation to complete before trying to click the sub-menu menu item, so that the click registers with the element correctly?
I tried doing this with the line:
browser.wait(EC.visibilityOf(pageBrowserBtn), 12000).then(
It seems that the EC.visibilityOf(...) condition is met as soon as the element starts to become visible, rather than waiting until it is fully opaque, but that the
pageTagBrowserBtn.click().then(
line, which is called as soon as the condition is true can't actually be performed at this point- presumably because the element is not 'fully' visible at the point at which it's clicked?
How can I make my test wait for the animation (which has been implemented using CSS) to complete before it tries to click on the element?
I had a look on the Protractor API for anything about animations, but it only seems to provide the function allowAnimations()...
Edit
The animation for this element is set in the CSS with:
/* Animation for moving lists in configuration */
.list-fade.ng-enter,
.list-fade-leave.ng-leave {
-webkit-transition: all linear 0.5s;
transition: all linear 0.5s;
}
i.e. it should take 0.5 seconds for the element to be displayed when the cursor hovers over its parent element.
I tried adding a call to browser.wait(), so that my test would wait for the element to be fully displayed before trying to click on it- I updated the part of my test that is sending the click to:
browser.actions().mouseMove(pagesMenuBtn).perform().then(
//expect(pageTagBrowserBtn.isDisplayed()).toBeTruthy();
browser.wait(EC.visibilityOf(pageTagBrowserBtn), 12000).then(
browser.wait(10000).then(
pageTagBrowserBtn.click().then(
function() {
console.log("Tag Browser menu button clicked");
I told it to wait for 10 seconds at this point to ensure that it definitely gave the element enough time to load (according to the CSS, it should only take 0.5 seconds to be displayed), but for some reason, my test is still failing due to the same timeout issue.
Anyone have any suggestions?
Looking at your tests I'm wondering why you have to chain your promises like that. On a fully angular page Protractor is supposed to automatically chain promises, ie when I write a test like this
driver.get(“http://www.google.com”);
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.getTitle().then(function(title) {
console.log(title);
});
it actually is executed in a synchronous manner like this:
driver.get(“http://www.google.com”).
then(function() {
return driver.findElement(webdriver.By.name('q'));
}).
then(function(q) {
return q.sendKeys('webdriver');
}).
then(function() {
return driver.findElement(webdriver.By.name('btnG'));
}).
then(function(btnG) {
return btnG.click();
}).
then(function() {
return driver.getTitle();
}).
then(function(title) {
console.log(title);
});
If your page is fully Angular most of what you've written shouldn't need the promises, and that my be causing timing issues with your test. Have you tried writing the test without chaining promises?
That said, you might also try EC.elementToBeClickable(yourElement) instead of waiting for EC.visibilityOf() if you haven't already.

Protractor: verification of pop up elements randomly fails

I'm verifying and also clicking on elements of pop up window on Angular page with Protractor. The problem is that verification fails randomly.
My spec file:
describe('...
it('...
// initialize page object
var home = new homePage();
// hover over the shopping cart icon
browser.actions().mouseMove(home.shoppingCartLink).perform();
// pause browser for 4 sec
browser.sleep(4000);
// initialize page object
var shoppingCartPreview = new shoppingCartPage();
// hover over the shopping cart preview window
browser.actions().mouseMove(shoppingCartPreview.window).perform();
// verify elements are displayed
expect(shoppingCartPreview.shopName.isDisplayed()).toBeTruthy();
expect(shoppingCartPreview.price.isDisplayed()).toBeTruthy();
expect(shoppingCartPreview.delete.isDisplayed()).toBeTruthy();
// click on "Checkout" button
shoppingCartPreview.checkoutButton.click();
});
});
As wtritten, the problem is that for all the verifications I get falsy instead of truthy. What I'm doing wrong?
I even tried with the following without a success:
// waiting for elements to be visible
browser.wait(EC.presenceOf(shoppingCartPreview.popUpWindow),10000);
browser.wait(EC.presenceOf(shoppingCartPreview.shopName),10000);
browser.wait(EC.presenceOf(shoppingCartPreview.price),10000);
browser.wait(EC.presenceOf(shoppingCartPreview.delete),10000);
The problem is - you are waiting on - presenceOf() which only checks the presence of the element in DOM and hence it will always return true whether your pop-up is visible or not.
You need to wait like this leveraging visibilityOf() - browser.wait(EC.visibilityOf(shoppingCartPreview.popUpWindow), 5000)

Execution order of protractor tests

Which is the best way to control the execution order of Protractor tests?
Problem case 1: protractor swipes angular pages so quickly that it cannot manipulate (fill in) input data. (The swipe logic is to transfer from being invisible to visible and by translating them into the window visible area). thus protractor cannot see those beyond the window and with opacity 0. To test i can only fill in the first page. the others are swiped too fast (or async).
Problem case 2: After i filled in the first page and submitted the form, the data is saved and alert shows confirmation message. Then protractor has to click a drop-down list and browser should navigate to the page where saved data is displayed. The problem is that protractor clicks the drop-down list before the data is saved due to alert fired later (have to wait for alert).
Question is: Is there a way to control tests to be executed in the given order in protractor? And is there a way to hold down swiping to fill in the date (otherwise protractor does not see it)? Here is the simplified code:
it('should fill in form and send data', function() {
// fill in textarea field
element.all(by.css('textarea')).first().clear().sendKeys('test');
// goes to page 2
browser.executeScript("angular.element(document.documentElement)
.injector().get('$rootScope').$broadcast('nextPage', {direction: 'next'});");
// Here is Problem 1. Though i can see this page when testing,
// the input is not visible for protractor.
// fill in input-field
element.all(by.css('input')).first().clear().sendKeys('test');
// goes to page 1
browser.executeScript("angular.element(document.documentElement)
.injector().get('$rootScope').$broadcast('prevPage', {direction: 'prev'});");
// submit form
element(by.css('button[type=submit]')).click();
// Here is problem 2. The following test is executed earlier
// than the following alert.
//browser.wait(protractor.ExpectedConditions.alertIsPresent(), 3000);
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual('Saved');
alertDialog.accept();
});
it('should click drop-down-list', function() {
// click drop-down list
element(by.css('.drop-down-list')).click();
});
I personally believe browser.sleep(5000) should resolve the second issue.
if not can you try with promisies
element(by.css('button[type=submit]')).click().then(function(){
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual('Saved');
alertDialog.accept();
});
This should wait for the promise to get resolved (i.e to click submit button) and then execute the code snippet inside

Resources