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

Global hooks are not working for nightwatch ^2.6.3 and Mocha runner #3564

Closed alexkirillovtech closed 1 year ago

alexkirillovtech commented 1 year ago

Description of the bug/issue

I am using an example that is recommended in documentation. Repo can be find here https://github.com/nightwatchjs-community/nightwatch-examples.

In globals.js We have a plenty of hooks such as before, after and etc.

before(cb) {
    //console.log('GLOBAL BEFORE')
    cb();
  },

  beforeEach(browser, cb) {
    //console.log('GLOBAL beforeEach')
    cb();
  },

  after(cb) {
    //console.log('GLOBAL AFTER')
    cb();
  },

  afterEach(browser, cb) {
    browser.perform(function() {
      //console.log('GLOBAL afterEach')
      cb();
    });
  },

  reporter(results, cb) {
    cb();
  }

The problem is that these hooks are not working no matter what I changed in configuration.

Please review it

Steps to reproduce

  1. Clone https://github.com/nightwatchjs-community/nightwatch-examples
  2. Install modules
  3. Uncomment console.log commands in before, after, beforeEach, afterEach and reporter
  4. Run the npm test

Sample test

Reproducible for all tests, Example:

googlePageObjects.js
describe('google search with consent form - page objects', function() {

    this.disabled = true;

    const homePage = browser.page.google.search();
    const consentPage = browser.page.google.consent();

    before(async () => homePage.navigate());

    after(async (browser) => browser.quit());

    it('should complete the consent form', async function (browser) {

        const consentPresent = await homePage.isPresent('@consentModal');

        if (consentPresent) {
            await homePage.expect.section('@consentModal').to.be.visible;

            const {consentModal} = homePage.section;
            await consentModal.click('@customizeButton');

            await browser.expect.url().toContain('https://consent.google.');
            await consentPage.turnOffEverything();
        }
    });

    it('should find nightwatch.js in results', function (browser) {
        homePage.setValue('@searchBar', 'Nightwatch.js');
        homePage.submit();

        const resultsPage = browser.page.google.searchResults();
        resultsPage.expect.element('@results').to.be.present;

        resultsPage.expect.element('@results').text.to.contain('Nightwatch.js');

        resultsPage.expect.section('@menu').to.be.visible;

        const menuSection = resultsPage.section.menu;
        menuSection.expect.element('@all').to.be.visible;
    });
});

Command to run

npm test or night or nightwatch --reporter=json

Verbose Output

No response

Nightwatch Configuration

