12

While writing selenium tests in Python, I got used to using Explicit Waits a lot for waiting for a page to load, or for waiting for an element to become visible, or clickable etc:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "myDynamicElement"))
)

The key concept here is providing an Expected Condition to wait for, there are multiple types:

Using Expected Conditions makes the code cleaner and more reliable comparing to using sleeps with hardcoded time intervals.

Now, we are switching our end-to-end testing infrastructure to protractor a lot.

Are there similar Expected Conditions in protractor as there are in python-selenium or java-selenium? If not, what is the canonical way to explicitly wait for a condition in protractor?

I've looked through protractor documentation and found nothing about it.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Is this what you want? https://github.com/angular/protractor/pull/1703 – hankduan Jan 09 '15 at 05:03
  • @hankduan only if the build would not fail :) Joking, exactly, super awesome! If you have time - please post an answer about the feature here, if not - I can do it istead, lmk. Thank you! – alecxe Jan 09 '15 at 05:17

3 Answers3

19

Once feat(expectedConditions) is in (probably protractor 1.7), you can do:

var EC = protractor.ExpectedConditions;
var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);
expect(e.isPresent()).toBeTruthy();

Please note though, if you're working with an Angular app and your test requires these conditional waits, it's a big red flag for what you're doing, as protractor should handle waits natively.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
hankduan
  • 5,994
  • 1
  • 29
  • 43
  • 1
    Regarding your last comment about the red flag..how would you wait for an element to be not clickable (=disabled or invisible) currently in protractor 1.5? Thank you. – alecxe Jan 10 '15 at 07:52
  • 1
    Ideally, when your page settles (i.e. waitForAngular finishes as part of protractor), nothing in your page should change. (i.e. your element will either be clickable or not, and waiting will not cause its state to change). I know there are cases where this is not true, like certain animations and when setTimeout is involved (although ideally, you want to replace setTimeout with interval service). So yes there are cases where you have to add waits even for angular apps, but most of the time, it's an error in the test. – hankduan Jan 10 '15 at 08:04
  • 1
    @hankduan: It seems that our tests fail frequently without these expected conditions (pure angular app). Sometimes even with. I wonder if anyone else is experiencing this kind of inconsistency. – VSO Aug 12 '15 at 19:08
  • @VSO I found sometimes animations contribute to this - protractor may think an element is clickable according to the EC, but somehow an ongoing animation / css transition blocks this. I've got a possible solution recently posted here: http://stackoverflow.com/a/32264842/446030 – JcT Aug 28 '15 at 07:03
  • To my experience, a `browser.wait(//protractor.ExpectedConditions)` is needed [when an action triggers a non-Angular async task](https://github.com/angular/protractor/issues/909), like a full page to be loaded. Maybe it's also (only?) required [when it triggers a route change](https://github.com/angular/protractor/issues/2358). – ThCollignon Aug 30 '18 at 12:04
1

In Protractor you can use browser.wait(fn, timeout).

Example:

var element = by.id('myDynamicElement');
browser.wait(function() {
  return ptor.isElementPresent(element);
}, 10000);

expect(ptor.isElementPresent(element)).toBeTruthy();
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Surya
  • 4,446
  • 2
  • 17
  • 19
  • Yes, I think this is it, though I'm really missing all the expected conditions - shortcuts provided by other selenium language bindings. Thank you! – alecxe Jan 03 '15 at 01:55
  • FYI, I've created a github issue on protractor's issue tracker: [Expected conditions in protractor](https://github.com/angular/protractor/issues/1681). – alecxe Jan 03 '15 at 02:05
  • The current version (2.0.0 in this moment) supports: browser.wait(fn, timeout, errorMessage). Helpful to add a specific error message. – Mike Park Apr 16 '15 at 20:17
-1
waitForControlVisible(locator: string, timeout: number) {
    try {
        const element = this.findElement(locator);
        const condition = browser.ExpectedConditions;
        browser.wait(condition.visibilityOf(element), timeout);
    } catch (e) {
        console.log(e.message);
        console.error('Control not visible.', e);
    }
}

Maybe help you, wait for element visibility in DOM.

Dao Minh Dam
  • 373
  • 1
  • 2
  • 14