nightwatchjs / nightwatch

Integrated end-to-end testing framework written in Node.js and using W3C Webdriver API. Developed at @browserstack
https://nightwatchjs.org
MIT License
11.78k stars 1.31k forks source link

waitForElementVisible() failures does not fail the cucumber js steps #3085

Closed luke-btn closed 2 years ago

luke-btn commented 2 years ago

Describe the bug

When running nightwatch 2 with the inbuilt cucumberjs runner using the same setup as defined in nightwatchjs/cucumberjs-boilerplate, if you are using the waitForElementVisible() function on the browser, and the assertion fails, you can see the failure on the cli output, but the cucumber js runner does not pick this up and passes the step.

This is what the error looks like when running my failing waitForElementVisible() test on the cli output:

ℹ Connected to ChromeDriver on port 9515 (1194ms).
  Using: chrome (98.0.4758.109) on MAC OS X.

  ℹ Loaded url ****** in 4625ms
  ✖ Timed out while waiting for element <.header-text1> to be present for 5000 milliseconds. - expected "visible" but got: "not found" (5106ms)
    at World.<anonymous> (/***/cucumberjs-boilerplate/src/specs/test.js:11:8)

..

1 scenario (1 passed)
1 step (1 passed)
0m11.156s (executing steps: 0m11.146s)

I have only been able to get failures working in cucumberjs i I am using the browser.assert... way of checking elements - this does fail the cucumber js runner correctly.

This is my step definition

const { Given, Then, When } = require('@cucumber/cucumber');

Given(/^I have navigated to the ORR login screen$/, function() {
      return browser.url(<Secret>)
      .useCss()
      .waitForElementVisible('.header-text1')
    });

Configuration

nightwatch.json

