11

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);
          });
      });
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Kirk Strobeck
  • 17,984
  • 20
  • 75
  • 114

2 Answers2

5

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:

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

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I’ve tried `browser.executeScript`, but it doesn’t work; Any tricks about it? – Kirk Strobeck Jun 12 '15 at 18:43
  • @KirkStrobeck thanks for trying it out! What are the symptoms, do you see the element is getting focused and hovered in the browser? Any errors? Have you tried the "wait" approach? – alecxe Jun 12 '15 at 20:25
1

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

intika
  • 8,448
  • 5
  • 36
  • 55
  • This page doesn’t use any Angular – Kirk Strobeck Jun 12 '15 at 14:56
  • Ok... you could then just use the first solution or integrate `.onmouseover` and `.onmouseout` to your current function instead of `.mouseMove` ... any way this issue seems to be know for protractor https://github.com/angular/protractor/issues/159 – intika Jun 12 '15 at 15:07
  • Right, but that would require JS to do everything CSS does, which is a non-starter – Kirk Strobeck Jun 12 '15 at 18:42