nightwatch: .click() not working occasionally

Sometimes nightwatch.js .click() method works and other times it doesn’t. I even put a .pause() to make sure the button is visible, I also inspect the element (while paused) to make sure it has the correct selector Im using and it does, but it just won’t click the element. Sometimes it does work though, any ideas?

module.exports = { 'Step 8: Search Inventory' : function (browser) { browser .waitForElementVisible('button.searchInventory', 3000) .click('button.searchInventory') .waitForElementVisible('div.newVehicleHeader > h2', 6000) .assert.elementPresent('div.newVehicleHeader > h2') .end();} };

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 25 (3 by maintainers)

Most upvoted comments

This is not a Selenium-specific bug but a Nightwatch bug. There have been many issues open about click() not working in a consistent manner, but you seem to always close them without any fix. If you don’t want/are unable to fix this bug, please leave it open so that someone else can fix it. As a popular open source project you may have to rely on the community to fix issues.

Please see this answer on the mailing list: https://groups.google.com/forum/#!topic/nightwatchjs/3KXgjq7YiKY. You are reporting an issue with WebDriver/Selenium and not something that we can fix in Nightwatch.

Is it possible the element is not enabled? Does it make sense for Nightwatch to offer .waitForElementClickable which checks visible + enabled?

@darrylivan We’ve found this frequently is caused by popups whose appearance isn’t predictable due to e.g. A/B testing. For affected pages, we’ve added an angryClick command, which on a click failure assumes there is some modal DIV capturing events, clicks on the BODY to dismiss it, then retries the click target. (YMMV, use whatever “click outside the popup” event works on your site.) Hope it helps:

// Wrapper around standard .click()
//
// If click fails, it might be because something is in the way.
// Try dismissing lightboxes/overlays by clicking on the body tag,
// then click again.
exports.command = function angryClick(selector, callback) {
  var self = this;
  return this.click(selector, function(result) {
    if (result.status == 0) {
      // click succeeded, handle callback
      if (typeof callback === 'function') {
        callback.call(self, result);
      }
    }
    else {
      // click failed
      console.log('element not clickable; trying to dismiss lightboxes');
      this.execute(function() {
        // Bypass Selenium element selection and access the body directly.
        // TA body click handler will dismiss it.
        if (typeof document.body.click !== 'undefined') {
          document.body.click();
        }
      })
      // try clicking again
      .click(selector, callback);
    }
  });

};

Thanks @kaueraal for your insight! I was pulling my hairs out over this one! However, I found that moveToElement would not always do the trick, so I had to invoke some scrollIntoView() for this one:

module.exports.command = function (selector) {
    this
        .execute(function (selector) {
            document.querySelector(selector).scrollIntoView();
        }, [selector])
        .pause(200)
        .click(selector);
};

I can reproduce this consistently as well with the following steps:

  1. Run a headless Chrome on OSX
  2. Let the element to click be on the lower border of the web page, but also outside the view port.
  3. Try to click on it via Nightwatch.

This fails with the error that <html>...</html> would receive the click, but not the intended target.

This is caused due to the scrollbars of OSX, which appear when scrolling. osx-scrollbars-censored

A temporary workaround is to move to the element, wait about a second, and then click on it:

page.moveToElement('@button', 100, 100);
browser.pause(1100);
page.click('@button);

I think you will need the Selenium server log, with -debug true, showing that either the click request wasn’t received, or wasn’t handled as you expect. (It may even expose the problem.) Here’s one such example:

13:41:12.069 WARN - Exception thrown
org.openqa.selenium.WebDriverException: unknown error: Element <input value="Google Search" aria-label="Google Search" name="btnK" type="submit" jsaction="sf.chk"> is not clickable at point (547, 411). Other element would receive the click: <b>...</b>

I don’t think this is always the case, though. I have a test where I first verify it is enabled, then wait for it to be present, then click. And the click still fails:

browser.expect.element(selector).to.be.enabled     // passes
browser.waitForElementPresent(selector, 5000)
      .click(selector)
// assert side effect from click

But this passes if I just append a second .click(selector) to the end. Apparently clicking the element twice is a workaround, at least in this case.