In one of our tests, we are testing the link (a
element) style changes after a mouse over.
By default, the link has a black font without decoration, but on mouse over the font changes to blue and the link text becomes underlined. Here is the relevant test:
it("should change font style on mouse over", function () {
expect(scope.page.forgotPassword.getCssValue("color")).toEqual("rgba(11, 51, 60, 1)");
expect(scope.page.forgotPassword.getCssValue("text-decoration")).toEqual("none");
browser.actions().mouseMove(scope.page.forgotPassword).perform();
expect(scope.page.forgotPassword.getCssValue("color")).toEqual("rgba(42, 100, 150, 1)");
expect(scope.page.forgotPassword.getCssValue("text-decoration")).toEqual("underline");
});
The problem is that in about 1 out of 10 runs, it is failing with the following error messages:
Expected 'rgba(11, 51, 60, 1)' to equal 'rgba(42, 100, 150, 1)'.
Expected 'none' to equal 'underline'.
I suspect that it reads the css styles before they actually change.
What can I do to make the test more reliable and stable? Would appreciate any hints.
Following @P.T.'s suggestion, I've ended up making a custom reusable "Expected Condition":
Example usage:
This asynchrony in the CSS update seems like something that protractor/webdriver should be able to wait for. Is your app doing anything unusual to implement the CSS update on hover? Is it specifying an animation or update delay somehow?
That said, I think there can be times when protractor cannot know that an update may take some time, so I think you can write the test with a different approach. Instead of expecting the value to be what you want (and racing with the change in the browser), can you re-phrase the test as "wait-until-value-I-want-shows-up"? (The failure case is a little slower and uglier, but hopefully that is rare.)
Checking for the
text-decoration
to move to 'underline' seems simpler (and presumably both will change "at once", so you only need to wait for one and can then check the other?)So remove:
and use something like this untested code:
(Or use the Expected Conditions infrastructure for this ?)
You should be able to hide some of the ugliness in a function: