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.83k stars 1.32k forks source link

.verify.containsText() is not logging failed report when inside a perform command #3256

Closed chriscuba23 closed 2 years ago

chriscuba23 commented 2 years ago

Describe the bug

After upgrading to v2.2.2 I've noticed that the .verify.containsText() assertion does not appear at the report when it fails, yet it appears at the console results. This is not the case with .assert.containsText(), though, where it logs a failed assertion if it fails and it logs a passed one if it passes. The namespace needs to be nested within a perform command. This issue leads to false positive results since the failure is not being logged at the report

Sample test

sampleTest.js

```js // Please add the sample test here describe('Demo test Ecosia.org', () => { it('search for nightwatch', (browser) => { browser .waitForElementVisible('body') .assert.titleContains('Ecosia') .assert.visible('input[type=search]') .sendKeys('input[type=search]', 'nightwatch') .assert.visible('button[type=submit]') .click('button[type=submit]') .perform(function () { const webbrowser = browser.options.desiredCapabilities.browserName // assign browserName if (webbrowser == 'chrome' || webbrowser == 'MicrosoftEdge') { browser .pause(1000) .waitForElementPresent('a[href="https://nightwatchjs.org/"] h2 span') .moveToElement('a[href="https://nightwatchjs.org/"] h2 span', 0, 0) .verify.containsText('a[href="https://nightwatchjs.org/"] h2 span', 'nightwatch.js') } }) }) before((browser) => { browser .url('https://www.ecosia.org/') }) after((browser) => { browser .end() }) }); ```

Run with command

$ nightwatch test/sampleTest.js --verbose

Verbose output

debug.log