//
// Refer to the online docs for more details:
// https://nightwatchjs.org/gettingstarted/configuration/
//
//  _   _  _         _      _                     _          _
// | \ | |(_)       | |    | |                   | |        | |
// |  \| | _   __ _ | |__  | |_ __      __  __ _ | |_   ___ | |__
// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
// | |\  || || (_| || | | || |_  \ 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: ['tests'],

  // See https://nightwatchjs.org/guide/working-with-page-objects/using-page-objects.html
  page_objects_path: ['lib/pages/'],

  // See https://nightwatchjs.org/guide/extending-nightwatch/custom-commands.html
  custom_commands_path: ['lib/custom-commands/'],

  // See https://nightwatchjs.org/guide/extending-nightwatch/custom-assertions.html
  custom_assertions_path: '',

  // See https://nightwatchjs.org/guide/extending-nightwatch/plugin-api.html
  plugins: [],

  // See https://nightwatchjs.org/guide/#external-globals
  globals_path : '',

  webdriver: {},

  test_settings: {
    default: {
      disable_error_log: false,
      launch_url: 'https://nightwatchjs.org',

      screenshots: {
        enabled: true,
        on_failure: true,
        on_error: true,
        path: './screens',
      },

      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: ['examples/cucumber-js/features/step_definitions'],

      test_runner: {
        // set cucumber as the runner
        type: 'cucumber',

        // define cucumber specific options
        options: {
          //set the feature path
          feature_path: 'node_modules/nightwatch/examples/cucumber-js/*/*.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_USERNAME                                                       |
    // - BROWSERSTACK_ACCESS_KEY                                                     |
    // .env files are supported                                                      |
    //////////////////////////////////////////////////////////////////////////////////
    browserstack: {
      selenium: {
        host: 'hub.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_USERNAME}',
          accessKey: '${BROWSERSTACK_ACCESS_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 SauceLabs cloud service                      |
    //                                                                               |
    // Please set the username and access key by setting the environment variables:  |
    // - SAUCE_USERNAME                                                              |
    // - SAUCE_ACCESS_KEY                                                            |
    //////////////////////////////////////////////////////////////////////////////////
    saucelabs: {
      selenium: {
        host: 'ondemand.saucelabs.com',
        port: 443
      },
      // More info on configuring capabilities can be found on:
      // https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options
      desiredCapabilities: {
        'sauce:options' : {
          username: '${SAUCE_USERNAME}',
          accessKey: '${SAUCE_ACCESS_KEY}',
          // https://docs.saucelabs.com/dev/cli/sauce-connect-proxy/#--region
          // region: 'us-west-1'
          // https://docs.saucelabs.com/dev/test-configuration-options/#tunnelidentifier
          // parentTunnel: '',
          // tunnelIdentifier: '',
        }
      },
      disable_error_log: false,
      webdriver: {
        start_process: false
      }
    },
    'saucelabs.chrome': {
      extends: 'saucelabs',
      desiredCapabilities: {
        browserName: 'chrome',
        screenResolution: '1280x1024',
        browserVersion: 'latest',
        javascriptEnabled: true,
        acceptSslCerts: true,
        timeZone: 'London',
        chromeOptions : {
          w3c: true
        }
      }
    },
    'saucelabs.firefox': {
      extends: 'saucelabs',
      desiredCapabilities: {
        browserName: 'firefox',
        screenResolution: '1280x1024',
        browserVersion: 'latest',
        javascriptEnabled: true,
        acceptSslCerts: true,
        timeZone: 'London'
      }
    },
    //////////////////////////////////////////////////////////////////////////////////
    // 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
      // Install the NPM package @nightwatch/selenium-server or download the selenium server jar file from https://github.com/SeleniumHQ/selenium/releases/, e.g.: selenium-server-4.1.1.jar
      selenium: {
        start_process: true,
        port: 4444,
        server_path: '', // Leave empty if @nightwatch/selenium-server is installed
        command: 'standalone', // Selenium 4 only
        cli_args: {
          //'webdriver.gecko.driver': '',
          //'webdriver.chrome.driver': ''
        }
      },
      webdriver: {
        start_process: false,
        default_path_prefix: '/wd/hub'
      }
    },

    'selenium.chrome': {
      extends: 'selenium_server',
      desiredCapabilities: {
        browserName: 'chrome',
        chromeOptions : {
          w3c: true
        }
      }
    },

    'selenium.firefox': {
      extends: 'selenium_server',
      desiredCapabilities: {
        browserName: 'firefox',
        'moz:firefoxOptions': {
          args: [
            // '-headless',
            // '-verbose'
          ]
        }
      }
    }
  }
};

Nightwatch.js Version

2.6.3

Node Version

19.10.1

Browser

Chrome 108.0.0

Operating System

MacOs Ventura 13.1 (22C65)

Additional Information

No response

alexkirillovtech commented 1 year ago

Hey @beatfactor, as discussed here https://github.com/nightwatchjs/nightwatch/issues/652, I created a new issue for problem with global hooks in example project. Please reach out with any questions, would love to help, because I really need to make this global hooks work

beatfactor commented 1 year ago

There is a small fix for this in 2.6.9. Can you try with this version? Is that the entire globals module?

alexkirillovtech commented 1 year ago

@beatfactor I made upgrade to 2.6.9, but still can't make the hooks works.

Hooks are located in /lib/globals.js

beatfactor commented 1 year ago

can you post your entire globals file here?

alexkirillovtech commented 1 year ago

@beatfactor yes, it looks like this `const globals = { // this controls whether to abort the test execution when an assertion failed and skip the rest // it's being used in waitFor commands and expect assertions abortOnAssertionFailure: true,

// this will overwrite the default polling interval (currently 500ms) for waitFor commands // and expect assertions that use retry waitForConditionPollInterval: 500,

// default timeout value in milliseconds for waitFor commands and implicit waitFor value for // expect assertions waitForConditionTimeout: 5000,

// this will cause waitFor commands on elements to throw an error if multiple // elements are found using the given locate strategy and selector throwOnMultipleElementsReturned: false,

// controls the timeout value for async hooks. Expects the done() callback to be invoked within this time // or an error is thrown asyncHookTimeout: 10000,

// controls the timeout value for when running async unit tests. Expects the done() callback to be invoked within this time // or an error is thrown unitTestsTimeout: 2000,

// controls the timeout value for when executing the global async reporter. Expects the done() callback to be invoked within this time // or an error is thrown customReporterCallbackTimeout: 20000,

// Automatically retrying failed assertions - You can tell Nightwatch to automatically retry failed assertions until a given timeout is reached, before the test runner gives up and fails the test. retryAssertionTimeout: 1000,

default: { myGlobal: function () { return "I'm a method"; }, isLocal: true, },

integration: { isLocal: false, },

test_env: { myGlobal: "test_global", beforeEach: function () { console.log("GLOBAL afterEach"); }, },

before(cb) { console.log("GLOBAL BEFORE"); cb(); },

beforeEach: function (browser, cb) { console.log("GLOBAL beforeEach"); cb() },

after(cb) { console.log("GLOBAL AFTER"); cb(); },

afterEach: function (browser, cb) { console.log("GLOBAL afterEach"); cb(); },

reporter(results, cb) { cb(); }, };

module.exports = globals;`

alexkirillovtech commented 1 year ago

@beatfactor Is there a way how I can help you with this?

alexkirillovtech commented 1 year ago

@beatfactor I found an issue, can't believe that it was so simple

In globals.js we need to specify a path for globals file // See https://nightwatchjs.org/guide/concepts/test-globals.html globals_path: "lib/globals.js",

harshit-bs commented 1 year ago

Hey @alexkirillovtech Since this was a configuration issue, I'm closing it for now. Please feel free to reopen if you are still facing it.