Nightwatch: .click() does not fail the test immediately

Created on 30 Jul 2020  Â·  9Comments  Â·  Source: nightwatchjs/nightwatch

When using nightwatch with default settings (following the instructions in the documentation) to click() a button that does not exist, it does not immediately fail the test. It still continues to execute chained commands for the rest of the test up to the end. I don't think this makes much sense as default behaviour.

My test file:

module.exports = {
  'Click the thing that does not exist' : function (browser) {
    browser
      .url('https://www.google.com/')
      .waitForElementVisible('body')
      .perform(() => {
        console.log('I am going to click the first button');
      })
      .click('button.that-does-not-exist')
      .perform(() => {
        console.log('I am going to click the second button');
      })
      .click('button.that-also-does-not-exist')
      .end();
  }
};

The output:

leroux:~/nightwatch-reproduce$ npx nightwatch

[Test] Test Suite
=================
ℹ Connected to localhost on port 9515 (852ms).
  Using: chrome (85.0.4183.48) on Mac OS X platform.

Running:  Click the thing that does not exist

✔ Element <body> was visible after 17 milliseconds.
I am going to click the first button
I am going to click the second button

FAILED: 2 errors and  1 passed (12.661s)
_________________________________________________

TEST FAILURE: 2 errors during execution; 0 assertions failed, 1 passed (13.745s)

 ✖ test
 – Click the thing that does not exist (12.661s)

  NoSuchElementError: An error occurred while running .click() command on <button.that-does-not-exist>:
   {"sessionId":"a95c25679c67380e7a78492114d606fa","status":0,"value":[]}
       at processTicksAndRejections (internal/process/task_queues.js:97:5)


  NoSuchElementError: An error occurred while running .click() command on <button.that-also-does-not-exist>:
   {"sessionId":"a95c25679c67380e7a78492114d606fa","status":0,"value":[]}
       at processTicksAndRejections (internal/process/task_queues.js:97:5)

Nightwatch version:

leroux:~/nightwatch-reproduce$ npx nightwatch -v
  Nightwatch:
    version: 1.3.7
    changelog: https://github.com/nightwatchjs/nightwatch/releases/tag/v1.3.7

nightwatch.json:

{
  "src_folders" : ["tests"],

  "webdriver" : {
    "start_process": true,
    "server_path": "node_modules/.bin/chromedriver",
    "port": 9515
  },

  "test_settings" : {
    "default" : {
      "desiredCapabilities": {
        "browserName": "chrome"
      }
    }
  }
}

Is this configurable?

  • Is it possible to make click fail fast? ie. fail the test and don't run the rest of that test.
  • Is it possible to make click instantaneous globally? Ie no polling and waiting. Just fail fast if the element isn't there yet.
  • Is it possible to make click fail if the element is not clickable, ie. it is disabled? And then again fail the rest of the test.

What's the thinking about making click behave this way? How often would you try and click on an element and it doesn't matter if the click happened or not?

All 9 comments

Looking at the defaults, I don't see anything that targets what you're looking for explicitly.

But, you could work around it by checking if the button is visible, then if that command fails, your testcase should stop there, _I think_. Something like

browser
  .waitForElementVisible('button.that-does-not-exist')
  .click('button.that-does-not-exist')

+1

We tried adding asserts on presence, clickability etc but with literally hundreds of .click() it becomes unmaintainable quickly.

I am loathed to add a custom command to override core functionality. @beatfactor is this what you would suggest we do?

This will be addressed in the new version which is coming by the end of this week or early next.

Thanks so much

You can already do this by specifying the element as an object, but another setting will be added in a new version to have the behaviour determined for all element interactions.

Here's the syntax for existing support (v1.3):

browser.click({
  selector: 'button.that-does-not-exist',
  abortOnFailure: true
}) 

While this would help me in my case I think it is a terrible idea to be able to configure how click() behaves. The reason being that you then cannot look at test code and know how it will behave. Best is for a framework to make a decision. If it might break existing tests, then bump a new major version. Surely it is extremely rare for it to not matter if click did anything or not?

Just my 2 cents.

While this would help me in my case I think it is a terrible idea to be able to configure how click() behaves. The reason being that you then cannot look at test code and know how it will behave. Best is for a framework to make a decision. If it might break existing tests, then bump a new major version. Surely it is extremely rare for it to not matter if click did anything or not?

Just my 2 cents.

The only thing being discussed here is whether to fail the test immediately in case of a failed click action. In the current behaviour, the error is always recorded and the test will fail in the event of a failed click action. I think that's very far from saying that it doesn't matter if click failed to do anything or not. The idea is that the test case should continue to run assertions in order to get a better result at the end.

The option to abortOnElementLocateError has been added as a global property in v1.4.

You can already do this by specifying the element as an object, but another setting will be added in a new version to have the behaviour determined for all element interactions.

Here's the syntax for existing support (v1.3):

browser.click({
  selector: 'button.that-does-not-exist',
  abortOnFailure: true
}) 

In the developer guide abortOnFailure is described as 'abortOnFailure - used to overwrite this setting when using waitForElement* commands' wich suggests that it applies only to waitForElement* commands which seems to be not entirely correct.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gary5 picture gary5  Â·  4Comments

betweenbrain picture betweenbrain  Â·  4Comments

MateuszJeziorski picture MateuszJeziorski  Â·  3Comments

manjero picture manjero  Â·  4Comments

Zechtitus picture Zechtitus  Â·  4Comments