```txt Running search for nightwatch: ──────────────────────────────────────────────────────────────────────────────────────────────────────────── → Running [beforeEach]: → Completed [beforeEach]. → Running command: waitForElementVisible ('body') Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'body' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (13ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.9144004967340595-1' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync { script: 'return (function(){return (function(){var k=this||self;function aa(a){return"string"==typeof a}function ba(a,b){a=a.split(".");var c=k;a[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+a... (44027 characters)', args: [ { 'element-6066-11e4-a52e-4f735466cecf': '0.9144004967340595-1', ELEMENT: '0.9144004967340595-1' } ] } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync (17ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: true } √ Element was visible after 38 milliseconds. → Completed command: waitForElementVisible ('body') (42ms) → Running command: assert.titleContains ('Ecosia') → Running command: title ([Function]) Request GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/title Response 200 GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/title (6ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: 'Ecosia - the search engine that plants trees' } √ Testing if the page title contains 'Ecosia' (12ms) → Completed command: assert.titleContains ('Ecosia') (14ms) → Completed command: title ([Function]) (10ms) → Running command: assert.visible ('input[type=search]') → Running command: isVisible ({selector, suppressNotFoundErrors}, [Function]) Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'input[type=search]' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (10ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.9144004967340595-2' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync { script: 'return (function(){return (function(){var k=this||self;function aa(a){return"string"==typeof a}function ba(a,b){a=a.split(".");var c=k;a[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+a... (44027 characters)', args: [ { 'element-6066-11e4-a52e-4f735466cecf': '0.9144004967340595-2', ELEMENT: '0.9144004967340595-2' } ] } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync (16ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: true } √ Testing if element is visible (37ms) → Completed command: assert.visible ('input[type=search]') (38ms) → Completed command: isVisible ({selector, suppressNotFoundErrors}, [Function]) (33ms) → Running command: sendKeys ('input[type=search]', 'nightwatch') Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'input[type=search]' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (8ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.9144004967340595-2' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.9144004967340595-2/value { text: 'nightwatch', value: [ 'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h' ] } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.9144004967340595-2/value (58ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: null } → Completed command: sendKeys ('input[type=search]', 'nightwatch') (71ms) → Running command: assert.visible ('button[type=submit]') → Running command: isVisible ({selector, suppressNotFoundErrors}, [Function]) Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'button[type=submit]' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (10ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.9144004967340595-3' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync { script: 'return (function(){return (function(){var k=this||self;function aa(a){return"string"==typeof a}function ba(a,b){a=a.split(".");var c=k;a[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+a... (44027 characters)', args: [ { 'element-6066-11e4-a52e-4f735466cecf': '0.9144004967340595-3', ELEMENT: '0.9144004967340595-3' } ] } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/execute/sync (14ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: true } √ Testing if element is visible (33ms) → Completed command: assert.visible ('button[type=submit]') (34ms) → Completed command: isVisible ({selector, suppressNotFoundErrors}, [Function]) (30ms) → Running command: click ('button[type=submit]') Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'button[type=submit]' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (12ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.9144004967340595-3' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.9144004967340595-3/click {} Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.9144004967340595-3/click (1513ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: null } → Completed command: click ('button[type=submit]') (1530ms) → Running command: perform ([Function]) → Completed command: perform ([Function]) (2ms) → Running command: pause (1000) → Completed command: pause (1000) (1015ms) → Running command: waitForElementPresent ('a[href="https://nightwatchjs.org/"] h2 span') Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'a[href="https://nightwatchjs.org/"] h2 span' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (17ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.5476174756916765-1' } ] } √ Element was present after 20 milliseconds. → Completed command: waitForElementPresent ('a[href="https://nightwatchjs.org/"] h2 span') (22ms) → Running command: moveToElement ('a[href="https://nightwatchjs.org/"] h2 span', 0, 0) Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'a[href="https://nightwatchjs.org/"] h2 span' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (8ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.5476174756916765-1' } ] } Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/actions { actions: [ { actions: [ { type: 'pointerMove', origin: [Object], duration: 100, x: 0, y: 0 } ], parameters: { pointerType: 'mouse' }, type: 'pointer', id: 'default mouse' } ] } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/actions (123ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: null } → Completed command: moveToElement ('a[href="https://nightwatchjs.org/"] h2 span', 0, 0) (137ms) → Running command: verify.containsText ('a[href="https://nightwatchjs.org/"] h2 span', 'nightwatch.js') DEPRECATED: the assertion .containsText() has been deprecated and will be removed from future versions. Use assert.textContains(). → Running command: getText ({selector, suppressNotFoundErrors}, [Function]) Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'a[href="https://nightwatchjs.org/"] h2 span' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (6ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.5476174756916765-1' } ] } Request GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.5476174756916765-1/text Response 200 GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.5476174756916765-1/text (11ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: 'Nightwatch.js | Node.js powered End-to-End testing framework' } → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (21ms) → Running command: getText ({selector, suppressNotFoundErrors}, [Function]) Request POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements { using: 'css selector', value: 'a[href="https://nightwatchjs.org/"] h2 span' } Response 200 POST /session/b7c96f71c94e9fed3d96ba801f8bd07e/elements (13ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: [ { ELEMENT: '0.5476174756916765-1' } ] } Request GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.5476174756916765-1/text Response 200 GET /session/b7c96f71c94e9fed3d96ba801f8bd07e/element/0.5476174756916765-1/text (9ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: 'Nightwatch.js | Node.js powered End-to-End testing framework' } → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (26ms) → Running [afterEach]: → Completed [afterEach]. OK. 5 assertions passed. (3.494s) → Running [after]: → Running command: end () → Running command: session ('delete', [Function]) Request DELETE /session/b7c96f71c94e9fed3d96ba801f8bd07e Response 200 DELETE /session/b7c96f71c94e9fed3d96ba801f8bd07e (81ms) { sessionId: 'b7c96f71c94e9fed3d96ba801f8bd07e', status: 0, value: null } → Completed command: end () (102ms) → Completed command: session ('delete', [Function]) (86ms) → Completed [after]. HTML Report Generated at: reports\chrome_1656342645830.html Wrote JSON report file to: C:\Users\user\e2e_tests\reports\CHROME_103.0.5060.53_Windows_ecosia.json Wrote XML report file to: C:\Users\user\e2e_tests\reports\CHROME_103.0.5060.53_Windows_ecosia.xml Wrote HTML report file to: C:\Users\user\e2e_tests\reports\nightwatch-html-report\index.html → Running command: getText ({selector, suppressNotFoundErrors}, [Function]) × Testing if element contains text 'nightwatch.js' in 5000ms - expected "contains text 'nightwatch.js'" but got: "does not contain 'nightwatch.js'" (61572ms) at NightwatchAPI. (C:\Users\user\e2e_tests\tests\ecosia.js:22:21) → Completed command: verify.containsText ('a[href="https://nightwatchjs.org/"] h2 span', 'nightwatch.js') (61578ms) → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (60490ms) ```

