Thrillofit86
Thrillofit86

Reputation: 619

How to wait for element using mocha, chai & protractor

So my idea was to make a function that is trying to find a element for x seconds. If the element is not presented (Be able to write on the element) and/or not able to send any keys to the element then wait. If it passed given wait seconds (etc 10 sec) then it should throw a exception.

For right now I did:

    it('enter email', function (done) {
        browser
            .then(() => browser.wait(piPage.getEmailValue().isPresent(), 10000)) 
//getEmailValue = element(by.id('email').getAttribute("value");
            .then((isPresent) => {
                assert.equal(isPresent, true, 'Email failed entering.')
            })
            .then(() => piPage.enterEmail("[email protected]"))
            .then(() => done());
    });

which actually finds the element and send keys if the value is presented. HOWEVER it seems that the 10 seconds browser.wait doesn't seem to apply and it instead immediately triggers without waiting at all. I had to manually add

browser.driver.sleep(10000).then(function() {
    console.log('waited 10 seconds');
}); 

but it isnt something I want.

What I would like to do is that have browser.wait to find the element is presented/able to send_keys until x seconds and then if the element is found then we continue, else throw a exception basically.

Upvotes: 0

Views: 1751

Answers (2)

Hamdy
Hamdy

Reputation: 440

When you pass 10 s it's actually said: i will give you 10 s to find it but if you find it before the 10s return the value expected

Schedules a command to wait for a condition to hold. The condition may be specified by a {@link webdriver.Condition}, as a custom function, or as a {@link webdriver.promise.Promise}.

For a {@link webdriver.Condition} or function, the wait will repeatedly evaluate the condition until it returns a truthy value. If any errors occur while evaluating the condition, they will be allowed to propagate. In the event a condition returns a {@link webdriver.promise.Promise promise}, the polling loop will wait for it to be resolved and use the resolved value for whether the condition has been satisified. Note the resolution time for a promise is factored into whether a wait has timed out.

Note, if the provided condition is a {@link WebElementCondition}, then the wait will return a {@link WebElementPromise} that will resolve to the element that satisified the condition.

Example: waiting up to 10 seconds for an element to be present and visible on the page.

The only solution as I know is to use sleep()

I recommended to use instead of many then()

import { browser, element, by, ExpectedConditions as ec } from 'protractor';

    await browser.wait(ec.visibilityOf(element(by.id('menu-id')), 5000);

Upvotes: 0

Joaquin Casco
Joaquin Casco

Reputation: 734

The isPresent() method waits for the element to be present in the html DOM, but that doesn't necessarily means the element is interactable yet. For that you'd need to chain it with an explicit wait like elementToBeClickable(element)

const EC = protractor.ExpectedConditions;

waitForElement = async () => {
    const present = await yourElement.isPresent();
    if (present) {
        await browser.wait(EC.elementToBeClickable(yourElement));
        await yourElement.sendKeys('something');
    }
};

Upvotes: 1

Related Questions