Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test hover state changes with protractor

No matter what I do I can’t get the hover state functional with protractor tests. The following code is semi functional ..

  • Works well in Firefox
  • Only works when I scroll the area into view with Chrome.
  • Fails in Phantom JS

obj
  .getCssValue('color')
  .then(function (color1) {
    browser
      .actions()
      .mouseMove(obj)
      .perform()
      .then(function () {
        obj
          .getCssValue('color')
          .then(function (color2) {
            expect(color1)
              .not
              .toEqual(color2);
          });
      });
like image 827
Kirk Strobeck Avatar asked Jun 06 '15 00:06

Kirk Strobeck


2 Answers

We've encountered something similar recently.

What helped us was to wait for an element to have a specific CSS value using browser.wait():

function waitForCssValue (elementFinder, cssProperty, cssValue) {
    return function () {
        return elementFinder.getCssValue(cssProperty).then(function (actualValue) {
            return actualValue === cssValue;
        });
    };
};

Usage:

browser.wait(waitForCssValue(obj, 'color', color2), 5000);

Here, we are basically waiting up to 5 seconds for a CSS color value to be equal to color2. Apply the wait call right after you hover the element.


Also, I remember having that scrolling into view helped to resolve similar issues on SO:

browser.executeScript("arguments[0].scrollIntoView();", obj);

Maximizing browser window can also help, we usually do it in onPrepare():

onPrepare: function () {
    browser.driver.manage().window().maximize();
},

Additional note about PhantomJS:

First of all, protractor developers recommend against running protrator end-to-end tests with PhantomJS:

Note: We recommend against using PhantomJS for tests with Protractor. There are many reported issues with PhantomJS crashing and behaving differently from real browsers.

Aside from that, see:

  • Using Protractor with PhantomJS

Here I'm trying to get to the point, that you should sacrifice the "Fails in Phantom JS" argument.

like image 137
alecxe Avatar answered Nov 17 '22 11:11

alecxe


Solution 1 :

Just use a simple hover function for your object

<!DOCTYPE html>
<html>
<body>

<p onmouseover="colorin(this)" onmouseout="colorout(this)">
Testing colorin and colorout function for mouse hover
</p>


<script>
function colorout(x) {
    x.style.color = "#000000";
}

function colorin(x) {
    x.style.color = "#7FAF00";
}
</script>

</body>
</html>

Possible Solution 2 :

Try this version with waitForAngular(); you may need to wait for angular :

obj
  .getCssValue('color')
  .then(function (color1) {
    browser.waitForAngular();
    browser
      .actions()
      .mouseMove(obj)
      .perform()
      .then(function () {
        obj
          .getCssValue('color')
          .then(function (color2) {
            expect(color1)
              .not
              .toEqual(color2);
          });
      });

Possible Solution 3 :

Replace .mouseMove(obj) with .mouseMove(browser.findElement(protractor.B.id('foo'))) and adapt it to your code

like image 1
intika Avatar answered Nov 17 '22 11:11

intika