Configuration

nightwatch.json

```js // Autogenerated by Nightwatch // Refer to the online docs for more details: https://nightwatchjs.org/gettingstarted/configuration/ const Services = {}; loadServices(); require('dotenv').config(); const FAILURES_ERRORS_PATH = "./failures"; // Location of the screenshots taken on failures/errors const REPORTS = "./reports"; // The location where the JUnit XML report files will be saved. 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: ["Scenarios"], // See https://nightwatchjs.org/guide/working-with-page-objects/ page_objects_path: "pages", // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands custom_commands_path: ["./custom_commands", "./node_modules/nightwatch-xhr/es5/commands", "./node_modules/nightwatch-mixpanel/es5/commands", "./node_modules/nightwatch-vrt/commands"], // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions custom_assertions_path: ["./custom_assertions", "./node_modules/nightwatch-xhr/es5/assertions", "./node_modules/nightwatch-mixpanel/es5/assertions", "node_modules/nightwatch-vrt/assertions"], // See https://nightwatchjs.org/guide/#external-globals globals_path: "./globals.js", data_path: "data", output_folder: REPORTS, // The location where the JUnit XML report files will be saved. live_output: false, // Whether or not to buffer the output in case of parallel running detailed_output: true, // By default detailed assertion output is displayed while the test is running. Set this to `false` if you'd like to only see the test case name displayed and pass/fail status. Detailed output is disabled by default when running tests in parallel. //parallel_process_delay: 1000, // Specifies the delay (in milliseconds) between starting the child processes when running in parallel mode. webdriver: { "keep_alive": true // Enable HTTP Keep-Alive. If set to true the keepAlive option is enabled with default settings (keepAliveMsecs = 3000). If set to an object, can specify specify the keepAliveMsecs value. }, // This object contains all the test related options. test_settings: { default: { disable_error_log: false, // Set this to true if you'd like to not display errors during the execution of the test (they are shown at the end always). launch_url: "http://localhost", // A url which can be used later in the tests as the main url to load. Can be useful if your tests will run on different environments, each one with a different url. silent: true, // Whether to show the extended HTTP traffic command logs from the WebDriver or Selenium server. use_xpath: false, // Use xpath as the default locator strategy test_workers: { "enabled": true, "workers": 25 }, // Whether or not to run individual test files in parallel. If set to `true`, runs the tests in parallel and determines the number of workers automatically. If set to an object, can specify specify the number of workers as `"auto"` or a `number`. globals: require('./globals'), // An object which will be made available within the test and can be overwritten per environment screenshots: { enabled: true, path: FAILURES_ERRORS_PATH, on_failure: true }, desiredCapabilities: { // An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities. browserName: 'chrome', javascriptEnabled: true, acceptSslCerts: true, browserTag: "mttestcr" }, end_session_on_fail: true, // End the session automatically when the test is being terminated, usually after a failed assertion. skip_testcases_on_fail: true, // Skip the remaining testcases (or test steps) from the same test suite (i.e. test file), when one testcase fails. detailed_output: true, // By default detailed assertion output is displayed while the test is running. Set this to `false` if you'd like to only see the test case name displayed and pass/fail status. This is especially useful when running tests in parallel. webdriver: { start_process: true, // When this is enabled, the Webdriver server is run in background in a child process and started/stopped automatically. Nightwatch includes support for managing Chromedriver, Geckodriver (Firefox), Safaridriver, and Selenium Server. Please refer to the Install Webdriver section for details. server_path: (Services.chromedriver ? Services.chromedriver.path : '') // Only useful if start_process is enabled. }, }, firefox: { desiredCapabilities: { browserName: 'firefox', alwaysMatch: { acceptInsecureCerts: true, 'moz:firefoxOptions': { args: [ // '-verbose' '--window-size=1920,925', '--no-sandbox', ] } }, }, browserTag: "mttestff", webdriver: { start_process: true, port: 4444, server_path: (Services.geckodriver ? Services.geckodriver.path : ''), cli_args: [ // very verbose geckodriver logs // '-vv' ] }, }, h_firefox: { desiredCapabilities: { browserName: 'firefox', alwaysMatch: { acceptInsecureCerts: true, 'moz:firefoxOptions': { args: [ '--headless', // '-verbose' '--window-size=1920,925', '--no-sandbox', ] } }, }, browserTag: "mttestff", webdriver: { start_process: true, port: 4444, server_path: (Services.geckodriver ? Services.geckodriver.path : ''), cli_args: [ // very verbose geckodriver logs // '-vv' ] }, }, chrome: { desiredCapabilities: { browserName: 'chrome', loggingPrefs: { browser: "ALL" }, javascriptEnabled: true, acceptSslCerts: true, 'goog:chromeOptions': { // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ // // This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78) w3c: false, args: [ '--no-sandbox', //'--ignore-certificate-errors', //'--allow-insecure-localhost', '--disable-software-rasterizer', '--disable-gpu', '--window-size=1920,925', '--log-level=3', '--disable-logging' ], prefs: { "profile.default_content_setting_values.cookies": 1, // Allow sites to save and read cookie data (recommended): 2=Blocked, 1=Allow }, } }, webdriver: { start_process: true, port: 9515, server_path: (Services.chromedriver ? Services.chromedriver.path : ''), cli_args: [ // --verbose ] }, }, h_chrome: { desiredCapabilities: { browserName: 'chrome', loggingPrefs: { browser: "ALL" }, javascriptEnabled: true, acceptSslCerts: true, 'goog:chromeOptions': { // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ // // This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78) w3c: false, args: [ '--no-sandbox', '--ignore-certificate-errors', '--allow-insecure-localhost', '--headless', '--disable-gpu', '--disable-software-rasterizer', //'--verbose', '--window-size=1920,925', '--log-level=3', '--disable-logging' ], prefs: { "profile.default_content_setting_values.cookies": 1, // Allow sites to save and read cookie data (recommended): 2=Blocked, 1=Allow }, }, }, webdriver: { start_process: true, port: 9515, server_path: (Services.chromedriver ? Services.chromedriver.path : ''), cli_args: [ // --verbose ] }, }, edge: { desiredCapabilities: { browserName: 'MicrosoftEdge', acceptSslCerts: true, 'ms:edgeOptions': { w3c: false, // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options args: [ ] }, browserTag: "mtteste" }, webdriver: { start_process: true, // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/ // and set the location below: server_path: "C:\\Windows\\System32\\msedgedriver.exe", cli_args: [ // --verbose ] }, }, h_edge: { desiredCapabilities: { browserName: 'MicrosoftEdge', 'ms:edgeOptions': { w3c: false, // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options args: [ '--no-sandbox', //'--ignore-certificate-errors', //'--allow-insecure-localhost', '--headless', '--window-size=1920,925', '--log-level=3', '--disable-gpu', '--disable-software-rasterizer', ] }, browserTag: "mtteste" }, webdriver: { start_process: true, // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/ // and set the location below: server_path: "C:\\Windows\\System32\\msedgedriver.exe", cli_args: [ // --verbose ] }, }, safari: { test_workers: { "enabled": false }, desiredCapabilities: { acceptInsecureCerts: false, browserName: 'safari', browserTag: "mttests", }, webdriver: { port: 4445, start_process: true, server_path: '/usr/bin/safaridriver' } }, ////////////////////////////////////////////////////////////////////////////////// // 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: false, host: '127.0.0.1', port: 4444, launch_url: 'http://localhost', server_path: (Services.seleniumServer ? Services.seleniumServer.path : ''), screenshots: { enabled: true, path: FAILURES_ERRORS_PATH, on_failure: true }, 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', javascriptEnabled: true, acceptSslCerts: true, acceptInsecureCerts: true, chromeOptions: { w3c: false, args: [ '--no-sandbox', '--ignore-certificate-errors', '--allow-insecure-localhost', '--headless', '--disable-gpu', '--disable-software-rasterizer', //'--verbose', '--window-size=1920,925', '--log-level=3', '--disable-logging' ] } }, webdriver: { start_process: false, } }, '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.2.2
npm --version 6.14.13
yarn --version VERSION
node --version v14.17.1
Browser driver Version
chromedriver 102.0.0
OS Version
Windows 10 1607
chriscuba23 commented 2 years ago

image

image

harshit-bs commented 2 years ago

Thanks @chriscuba23 for reporting the issue. This bug seems related to #3151 which is already in @swrdfish's pipeline.

AutomatedTester commented 2 years ago

Please also check this fixes #3351