nightwatch Documentation

Integrated end-to-end testing framework written in Node.js and using W3C Webdriver API. Developed at @browserstack

RAW Doc

File: README.md

Nightwatch.js




Discord

[Homepage](https://nightwatchjs.org) • [Developer Guide](https://nightwatchjs.org/guide) • [API Reference](https://nightwatchjs.org/api) • [About](https://nightwatchjs.org/about) • [Blog](https://nightwatchjs.org/blog)

Nightwatch is an integrated testing framework powered by Node.js and using the W3C Webdriver API. It is a complete testing solution developed at BrowserStack and which can be used for:

โ˜‘๏ธ end-to-end testing of web applications and websites

โ˜‘๏ธ component testing in isolation (React / Vue / Storybook / Angular)

โ˜‘๏ธ Node.js unit, visual regression testing, accessibility testing & API testing

โ˜‘๏ธ Native mobile app testing on Android & iOS

๐Ÿš€ Nightwatch v3

What's New | Release Notes | Discussions

Nightwatch v3 is an all new generation that has been built around these three pillars:

  • Developer Experience : The entire experience from getting started, to writing and debugging tests, has been redesigned for speed, stability, and consistent non-flaky results.

  • Mobile first: Test your web or native, iOS and Android, mobile applications on simulators, real mobile devices or a cloud grid like BrowserStack.

  • One test automation framework: Run all types of tests from unit, component, and E2E to API, visual, and accessibility with a single framework.

The Nightwatch v3 is not just a new version, itโ€™s the result of months of engineering effort to reimagine test automation for the future. Try it out in 60 seconds and see it in action.

โš™๏ธ Get started in 60 seconds

1. Install Nightwatch from NPM

From your existing project's root dir:

sh
npm init nightwatch@latest

or, if you want to initialize a new project:

sh
npm init nightwatch@latest ./path/to/new/project

2. Answer a few questions about your preferred setup:

  • What is your Language - Test Runner setup?
  • Where do you want to run your e2e tests?
  • Where you'll be testing on?
  • Where do you plan to keep your end-to-end tests?
  • What is the base_url of your project?

Nightwatch will do the entire setup for you based on your answers.

3. Run a Demo Test:

Nightwatch comes with a few examples, which are automatically copied to your Nightwatch project during the setup and can also be used as boilerplate to write your own tests on top of them.

You can follow the instructions given at the end of the setup to run your first test with Nightwatch.


Nightwatch mobile app testing

Nightwatch enables automation testing of native mobile applications via Appium. It combines the robustness of Appium with the enhanced developer experience provided by Nightwatch. It enables end-to-end functional testing of native mobile apps on Android and iOS devices. Try it now

Go beyond E2E

[Component testing](https://nightwatchjs.org/guide/component-testing/introduction.html)

With Nightwatch you can test components in isolation by mounting them in the browser. Nightwatch 2 added support for component testing for popular web frameworks such as

  1. React
  2. VueJS
  3. Angular
  4. Storybook

Nightwatch unit tests

The tests for Nightwatch are written using Mocha.

  1. Clone the project

    bash
    git clone https://github.com/nightwatchjs/nightwatch.git
    
    # change directory
    cd nightwatch
    
    # install the dependencies
    npm install
  2. Run tests

    To run the complete test suite:

    bash
    npm test

    To check test coverage, run the command:

    bash
    npm run mocha-coverage

    and then open the generated coverage/index.html file in your browser.

See Unit testing guide for more details.

Other types of testing

[Visual Regression Testing](https://nightwatchjs.org/guide/writing-tests/visual-regression-testing.html)

Nightwatch v3 introduces visual regression testing as an in-house plugin. The plugin takes care of

  1. Capturing screenshots
  2. Comparison with baseline to highlight visual differences
  3. Report to review the differences
  4. Approve the changes

VRT can be done on real desktop & mobile browsers. Also, VRT can be run on components as part of component testing as well.

[API Testing](https://nightwatchjs.org/guide/writing-tests/api-testing.html)

API testing is now available with Nightwatch v3. The following functionality can be achieved with API testing

  1. Request assertions
  2. Response assertions
  3. Viewing API tests in the HTML report
  4. Mock server

[Accessibility Testing](https://nightwatchjs.org/guide/using-nightwatch/accessibility-testing.html)

Nightwatch v3 packages the aXe-core package developed by Deque Systems as a plugin. It enables 90 different types of accessibility tests for WCAG compliance.

๐Ÿฆ‰ About Nightwatch

Nightwatch was initially built by @pineviewlabs - an independent software consultancy based in Oslo, Norway, with help from contributors. In mid 2021, Nightwatch has become a part of the @BrowserStack family and it is being developed further at the BrowserStack Open-source Program Office. Read more on our blog.

Contributing

We welcome any and all contributions from the community which can help improve Nightwatch. Please check out CONTRIBUTING.md for more extensive contributing guidelines.

Licence

MIT


File: CODE_OF_CONDUCT.md

Code of Conduct

Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, gender, gender identity and expression, sex characteristics, disability, ethnicity, level of experience, education, socio-economic status, nationality, personal appearance, body size, race, religion (or lack thereof), or sexual identity and orientation.

Our Standards

Examples of behavior that contributes to creating a positive environment include:

  • Using welcoming and inclusive language - please read the inclusive language guidance from the UUA
  • Being respectful of differing viewpoints and experiences
  • Showing empathy towards other community members
  • Gracefully accepting constructive criticism
  • Exercising consideration and respect in your speech and actions
  • Attempting collaboration before conflict or criticism

Examples of unacceptable behavior by participants include:

  • The use of sexualized language or imagery and unwelcome sexual attention or advances
  • Trolling, spamming, intentionally disrupting conversations, making insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing or threatening to publish others' private information, such as a physical or electronic address, without explicit permission
  • Advocating for, or encouraging, any of the above behavior
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [email protected]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html.

It's inspired among other things by:

For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq


File: codecov.yml

codecov:
require_ci_to_pass: yes

coverage:
precision: 2
round: down
range: "70...100"

parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no

comment: false


File: CONTRIBUTING.md

Contributing to Nightwatch

Contributions to Nightwatch are always welcome but please try to follow these guidelines when sending in something as it will help addressing the issue quicker and more smoothly.

Please do not ask for assistance in the Issues list. Join our Discord server to ask questions and seek help.

Assistance requests posted in the Issues list are usually closed right away.

Code of Conduct

Contributors are expected to adhere to the Code of Conduct.

Submit an issue

Before submitting a new issues, try searching for a similar one here: https://github.com/nightwatchjs/nightwatch/search?type=Issues and add your scenario there and anything else which you think will help with fixing it;

If you are filing a bug report, regression issue or what it appears to be strange behaviour, please follow the steps below:

  1. Please write an elaborate title which explains the problem as accurate as possible
    For instance:
    • not helpful: "Issue with tags"
    • much better: "Tags don't work when combined with --skiptags option"
  2. Include a sample test which reproduces the problem you're experiencing. The test should be against a public url. The test and other info should be posted inline, attachments will be ignored;
  3. Include the verbose output, if possible (run nightwatch with --verbose argument);
  4. Include your configuration (try to leave out the irrelevant bits);
  5. Also include: Nightwatch version, Node.js version, OS version and Webdriver/Selenium Server version;
  6. Please try not to report issues you have with individual browser drivers which cannot or should not be solved in Nightwatch.

Requesting a feature

Feature requests are welcome.

  1. Indicate in the issue title that it is a feature/enhancement request;
  2. Explain the use case and include a sample test case and/or usage, if possible;
  3. Try to submit enhancements that you cannot build with custom commands/assertions and something that will benefit the community;
  4. Same as for issues, add your comments/vote to an existing feature request if you'd like to see it implemented.

Submitting a pull request

Thanks in advance for your contribution.

  1. Follow the usual git workflow for submitting a pull request:

    • Fork and clone the project.
    • Create a new branch from main (e.g. features/my-new-feature or issue/123-my-bugfix).
    • Add your changes.
    • Try to run some Nightwatch example tests locally to test the functionality after making your changes: node ./bin/nightwatch examples/tests/ecosia.js --env chrome.
    • Run Nightwatch unit tests locally: npm test;
      Or, run individual tests: npx mocha test/src/api/commands/client/testWaitUntil.js.
    • Commit your changes and create a pull request.

    Note: When running Nightwatch example test for the first time, if you encounter "Cannot read source" error, go to nightwatch.conf.js file and set 'page_objects_path' and 'custom_commands_path' configs to [].

  2. If you're fixing a bug, also create an issue if one doesn't exist yet.

  3. If it's a new feature/enhancement, explain why do you think it's necessary.

  4. If your change include drastic or low level changes please discuss them to make sure they will be accepted and what the impact will be.

  5. If your change is based on existing functionality, please consider refactoring first. Pull requests that duplicate code will not make it in very quick, if at all.

  6. Do not include changes that are not related to the issue at hand.

  7. Follow the same coding style with regards to spaces, semicolons, variable naming etc.

  8. Always add tests - after all this is a testing framework.


File: LICENSE.md

The MIT License (MIT)

Copyright (c) 2014-2021, Pine View Software AS. https://pineview.io
Copyright (c) 2022, BrowserStack Limited. https://www.browserstack.com

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


File: package.json

{
"name": "nightwatch",
"description": "Easy to use Node.js based end-to-end testing solution for web applications using the W3C WebDriver API.",
"version": "3.16.0",
"author": "Andrei Rusu",
"homepage": "https://nightwatchjs.org",
"main": "./lib/index.js",
"types": "./types/index.d.ts",
"license": "MIT",
"bugs": {
"url": "https://github.com/nightwatchjs/nightwatch/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nightwatchjs/nightwatch.git"
},
"dependencies": {
"@nightwatch/chai": "5.0.3",
"@nightwatch/html-reporter-template": "^0.3.0",
"@nightwatch/nightwatch-inspector": "^1.0.1",
"@types/chai": "^4.3.5",
"@types/selenium-webdriver": "^4.1.14",
"ansi-to-html": "0.7.2",
"aria-query": "5.1.3",
"assertion-error": "1.1.0",
"boxen": "5.1.2",
"chai-nightwatch": "^0.5.3",
"chalk": "^4.1.2",
"ci-info": "3.3.0",
"cli-table3": "^0.6.3",
"devtools-protocol": "^0.0.1140464",
"didyoumean": "^1.2.2",
"dotenv": "16.3.1",
"ejs": "^3.1.10",
"envinfo": "7.11.0",
"glob": "7.2.3",
"jsdom": "^24.1.0",
"lodash": "^4.17.21",
"minimatch": "3.1.5",
"minimist": "1.2.6",
"mocha": "10.8.2",
"nightwatch-axe-verbose": "^2.3.0",
"open": "8.4.2",
"ora": "5.4.1",
"piscina": "^4.3.1",
"selenium-webdriver": "4.27.0",
"semver": "7.5.4",
"stacktrace-parser": "0.1.10",
"strip-ansi": "6.0.1",
"untildify": "4.0.0",
"uuid": "8.3.2"
},
"devDependencies": {
"@cucumber/cucumber": "^8.2.1",
"@swc/core": "^1.3.67",
"@types/node": "^18.17.3",
"@typescript-eslint/eslint-plugin": "^6.3.0",
"@typescript-eslint/parser": "^6.3.0",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"eslint": "^8.46.0",
"husky": "^8.0.0",
"is-ci": "^3.0.1",
"js-yaml": "^3.13.1",
"lint-staged": "^13.2.2",
"mocha-junit-reporter": "^2.0.2",
"mochawesome": "^7.1.3",
"mochawesome-merge": "^4.2.1",
"mochawesome-report-generator": "^6.2.0",
"mockery": "~2.1.0",
"nock": "^13.2.9",
"nyc": "^15.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rimraf": "^3.0.2",
"serve": "^14.2.6",
"ts-node": "^10.9.1",
"tsd": "^0.31.2",
"wait-on": "^7.2.0"
},
"peerDependencies": {
"@cucumber/cucumber": ""
},
"peerDependenciesMeta": {
"chromedriver": {
"optional": true
},
"geckodriver": {
"optional": true
},
"@cucumber/cucumber": {
"optional": true
}
},
"overrides": {
"minimatch@^5.0.0": "^5.1.7"
},
"bin": {
"nightwatch": "./bin/nightwatch"
},
"man": "",
"scripts": {
"eslint": "eslint index.js lib bin api examples test --quiet",
"mocha": "mocha",
"mocha-coverage": "nyc --reporter=html mocha test/src/ --recursive",
"test": "mocha test/src/ --recursive --timeout 20000",
"test:types": "tsd --files types/tests",
"component-tests": "mocha test/component-tests/src",
"test-cucumber": "mocha test/cucumber-integration-tests --parallel",
"coverage": "npx nyc report --reporter=text-lcov > ./coverage/mocha_coverage.lcov",
"prepare": "husky install"
},
"eslintConfig": {
"extends": "eslint:recommended",
"env": {
"browser": false,
"node": true
},
"rules": {
"eqeqeq": "off",
"curly": [
"error",
"all"
],
"quotes": [
"error",
"single"
]
}
},
"engines": {
"node": ">= 18.20.5"
},
"keywords": [
"nightwatch",
"nightwatchjs",
"selenium",
"testing",
"webdriver",
"browserstack",
"end-to-end",
"automated-testing",
"e2e",
"component",
"integration",
"test",
"browser",
"mobile",
"runner",
"appium",
"cucumber",
"mocha",
"automation"
],
"files": [
"bin",
"examples",
"lib",
"api",
"types",
"README.md",
"CODE_OF_CONDUCT.md",
"LICENSE.md",
"index.js"
],
"lint-staged": {
"**/
.js": [
"npx eslint --fix"
]
}
}


File: api/README.md

Nightwatch API Commands

Public commands api exported by Nightwatch in order to be extended upon from outside.

Example:

js
const {Quit: quit} = require('nightwatch/api');

module.exports = CustomQuit extends Quit {
  async command(cb = function(r) {return r}) {
    console.log('from custom quit command');
    
    await super.command(cb);
  }
}

This is a work in progress.

Element commands:

Document handling:

Frames:

User actions:

User prompts:

Utilities & Debugging:


File: examples/globals.json

{
"default" : {
"myGlobal" : 1
},
"test_env" : {
"myGlobal" : 2
}
}


File: examples/tsconfig.json

{
"extends": "../tsconfig",
"include": ["."]
}


File: examples/cucumber-js/README.md

Using Cucumber.js with Nightwatch 2

Nightwatch 2 brings integrated support for using Cucumber.js directly as an alternative test runner. No other plugins are necessary, other than the Cucumber library itself (version 7.3 or higher).

Simply run the following in the same project where Nightwatch is also installed:

sh
$ npm i @cucumber/cucumber --save-dev

Configuration

js
{
  test_runner: {
    // set cucumber as the runner
    type: 'cucumber',  
      
    // define cucumber specific options  
    options: {
      //set the feature path
      feature_path: '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
    }
  },
  
  src_folders: ['examples/cucumber-js/features/step_definitions']
}

CLI Options

option description
--dry-run Do all the aggregation work of looking at your feature files, loading your support code etc but without actually executing the tests. read more
--name Specify a scenario by its name matching a regular expression. read more
--tags Use tags to run specific scenario or features. read more
--require Use --require <GLOB OR DIR OR FILE> to explicitly require support files before executing the features. read more
--format Use --format <TYPE[:PATH]> to specify the format of the output. read more
--format-options Many formatters, including the built-in ones, support some configurability via options. You can provide this data as a JSON literal via the --format-options CLI option. read more
--fail-fast Abort the run on first failure (default: false). read more
--retries Use --retries <NUMBER-OF-ATTEMPT> to have Cucumber attempt it multiple times until either it passes or the maximum number of attempts is reached. read more
--retry-tag-filter Use --retry-tag-filter to retry failed scenarios based on tags. read more
--require-module read more
--no-strict By default, cucumber runner works in strict mode, meaning it will fail if there are pending steps.
--parallel Use --parallel <NUMBER-OF-WORKER-THREADS> to run your scenarios in parallel. read more
--profile As of now only cucumber.js is considered while picking up profiles. read more
--world-parameters Provide this data as a JSON literal via the --world-parameters. read more

Running

Cucumber spec files/step definition files can be provided in src_folders in Nightwatch config or as a CLI argument.

With src_folders defined:

sh
$ npx nightwatch

Without src_folders defined:

sh
$ npx nightwatch examples/cucumber-js/features/step_definitions

Parallel running using 2 workers:

sh
$ nightwatch examples/cucumber-js/features/step_definitions --parallel 2

Use other test runner options as usual:

sh
$ npx nightwatch examples/cucumber-js/features/step_definitions --headless

Disable the automatic session start

You might need sometimes to not start the Webdriver session automatically after Nightwatch is instantiated. For this purpose, Nightwatch provides the instance available as this.client, which contains an launchBrowser() method.

Configuration:

js
test_runner: {
  type: 'cucumber',
  options: {
    feature_path: 'examples/cucumber-js/*/*.feature',
    auto_start_session: false
  }
}

You can then use an extra setup file that you can pass as an extra --require to Nightwatch, which will be forwarded to Cucumber. In the extra setup file, you can add other operations needed to be executed before the session is started.

Example _extra_setup.js:

Remember to set the browser on this so it can be closed automatically by Nightwatch. Otherwise, remember to call .quit() in your own Cucumber After() hooks.

js
const {Before} = require('@cucumber/cucumber');

Before(async function(testCase) {
  if (!this.client) {
    console.error('Nightwatch instance was not created.');

    return;
  }

  this.client.updateCapabilities({
    testCap: 'testing'
  });

  this.browser = await this.client.launchBrowser();
});

Nightwatch setup file for Cucumber

You might also want to inspect the built-in setup file that Nightwatch uses for initializing the Cucumber runner. It is available in our project root folder at /cucumber-js/_setup_cucumber_runner.js.

Run with extra setup:

sh
$ nightwatch examples/cucumber-js/features/step_definitions --require {/full/path/to/_extra_setup.js}

Reporting

When using the integrated Cucumber test runner, you need to use the Cucumber formatters for generating output.

Nightwatch reporters (like JUnit XML reports or the global custom reporter) are not available. The main reason is that reporting is delegated to the Cucumber CLI. You can also write your own Cucumber formatter.

Nightwatch will forward --format and --format-options CLI arguments, if present, to Cucumber.

By default, the progress formatter is used. Here's how the output looks like when running the example tests in Firefox:

sh
โ„น Connected to GeckoDriver on port 4444 (1740ms).
Using: firefox (92.0.1) on MAC (20.6.0).

..  โœ” Testing if the page title equals 'Rijksmuseum Amsterdam, home of the Dutch masters' (4ms)
.  โœ” Element <#rijksmuseum-app> was visible after 46 milliseconds.
.  โœ” Testing if element <.search-results> contains text 'Operation Night Watch' (1994ms)
...  โœ” Testing if the page title equals 'Rijksmuseum Amsterdam, home of the Dutch masters' (8ms)
.  โœ” Element <#rijksmuseum-app> was visible after 49 milliseconds.
.  โœ” Testing if element <.search-results> contains text 'The Night Watch, Rembrandt van Rijn, 1642' (1427ms)
.

2 scenarios (2 passed)
10 steps (10 passed)
0m13.024s (executing steps: 0m12.998s)

File: examples/tests/README.md

Using Mocha as a test runner in Nightwatch 2

Nightwatch 2 brings support for Mocha v9 as an alternative test runner which contains most of the existing functionality from the Nightwatch default runner.

We are still in the process of updating the examples. Please check back here soon.


File: lib/runner/test-runners/cucumber/README.md

Using Cucumber.js with Nightwatch 2

Nightwatch 2 brings integrated support for using Cucumber.js directly as an alternative test runner. No other plugins are necessary, other than the Cucumber library itself (version 7.3 or higher).

Simply run the following in the same project where Nightwatch is also installed:

sh
$ npm i @cucumber/cucumber --save-dev

The examples folder contains a few example spec files and cucumber features, as well as configuration details.


File: test/nightwatch.json

{
"src_folders" : ["./test/src"],
"test_workers" : false,
"selenium" : {
"start_process" : false,
"start_session" : false
},

"test_settings": {
"default" : {
"filter" : "**/*.js",
"compatible_testcase_support" : true,
"globals": {
"asyncHookTimeout" : 15000
}
}
}
}


File: test/tsconfig.json

{
"compilerOptions": {
"target": "esnext",
/* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. /
"module": "node16",
/
Specify what module code is generated. /
"allowJs": true,
/
Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. /
"outDir": "dist",
/
Specify an output folder for all emitted files. /
"esModuleInterop": true,
/
Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. /
"forceConsistentCasingInFileNames": true,
/
Ensure that casing is correct in imports. /
"strict": true,
/
Enable all strict type-checking options. /
"noImplicitAny": true,
/
Enable error reporting for expressions and declarations with an implied 'any' type. /
"skipLibCheck": true
/
Skip type checking all .d.ts files. */
},
"include": [
"."
],
"files": [
"./types/index.d.ts"
]
}


File: test/extra/minimalJsonReporter.json

{
"modules": {
"demoTagTest": {
"modulePath": "./test/sampletests/tags/sample.js",
"status": "pass"
},
"demoTest": {
"modulePath": "./test/sampletests/simple/test/sample.js",
"status": "fail"
}
}
}


File: test/extra/nightwatch.json

{
"src_folders" : ["../sampletests"],
"output_folder" : "./output",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"globals_path" : "./globals.js",
"test_workers" : {
"enabled" : false
},
"output" : false,
"selenium" : {
"start_process" : false,
"server_path" : "./bin/selenium-server.jar"
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
},
"filter" : ["async/**"]
},

text
"mixed" : {
  "filter" : ["mixed/*"]
}

}
}


File: test/extra/package.json

{
"name": "nightwatch"
}


File: test/extra/parallelism-auto.json

{
"src_folders" : ["./test/sampletests/before-after"],
"output_folder" : false,
"test_workers" : {
"enabled" : true,
"workers" : "auto"
},
"output" : false,
"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism-count.json

{
"src_folders" : ["./test/sampletests/before-after"],
"output_folder" : false,
"output" : false,
"test_workers" : {
"enabled" : true,
"workers" : 6
},

"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism-customCommandsSync.json

{
"src_folders" : ["./test/apidemos/custom-commands-parallel"],
"test_workers": true,
"custom_commands_path": ["./test/extra/commands/other"],
"persist_globals": true,
"output_folder" : false,
"output" : false,
"silent": false,
"selenium" : {
"start_process" : false,
"port": 10195
},
"test_settings": {
"default" : {
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism-disabled.json

{
"src_folders" : ["./test/sampletests"],
"output_folder" : false,
"test_workers" : {
"enabled" : true,
"workers" : "auto"
},
"output" : false,
"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
},
"test_workers" : false
}
}
}


File: test/extra/parallelism-envs.json

{
"src_folders" : ["./test/sampletests"],
"output_folder" : false,
"output" : false,

"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
},
"env1" : {
"filter" : "mixed/*"
},
"env2" : {
"filter" : "simple/**"
}
}
}


File: test/extra/parallelism-execArgv-selected.json

{
"src_folders" : ["./test/sampletests"],
"output_folder" : false,
"test_workers" : {
"enabled": true,
"node_options": ["--harmony"]
},
"output" : false,
"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism-execArgv.json

{
"src_folders" : ["./test/sampletests"],
"output_folder" : false,
"test_workers" : {
"enabled": true,
"node_options": "inherit"
},
"output" : false,
"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism-selenium-server.json

{
"src_folders" : ["./test/sampletests/before-after"],
"output_folder" : false,
"test_workers" : {
"enabled" : true,
"workers" : 2
},
"output" : false,
"selenium" : {
"start_process" : true
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/parallelism.json

{
"src_folders" : ["./test/sampletests/before-after"],
"output_folder" : false,
"test_workers" : true,
"output" : false,
"selenium" : {
"start_process" : false
},

"test_settings": {
"default" : {
"silent" : true,
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/withgeckodriver-concurrent.json

{
"src_folders" : ["../sampletests"],
"output_folder" : "./output",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"globals_path" : "./globals.js",
"test_workers" : {
"enabled" : true
},

"output" : false,

"test_settings": {
"default" : {
"desiredCapabilities" : {
"browserName" : "firefox"
},
"webdriver": {
"start_process": true,
"server_path": "./geckodriver"
}
}
}
}


File: test/extra/withmocha.json

{
"src_folders" : ["./test/mochatests"],
"output_folder" : "./output",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"output" : false,
"selenium" : {
"start_process" : false,
"server_path" : "./bin/selenium-server.jar"
},
"test_runner" : "mocha",
"test_settings": {
"default" : {
"selenium_port" : 10195,
"silent" : true,
"persist_globals" : true,
"globals" : {},
"desiredCapabilities" : {
"browserName" : "firefox"
}
}
}
}


File: test/extra/withsafari-concurrent.json

{
"src_folders" : ["../sampletests"],
"output_folder" : "./output",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"globals_path" : "./globals.js",
"test_workers" : {
"enabled" : true
},

"output" : false,

"test_settings": {
"default" : {
"desiredCapabilities" : {
"browserName" : "safari"
},
"webdriver": {
"start_process": true
}
},
"chrome" : {
"desiredCapabilities" : {
"browserName" : "chrome"
},
"webdriver": {
"start_process": true
}
},
"firefox" : {
"desiredCapabilities" : {
"browserName" : "firefox"
},
"webdriver": {
"start_process": true
}
}
}
}


File: test/lib/mocks.json

{
"mocks": [
{
"url": "/wd/hub/session",
"postdata": {
"desiredCapabilities": {
"browserName": "firefox"
}
},
"response": {
"status": 0,
"sessionId": "1352110219202",
"value": {
"browserName": "firefox",
"browserVersion": "TEST",
"platformVersion": "TEST"
},
"state": null
},
"responseHeaders": {
},
"statusCode": 201,
"method": "POST"
},

text
{
  "url": "/session",
  "postdata": {
    "capabilities": {
      "browserName": "firefox"
    },
    "desiredCapabilities": {
      "browserName": "firefox"
    }
  },

  "response": {
    "value": {
      "sessionId": "13521-10219-202",
      "capabilities": {
        "acceptInsecureCerts": false,
        "browserName": "firefox",
        "browserVersion": "65.0.1",
        "platformName": "linux",
        "platformVersion": "4.9.125-linuxkit",
        "setWindowRect": true,
        "strictFileInteractability": false,
        "timeouts": {
          "implicit": 0,
          "pageLoad": 300000,
          "script": 30000
        },
        "unhandledPromptBehavior": "dismiss and notify"
      }
    }
  },
  "responseHeaders": {
  },
  "statusCode": 201,
  "method": "POST"
},

{
  "url": "/wd/hub/session",
  "postdata": "",
  "response": {
    "status": 0,
    "sessionId": "1352110219202",
    "value": {
      "browserName": "firefox",
      "version": "TEST",
      "platform": "TEST"
    },
    "state": null
  },
  "responseHeaders": {
  },
  "statusCode": 201,
  "method": "POST"
},
{
  "url": "/wd/hub/session/1352110219202",
  "method": "DELETE",
  "response": {
    "status": 0,
    "state": "success"
  }
},
{
  "url": "/wd/hub/session/1352110219202/url",
  "postdata": {
    "url": "http://localhost"
  }
},
{
  "url": "/wd/hub/test",
  "response": {
    "status": 0
  }
},
{
  "url": "/wd/hub/test_error",
  "response": {
    "status": 7,
    "value": {
      "screen": "screenshot_data"
    }
  },
  "statusCode": 500
},
{
  "url": "/wd/hub/session/1352110219202/element",
  "postdata": {
    "using": "css selector",
    "value": "#weblogin"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": {
      "ELEMENT": "0"
    },
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/element",
  "postdata": {
    "using": "css selector",
    "value": "#webdriver"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": {
      "element-6066-11e4-a52e-4f735466cecf": "5cc459b8-36a8-3042-8b4a-258883ea642b"
    }
  }
},
{
  "url": "/session/13521-10219-202/element",
  "postdata": {
    "using": "css selector",
    "value": "#webdriver"
  },
  "response": {
    "value": {
      "element-6066-11e4-a52e-4f735466cecf": "5cc459b8-36a8-3042-8b4a-258883ea642b"
    }
  }
},
{
  "url": "/wd/hub/session/1352110219202/element",
  "postdata": {
    "using": "css selector",
    "value": "#signupSection"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": {
      "ELEMENT": "0"
    },
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/element",
  "postdata": {
    "using": "xpath",
    "value": "//weblogin"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": {
      "ELEMENT": "0"
    },
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},

{
  "url": "/wd/hub/session/1352110219202/element/0/element",
  "postdata": {
    "using": "css selector",
    "value": "#helpBtn"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": {
      "ELEMENT": "1"
    },
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": ".weblogin"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": "#badElement"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": "#weblogin"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "0"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": "#webdriver"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "element-6066-11e4-a52e-4f735466cecf": "5cc459b8-36a8-3042-8b4a-258883ea642b"
      }
    ]
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": "#weblogin-multiple"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "0"
      },
      {
        "ELEMENT": "1"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "xpath",
    "value": "//weblogin"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "0"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/elements",
  "postdata": {
    "using": "css selector",
    "value": "#signupSection"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "0"
      },
      {
        "ELEMENT": "1"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/element/0/elements",
  "postdata": {
    "using": "css selector",
    "value": "#helpBtn"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "1"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/element/0/elements",
  "postdata": {
    "using": "css selector",
    "value": ".btn"
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "value": [
      {
        "ELEMENT": "1"
      },
      {
        "ELEMENT": "2"
      },
      {
        "ELEMENT": "3"
      }
    ],
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/buttondown",
  "postdata": {
    "button": 0
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/window",
  "response": {
    "sessionId": "1352110219202",
    "status": 0
  },
  "method": "DELETE"
},
{
  "url": "/wd/hub/session/1352110219202/window",
  "method": "POST",
  "response": {
    "sessionId": "1352110219202",
    "status": 0
  }
},
{
  "url": "/wd/hub/session/1352110219202/buttondown",
  "postdata": {
    "button": 1
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
},
{
  "url": "/wd/hub/session/1352110219202/buttonup",
  "postdata": {
    "button": 2
  },
  "response": {
    "sessionId": "1352110219202",
    "status": 0,
    "class": "org.openqa.selenium.remote.Response",
    "hCode": 604376696
  }
}

]
}


File: test/lib/mocks/mocks-jsonwire.yaml


mocks:

Default JSON Wire session request with Selenium

  • url: '/wd/hub/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    browserName: firefox
    'moz:firefoxOptions':
    prefs:
    'remote.active-protocols': 3

    response:
    status: 0
    sessionId: &sessionId '1352110219202'
    value:
    browserName: firefox
    browserVersion: TEST_firefox

    state:
    responseHeaders: {}
    statusCode: 201
    method: POST
    matchEmpty: false

  • url: '/wd/hub/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    browserName: firefox

    response:
    status: 0
    sessionId: &sessionId '1352110219202'
    value:
    browserName: firefox
    browserVersion: TEST_firefox

    state:
    responseHeaders: {}
    statusCode: 201
    method: POST
    matchEmpty: true

  • url: '/wd/hub/session/1352110219202'
    method: DELETE
    response:
    status: 0
    state: success

  • url: '/wd/hub/session/1352110219202/url'
    postdata:
    url: http://localhost
    response:
    status: 0

  • url: '/wd/hub/session/1352110219202/url'
    postdata:
    url: http://localhost/test_url
    response:
    status: 0

  • url: '/wd/hub/session/1352110219202/url'
    postdata:
    url: http://localhost/homepage
    response:
    status: 0

  • url: '/wd/hub/session/1352110219202/url'
    method: GET
    response:
    status: 0
    value: http://localhost

  • url: '/wd/hub/test'
    response:
    status: 0

  • url: '/wd/hub/test_error'
    response:
    status: 7
    value:
    screen: screenshot_data

    statusCode: 500

  • url: '/wd/hub/session/1352110219202/element'
    postdata:
    using: 'css selector'
    value: '#weblogin'
    response:
    sessionId: '1352110219202'
    status: 0
    value:
    ELEMENT: '0'

    class: org.openqa.selenium.remote.Response
    hCode: 604376696

  • url: '/wd/hub/session/1352110219202/element'
    postdata:
    using: 'css selector'
    value: '#signupSection'
    response:
    sessionId: *sessionId
    status: 0
    value:
    ELEMENT: '0'

  • url: '/wd/hub/session/1352110219202/element'
    postdata:
    using: xpath
    value: '//weblogin'
    response:
    sessionId: *sessionId
    status: 0
    value:
    ELEMENT: '0'

  • url: '/wd/hub/session/1352110219202/element/0/element'
    postdata:
    using: 'css selector'
    value: '#helpBtn'
    response:
    sessionId: *sessionId
    status: 0
    value:
    ELEMENT: '1'

  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '.weblogin'
    response:
    sessionId: *sessionId
    status: 0
    value: []

  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '#badElement'
    response:
    sessionId: *sessionId
    status: 0
    value: []

  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '#weblogin'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '0'
  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '#weblogin-multiple'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '0'
    • ELEMENT: '1'
  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: xpath
    value: '//weblogin'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '0'
  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '#signupSection'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '0'
  • url: '/wd/hub/session/1352110219202/element/0/elements'
    postdata:
    using: 'css selector'
    value: '#helpBtn'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '1'
  • url: '/wd/hub/session/1352110219202/element/0/elements'
    postdata:
    using: 'css selector'
    value: '.btn'
    response:
    sessionId: *sessionId
    status: 0
    value:

    • ELEMENT: '1'
    • ELEMENT: '2'
    • ELEMENT: '3'
  • url: '/wd/hub/session/1352110219202/buttondown'
    postdata:
    button: 0
    response:
    sessionId: *sessionId
    status: 0

  • url: '/wd/hub/session/1352110219202/window'
    response:
    sessionId: *sessionId
    status: 0
    method: DELETE

  • url: '/wd/hub/session/1352110219202/window'
    method: POST
    response:
    sessionId: *sessionId
    status: 0

  • url: '/wd/hub/session/1352110219202/buttondown'
    postdata:
    button: 1
    response:
    sessionId: *sessionId
    status: 0

  • url: '/wd/hub/session/1352110219202/buttonup'
    postdata:
    button: 2
    response:
    sessionId: *sessionId
    status: 0

  • url: '/wd/hub/session/1352110219202/se/log'
    postdata:
    type: 'browser'
    method: POST
    response:
    sessionId: *sessionId
    status: 0
    value:

    • level: 'info'
      timestamp: 534547832
      message: 'Test log'
    • level: 'info'
      timestamp: 534547442
      message: 'Test log2'

File: test/lib/mocks/mocks-w3c.yaml


mocks:

Webdriver session request without Selenium

-------------------------------------------------------

  • url: '/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    browserName: firefox
    'moz:firefoxOptions':
    prefs:
    'remote.active-protocols': 3

    response:
    value:
    sessionId: &webdriverSessionId '13521-10219-202'
    capabilities:
    acceptInsecureCerts: false
    browserName: firefox
    browserVersion: 65.0.1
    platformName: linux
    platformVersion: 4.9.125-linuxkit
    setWindowRect: true
    strictFileInteractability: false
    timeouts:
    implicit: 0
    pageLoad: 300000
    script: 30000
    unhandledPromptBehavior: 'dismiss and notify'

    responseHeaders: {}
    statusCode: 201
    method: POST

  • url: '/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    browserName: firefox

    response:
    value:
    sessionId: '13521-10219-202'
    capabilities:
    acceptInsecureCerts: false
    browserName: firefox
    browserVersion: 65.0.1
    platformName: linux
    platformVersion: 4.9.125-linuxkit
    setWindowRect: true
    strictFileInteractability: false
    timeouts:
    implicit: 0
    pageLoad: 300000
    script: 30000
    unhandledPromptBehavior: 'dismiss and notify'

    responseHeaders: {}
    statusCode: 201
    method: POST

  • url: '/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    browserName: firefox

    response:
    value:
    sessionId: '13521-10219-202'
    capabilities:
    browserName: firefox
    browserVersion: 65.0.1
    platformName: linux
    platformVersion: 4.9.125-linuxkit

    responseHeaders: {}
    statusCode: 201
    method: POST

  • url: '/session'
    postdata:
    desiredCapabilities:
    browserName: safari
    platformName: iOS
    safari:useSimulator: true
    safari.options: {}

    capabilities:
    alwaysMatch:
    browserName: safari
    platformName: iOS
    safari:useSimulator: true

    response:
    value:
    sessionId: '13521-10219-202'
    capabilities:
    browserName: safari
    platformName: iOS
    safari:useSimulator: true
    safari:platformVersion: 15.6.1

    responseHeaders: {}
    statusCode: 201
    method: POST

  • url: '/wd/hub/session'
    postdata:
    capabilities:
    firstMatch: [{}]
    alwaysMatch:
    appium:automationName: "XCUITest"
    appium:appPackage: "org.wikimedia.wikipedia"
    platformName: "iOS"
    appium:deviceName: "iPhone 13"
    appium:platformVersion: "15.5"

    response:
    value:
    sessionId: '13521-10219-202'
    capabilities:
    appium:automationName: "XCUITest"
    appium:appPackage: "org.wikimedia.wikipedia"
    platformName: "iOS"
    appium:deviceName: "iPhone 13"
    appium:platformVersion: "15.5"

    responseHeaders: {}
    statusCode: 201
    method: POST

  • url: '/wd/hub/session/1352110219202/element'
    postdata:
    using: 'css selector'
    value: '#webdriver'
    response:
    sessionId: '1352110219202'
    status: 0
    value:
    element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b

  • url: '/session/13521-10219-202/element'
    postdata:
    using: 'css selector'
    value: '#webdriver'
    response:
    value:
    element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b

  • url: '/wd/hub/session/1352110219202/elements'
    postdata:
    using: 'css selector'
    value: '#webdriver'
    response:
    sessionId: '1352110219202'
    status: 0
    value:

    • element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b
  • url: '/session/13521-10219-202/elements'
    postdata:
    using: 'css selector'
    value: '#webdriver'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b
    • element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f
  • url: '/session/13521-10219-202/elements'
    postdata:
    using: 'css selector'
    value: '#weblogin'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b
    • element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f
  • url: '/session/13521-10219-202/elements'
    postdata:
    using: 'xpath'
    value: '//weblogin'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b
    • element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f
  • url: '/session/13521-10219-202/elements'
    postdata:
    using: 'css selector'
    value: 'html'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: '00'
  • url: '/session/13521-10219-202/element/00/elements'
    postdata:
    using: 'css selector'
    value: '#signupSection'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: '0'
  • url: '/session/13521-10219-202/elements'
    postdata:
    using: 'css selector'
    value: '#signupSection'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: '0'
  • url: '/session/13521-10219-202/element/0/elements'
    postdata:
    using: 'css selector'
    value: '#helpBtn'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: '1'
  • url: '/session/13521-10219-202/element/0/elements'
    postdata:
    using: 'css selector'
    value: '.btn'
    response:
    value:

    • element-6066-11e4-a52e-4f735466cecf: '1'
    • element-6066-11e4-a52e-4f735466cecf: '2'
    • element-6066-11e4-a52e-4f735466cecf: '3'

File: test/typescript-tests/tsconfig.nightwatch.json

{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"strict": true,
"rootDir": ".",
"outDir": "dist",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"sourceMap": false,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"skipLibCheck": true
}
}


File: types/tests/tsconfig.json

{
"extends": "../../tsconfig",
"include": ["."]
}


File: .github/FUNDING.yml

open_collective: nightwatch


File: .github/label-commenter-config.yml

Configuration for Label Commenter - https://github.com/peaceiris/actions-label-commenter

labels:

  • name: needs-triaging
    labeled:
    issue:
    body: |
    @{{ issue.user.login }}, thank you for creating this issue. We will troubleshoot it as soon as we can.

    ---

    Info for maintainers



    Triage this issue by using labels.


    If information is missing, add a helpful comment and add the I-issue-template label.


    Thank you!

  • name: I-issue-template
    labeled:
    issue:
    body: |
    Hi, @{{ issue.user.login }}.
    Please follow the issue template, we need more information to reproduce the issue.

    Either a complete code snippet (if more than one file is needed, provide a GitHub repo and instructions to run the code), the specific versions used, or a more detailed description to help us understand the issue.

    Reply to this issue when all information is provided, thank you.


File: .github/PULL_REQUEST_TEMPLATE.md

Thanks in advance for your contribution. Please follow the below steps in submitting a pull request, as it will help us with reviewing it quicker.

  • Before marking your PR for review, please test and verify your changes by making appropriate modifications to any of the Nightwatch example tests (present in examples/tests directory of the project) and running them. ecosia.js and duckDuckGo.js are good examples to work with.
  • Create a new branch from master (e.g. features/my-new-feature or issue/123-my-bugfix);
  • If you're fixing a bug also create an issue if one doesn't exist yet;
  • If it's a new feature explain why do you think it's necessary. Please check with the maintainers beforehand to make sure it is something that we will accept. Usually we only accept new features if we feel that they will benefit the entire community;
  • Please avoid sending PRs which contain drastic or low level changes. If you are certain that the changes are needed, please discuss them beforehand and indicate what the impact will be;
  • If your change is based on existing functionality please consider refactoring first. Pull requests that duplicate code will most likely be ignored;
  • Do not include changes that are not related to the issue at hand;
  • Follow the same coding style with regards to spaces, semicolons, variable naming etc.;
  • Always add unit tests - PRs without tests are most of the times ignored.

File: .github/stale.yml

Number of days of inactivity before an issue becomes stale

daysUntilStale: 90

Number of days of inactivity before a stale issue is closed

daysUntilClose: 7

Issues with these labels will never be considered stale

exemptLabels:

  • META
  • pinned
  • enhancement

Label to use when marking an issue as stale

staleLabel: stale

Comment to post when marking an issue as stale. Set to `false` to disable

markComment: >
This issue has been automatically marked as stale because it has not had any recent activity.

If possible, please retry using the latest Nightwatch version and update the issue with any relevant details.
If no further activity occurs, it will be closed. Thank you for your contribution.

Comment to post when closing a stale issue. Set to `false` to disable

closeComment: false


File: .github/ISSUE_TEMPLATE/bug_report.yml

name: "Bug Report"
body:

  • type: "markdown"
    attributes:
    value: |
    Thanks in advance for your contribution. Before submitting a new issue, try searching for a similar one here: https://github.com/nightwatchjs/nightwatch/search?type=Issues.
  • type: "textarea"
    id: "description"
    attributes:
    label: "Description of the bug/issue"
    placeholder: |
    When I ____, I expected ____ to happen but ____ happened instead.

    validations:
    required: true
  • type: "textarea"
    id: "steps"
    attributes:
    label: "Steps to reproduce"
    Explain how to cause the issue in the provided reproduction.

    value: |
    1. Go to '...'
    2. Click on '...'
    3. Scroll down to '...'
    4. See error
  • type: textarea
    id: "sample-test"
    attributes:
    label: "Sample test"
    Include a sample test that reproduces the problem you're experiencing. If possible, the test should be against a public URL.

    Please add the test and other info inline, not as attachments or screenshots.

    placeholder: |
    // Please add the sample test here

    module.exports = {
    sampleTest: function() {
    browser
    .navigateTo('')
    .click('')
    .end();
    }
    }

    render: node
  • type: textarea
    id: "run-with-command"
    attributes:
    label: "Command to run"
    placeholder: |
    nightwatch test/sampleTest.js --your-other-arguments-here

    render: bash
  • type: textarea
    id: "verbose-output"
    attributes:
    label: "Verbose Output"
    "Extended nightwatch command logging during the session.
    Please use nightwatch --verbose and paste the output here"

    placeholder: |
    [Sample Test] Test Suite
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    โ ‹ Starting ChromeDriver on port 9515...
    Request POST /session
    {
    desiredCapabilities: {
    browserName: 'chrome',
    'goog:chromeOptions': { w3c: true, args: [] },
    name: 'Sample Test'
    },
    capabilities: {
    alwaysMatch: {
    browserName: 'chrome',
    'goog:chromeOptions': { w3c: true, args: [] }
    }
    }

    render: fundamental
  • type: textarea
    id: "configuration"
    attributes:
    label: "Nightwatch Configuration"
    placeholder: |
    module.exports = {
    src_folders: [],
    page_objects_path: [],
    custom_commands_path: [],
    custom_assertions_path: '',
    plugins: [],
    globals_path: '',
    webdriver: {},
    test_settings: {}
    }

    render: node
  • type: "markdown"
    attributes:
    value: |
    ## Your Environment
    Include the relevant details related to your environment.
  • type: "input"
    id: "nightwatch-version"
    attributes:
    label: "Nightwatch.js Version"
    placeholder: "2.3.0"
    validations:
    required: true
  • type: "input"
    id: "node-version"
    attributes:
    label: "Node Version"
    placeholder: "14.0.0"
  • type: "input"
    id: "browser"
    attributes:
    label: "Browser"
    placeholder: "Firefox 102.0.1; Chrome 104.0.0"
  • type: "input"
    id: "operating-system"
    attributes:
    label: "Operating System"
    placeholder: "MacOs Monterey 12.5"
  • type: "textarea"
    id: "additional-information"
    attributes:
    label: "Additional Information"
    Use this section to provide any additional information you might have
    like screenshots, notes, or links to ideas.

File: .github/ISSUE_TEMPLATE/config.yml

blank_issues_enabled: true
contact_links:


File: .github/ISSUE_TEMPLATE/feature-request.yml

name: "Feature Request"
labels: ["enhancement"]
body:

  • type: "markdown"
    attributes:
    value: |
    Thanks in advance for your contribution. Before requesting a new feature, try searching for a similar issue here: https://github.com/nightwatchjs/nightwatch/search?type=Issues.
  • type: "textarea"
    id: "description"
    attributes:
    label: "Description"
    validations:
    required: true
  • type: "textarea"
    id: "proposed-solution"
    attributes:
    label: "Suggested solution"
    Please provide code snippets, gists, or links to the ideal
    design or API.
  • type: "textarea"
    id: "alternatives"
    attributes:
    label: "Alternatives / Workarounds"
    What alternative solutions have you considered before making this
    request?
  • type: "textarea"
    id: "additional-information"
    attributes:
    label: "Additional Information"
    What resources (links, screenshots, etc.) do you have to assist this
    effort?

File: .github/workflows/build-node.yaml

This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node

For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: tests

on:
push:
branches: [ main]
pull_request:
branches: [ main]

jobs:
linux:

text
runs-on: ubuntu-latest

strategy:
  fail-fast: false
  matrix:
    node-version: [18.x, 20.x, 22.x, 24.x]
    # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
  uses: actions/setup-node@v2
  with:
    node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run eslint
- run: npm test

windows:
runs-on: windows-latest

text
strategy:
  fail-fast: false
  matrix:
    node-version: [18.x, 20.x, 22.x, 24.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
  uses: actions/setup-node@v2
  with:
    node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run eslint
- run: npm test

File: .github/workflows/component-tests.yaml

name: component-tests

on:
push:
branches: [ main]
pull_request:
branches: [ main]

jobs:
linux:

text
runs-on: ubuntu-latest

strategy:
  matrix:
    node-version: [18.x]
steps:
  - uses: actions/checkout@v2
  - name: Use Node.js ${{ matrix.node-version }}
    uses: actions/setup-node@v2
    with:
      node-version: ${{ matrix.node-version }}
  - run: npm ci

- run: npm i @nightwatch/react @nightwatch/vue @testing-library/dom vite-plugin-nightwatch vue react react-dom

- run: npm run component-tests


File: .github/workflows/coverage.yml

This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node

For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Coverage Job

on:
push:
branches: [ ]
pull_request:
branches: [ ]

jobs:
build:

text
runs-on: ubuntu-latest

strategy:
  matrix:
    node-version: [18.x]
    # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
  uses: actions/setup-node@v2
  with:
    node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run eslint
- run: npm run mocha-coverage
- run: npm run coverage

- name: Upload coverage to Codecov
  uses: codecov/codecov-action@v1
  with:
    token: ${{ secrets.CODECOV_ACCESS_TOKEN }}
    files: ./coverage/mocha_coverage.lcov
    flags: unittests
    name: codecov-umbrella
    fail_ci_if_error: true
    path_to_write_report: codecov_report.txt
    verbose: false

File: .github/workflows/label-commenter.yml

Configuration for Label Commenter - https://github.com/peaceiris/actions-label-commenter

name: Label Commenter

on:
issues:
types: [ labeled ]

permissions:
contents: read
issues: write

jobs:
comment:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Label Commenter
uses: peaceiris/actions-label-commenter@v1


File: .github/workflows/missing-types-comment.yml

name: Add comment for missing types

on:
workflow_run:
workflows: ["Check missing types"]
types:
- completed

jobs:
add_comment:
runs-on: ubuntu-latest
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
steps:
- name: 'Download artifact'
uses: actions/github-script@v6
with:
script: |
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{github.event.workflow_run.id }},
});
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr"
})[0];
var download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
var fs = require('fs');
fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));

text
- name: 'Read artifact'
    id: modified-files
    run: |
      unzip pr.zip
      cat files_changed
      echo "modified=$(cat files_changed)" >> "$GITHUB_OUTPUT"

  - name: Comment on PR
    if: steps.modified-files.outputs.modified == ''
    id: comment-on-pr
    uses: actions/github-script@v6
    with:
      script: |
        const fs = require('fs');
        const issue_number = Number(fs.readFileSync('./NR'));
        const comment = `
        ## Status
        * โŒ No modified files found in the **types** directory.
        Please make sure to include types for any changes you have made. Thank you!.`;
        const pullRequest = await github.rest.pulls.get({
          owner: context.repo.owner,
          repo: context.repo.repo,
          pull_number: issue_number
        });
        const comments = await github.rest.issues.listComments({
          owner: context.repo.owner,
          repo: context.repo.repo,
          issue_number: issue_number
        });
        const existingComment = comments.data.find(comment => comment.user.login === 'github-actions[bot]' && comment.body.includes('No modified files found in the **types** director'));
        if (existingComment) {
          console.log('Comment already exists');
        } else {
          await github.rest.issues.createComment({
            owner: context.repo.owner,
            repo: context.repo.repo,
            issue_number: issue_number,
            body: comment
          });
        }

  - name: Edit comment on PR
    if: steps.modified-files.outputs.modified != ''
    uses: actions/github-script@v6
    with:
      script: |
        const fs = require('fs');
        const issue_number = Number(fs.readFileSync('./NR'));
        const comment = `
        ## Status
        * :white_check_mark: Type files updated!`;
        const comments = await github.rest.issues.listComments({
          owner: context.repo.owner,
          repo: context.repo.repo,
          issue_number: issue_number
        });
        const existingComment = comments.data.find(comment => comment.user.login === 'github-actions[bot]' && comment.body.includes('No modified files found in the **types** director'));
        if (existingComment) {
          await github.rest.issues.updateComment({
            owner: context.repo.owner,
            repo: context.repo.repo,
            comment_id: existingComment.id,
            body: comment
          });
        }

File: .github/workflows/missing-types.yml

name: Check missing types

on: pull_request

jobs:
detect-modified-files:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0

text
- name: Get modified files
    id: modified-files
    run: |
      echo $(git diff --name-only origin/$GITHUB_BASE_REF $GITHUB_SHA types/ | tr '\n' ',')
      mkdir -p ./pr
      echo $(git diff --name-only origin/$GITHUB_BASE_REF $GITHUB_SHA types/ | tr '\n' ',') > ./pr/files_changed
      echo ${{ github.event.number }} > ./pr/NR

  - uses: actions/upload-artifact@v4
    with:
      name: pr
      path: pr/

File: .github/workflows/nightly.yml

name: Nightly

on:
workflow_dispatch:
inputs:
version:
required: false
type: string
default: ''
ref:
required: false
type: string
default: ''

jobs:
nightly:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref }}
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18.x'
- name: Install dependencies
run: npm install
- name: Build Nightwatch
run: npm run build
- name: Create publishable package ๐Ÿ“ฆ
run: npm pack
- name: Release Nightly
uses: marvinpinto/action-automatic-releases@latest
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "nightly-${{ inputs.version }}"
title: "Nightly ${{ inputs.version }}"
prerelease: true
files: '*.tgz'


File: .github/workflows/publish.yml

name: Publish to NPM
on:
push:
tags:
- vv* # to enable this action, change this tag back to v*
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm install
- name: Publish package on NPM ๐Ÿ“ฆ
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}


File: .github/workflows/type-declaration-tests.yml

name: Type Declaration Tests

on:
push:
branches: [main, feat/types-test]
pull_request:
branches: [main]

jobs:
linux:
runs-on: ubuntu-latest

text
strategy:
  matrix:
    node-version: [18.x]
    typescript-version: [3.9, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0]
steps:
  - uses: actions/checkout@v2
  - name: Use Node.js ${{ matrix.node-version }}
    uses: actions/setup-node@v2
    with:
      node-version: ${{ matrix.node-version }}
  - name: Install TypeScript
    run: npm install typescript@${{ matrix.typescript-version }}
  - name: Install Dependencies
    run: npm ci
  - run: npm run test:types