```js const Services = {}; loadServices(); // _ _ _ _ _ _ _ // | \ | |(_) | | | | | | | | // | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__ // | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \ // | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | | // \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_| // __/ | // |___/ module.exports = { // An array of folders (excluding subfolders) where your tests are located; // if this is not specified, the test source must be passed as the second argument to the test runner. src_folders: ['src/specs'], // See https://nightwatchjs.org/guide/working-with-page-objects/ page_objects_path: '', // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands custom_commands_path: '', // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions custom_assertions_path: '', // See https://nightwatchjs.org/guide/#external-globals globals_path: '', webdriver: {}, test_runner: { type: 'cucumber', options: { feature_path: 'features/*.feature', additional_config: '', auto_start_session: true, parallel: 2 } }, test_settings: { default: { disable_error_log: false, launch_url: 'https://nightwatchjs.org', screenshots: { enabled: false, path: 'screens', on_failure: true }, desiredCapabilities: { browserName: 'chrome' }, webdriver: { start_process: true, server_path: '' } }, safari: { desiredCapabilities: { browserName: 'safari', alwaysMatch: { acceptInsecureCerts: false } }, webdriver: { start_process: true, server_path: '' } }, firefox: { desiredCapabilities: { browserName: 'firefox', alwaysMatch: { acceptInsecureCerts: true, 'moz:firefoxOptions': { args: [ // '-headless', // '-verbose' ] } } }, webdriver: { start_process: true, server_path: '', cli_args: [ // very verbose geckodriver logs // '-vv' ] } }, chrome: { desiredCapabilities: { browserName: 'chrome', 'goog:chromeOptions': { // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ // // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78) w3c: true, args: [ //'--no-sandbox', //'--ignore-certificate-errors', //'--allow-insecure-localhost', //'--headless' ] } }, webdriver: { start_process: true, server_path: '', cli_args: [ // --verbose ] } }, edge: { desiredCapabilities: { browserName: 'MicrosoftEdge', 'ms:edgeOptions': { w3c: true, // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options args: [ //'--headless' ] } }, webdriver: { start_process: true, // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/ // and set the location below: server_path: '', cli_args: [ // --verbose ] } }, ////////////////////////////////////////////////////////////////////////////////// // Configuration for when using cucumber-js (https://cucumber.io) | // | // It uses the bundled examples inside the nightwatch examples folder; feel free | // to adapt this to your own project needs | ////////////////////////////////////////////////////////////////////////////////// 'cucumber-js': { src_folders: ['src/specs'], test_runner: { // set cucumber as the runner type: 'cucumber', // define cucumber specific options options: { //set the feature path feature_path: 'features/*.feature' // start the webdriver session automatically (enabled by default) // auto_start_session: true // use parallel execution in Cucumber // parallel: 2 // set number of workers to use (can also be defined in the cli as --parallel 2 } } }, ////////////////////////////////////////////////////////////////////////////////// // Configuration for when using the browserstack.com cloud service | // | // Please set the username and access key by setting the environment variables: | // - BROWSERSTACK_USER | // - BROWSERSTACK_KEY | // .env files are supported | ////////////////////////////////////////////////////////////////////////////////// browserstack: { selenium: { host: 'hub-cloud.browserstack.com', port: 443 }, // More info on configuring capabilities can be found on: // https://www.browserstack.com/automate/capabilities?tag=selenium-4 desiredCapabilities: { 'bstack:options': { userName: '${BROWSERSTACK_USER}', accessKey: '${BROWSERSTACK_KEY}' } }, disable_error_log: true, webdriver: { timeout_options: { timeout: 15000, retry_attempts: 3 }, keep_alive: true, start_process: false } }, 'browserstack.local': { extends: 'browserstack', desiredCapabilities: { 'browserstack.local': true } }, 'browserstack.chrome': { extends: 'browserstack', desiredCapabilities: { browserName: 'chrome', chromeOptions: { w3c: true } } }, 'browserstack.firefox': { extends: 'browserstack', desiredCapabilities: { browserName: 'firefox' } }, 'browserstack.ie': { extends: 'browserstack', desiredCapabilities: { browserName: 'internet explorer', browserVersion: '11.0' } }, 'browserstack.safari': { extends: 'browserstack', desiredCapabilities: { browserName: 'safari' } }, 'browserstack.local_chrome': { extends: 'browserstack.local', desiredCapabilities: { browserName: 'chrome' } }, 'browserstack.local_firefox': { extends: 'browserstack.local', desiredCapabilities: { browserName: 'firefox' } }, ////////////////////////////////////////////////////////////////////////////////// // Configuration for when using the Selenium service, either locally or remote, | // like Selenium Grid | ////////////////////////////////////////////////////////////////////////////////// selenium_server: { // Selenium Server is running locally and is managed by Nightwatch selenium: { start_process: true, port: 4444, server_path: (Services.seleniumServer ? Services.seleniumServer.path : ''), cli_args: { 'webdriver.gecko.driver': (Services.geckodriver ? Services.geckodriver.path : ''), 'webdriver.chrome.driver': (Services.chromedriver ? Services.chromedriver.path : '') } } }, 'selenium.chrome': { extends: 'selenium_server', desiredCapabilities: { browserName: 'chrome', chromeOptions: { w3c: true } } }, 'selenium.firefox': { extends: 'selenium_server', desiredCapabilities: { browserName: 'firefox', 'moz:firefoxOptions': { args: [ // '-headless', // '-verbose' ] } } } } }; function loadServices() { try { Services.seleniumServer = require('selenium-server'); } catch (err) {} try { Services.chromedriver = require('chromedriver'); } catch (err) {} try { Services.geckodriver = require('geckodriver'); } catch (err) {} } ```

Your Environment

Executable Version
nightwatch --version 2.0.10
npm --version 6.14.15
node --version v14.18.1
Browser driver Version
Chromedriver 98.0.0
OS Version
MacOS 11.5.2
beatfactor commented 2 years ago

How about if you use async/await, like:

const { Given, Then, When } = require('@cucumber/cucumber');

Given(/^I have navigated to the ORR login screen$/, async function() {
      return await browser.url(<Secret>)
      .useCss()
      .waitForElementVisible('.header-text1')
    });
luke-btn commented 2 years ago

@beatfactor thanks for the suggestion, I've just tried this as well, but the cucumber step is still passing when it should be failing even when using the async method. It looks like Nightwatch itself bails out correctly, but is not reporting the failure to CucumberJS

beatfactor commented 2 years ago

Yes, that's right. We need to make sure the failure is reported correctly, so we'll need to send a patch release soon but in the meantime I guess you have a workaround? Using either .assert.visible() or expect.element().to.be.visible would be pretty much the same thing.