Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor Wait for Animation to Complete

In our application, we have some questions to answer that will update a progress bar. Currently, I have a function that waits for HTML Attribute changes which works for most things, but it's a little finicky for the progress bar since the animation occurs over 1-2 seconds as the bar moves from 0 - 10% etc. So the failure I'm currently facing is things like: Expected 11 to be within range 12, 14.

Code:

Util.prototype.waitForAttributeChange = function (el, attr, time) {
    var timeout = time || 0,
        currentAttr;

    el.getAttribute(attr).then(function (val) {
        currentAttr = val;
        return currentAttr;
    }).then(function () {
        return browser.wait(function () {
            return el.getAttribute(attr).then(function (val) {
                return val !== currentAttr;
            });
        }, timeout);
    });
};

Usage:

Util.waitForAttributeChange(Page.progressBar(), 'style', 10000).then(function () {
    expect(Page.getProgressBarValue()).toBeWithinRange(12, 14);
};

Problem: The value grabbed is not the end result of the progress bar, it's still moving when it's grabbing it (because my function waits for Attribute changes, and the attribute did change at this point)

Question: Is there another way I can wait for an animation, specifically waiting for it to be completed? And/or is this possible without using browser.sleep()?

like image 303
Gunderson Avatar asked Jun 06 '16 12:06

Gunderson


1 Answers

You might be able to solve this problem by using Expected Conditions.

I use the below methods whenever I need to wait for an element to be visible then wait for it to go away before executing the next step. This is helpful for temporary confirmation modals that may block interaction with other elements.

let waitTimeInSeconds = 15;
let EC = protractor.ExpectedConditions;

secondsToMillis(seconds) {
    return seconds * 1000;
}

waitToBeVisible(element: ElementFinder) {
    browser.wait(EC.visibilityOf(element), this.secondsToMillis(waitTimeInSeconds), 'The element \'' + element.locator() + '\' did not appear within ' + waitTimeInSeconds + ' seconds.');
}

waitToNotBeVisible(element: ElementFinder) {
    browser.wait(EC.not(EC.visibilityOf(element)), this.secondsToMillis(waitTimeInSeconds), 'The element \'' + element.locator() + '\' still appeared within ' + waitTimeInSeconds + ' seconds.');
}
like image 194
Chris Traynor Avatar answered Nov 11 '22 06:11

Chris Traynor