Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Workflow:Nightwatchjs Nightwatch Custom Commands And Assertions

From Leeroopedia
Knowledge Sources
Domains E2E_Testing, Framework_Extension, Test_Architecture
Last Updated 2026-02-12 00:00 GMT

Overview

End-to-end process for extending Nightwatch with reusable custom commands and custom assertions that encapsulate common testing patterns for a specific application domain.

Description

This workflow covers creating custom commands (reusable action sequences) and custom assertions (domain-specific validation logic) that integrate seamlessly into the Nightwatch API. Custom commands appear on the browser object and can be chained like built-in commands. Custom assertions integrate with the assert and verify namespaces. Both mechanisms support async/await, class-based definitions, and namespaced organization for large projects.

Usage

Execute this workflow when your test suite contains repeated multi-step interactions or validation patterns that would benefit from abstraction. Common triggers include repeated login sequences, complex form-filling patterns, application-specific element state checks, or any interaction that appears in three or more test files.

Execution Steps

Step 1: Configure Extension Paths

Set the custom_commands_path and custom_assertions_path in the Nightwatch configuration. These paths tell the framework where to discover and load custom extensions at startup. Multiple paths can be specified as arrays.

Key considerations:

  • Paths can be absolute or relative to the project root
  • Subdirectories are loaded recursively and can create namespaced commands
  • Plugin-provided commands are loaded from the plugin's nightwatch/commands directory
  • Assertion paths follow the same pattern as command paths

Step 2: Create Custom Commands

Write command modules that export either a function-style command or an ES6 class. Function-style commands receive arguments and return the browser instance for chaining. Class-style commands extend the base command and implement an async command() method.

What happens:

  • Function commands use module.exports with a command property function
  • Class commands define an async command() method that performs the action
  • Commands access the browser API via this (function-style) or this.api (class-style)
  • Commands can compose multiple built-in commands into a single high-level action
  • The command name matches the filename (e.g., strictClick.js becomes browser.strictClick())

Step 3: Create Custom Assertions

Write assertion modules that define the validation logic for a custom check. Each assertion module exports an object with expected(), pass(), value(), and command() methods that the framework calls during assertion evaluation.

Key considerations:

  • The command() method executes the WebDriver call to retrieve the actual value
  • The value() method extracts the relevant value from the command result
  • The pass() method compares actual vs. expected and returns a boolean
  • Custom assertions appear under browser.assert.assertionName() and browser.verify.assertionName()
  • Assertions support retry via the framework's assertion retry mechanism

Step 4: Implement Namespaced Commands

Organize commands into subdirectories to create namespaced access patterns. Commands in subdirectories are accessed via dot notation on the browser object, preventing name collisions in large projects.

What happens:

  • Place command files in subdirectories (e.g., custom-commands/auth/login.js)
  • Access via browser.auth.login() using the directory as namespace
  • Multiple namespace levels are supported via deeper nesting
  • Namespace aliases can be defined for convenience

Step 5: Use Extensions in Tests

Reference custom commands and assertions in test files exactly like built-in Nightwatch commands. Custom commands are available on the browser object, custom assertions on browser.assert and browser.verify.

Key considerations:

  • Custom commands chain with built-in commands seamlessly
  • Custom assertions follow the same pass/fail/retry semantics as built-in assertions
  • TypeScript type definitions can be added for custom extensions
  • Extensions are available in all test files without explicit import

Execution Diagram

GitHub URL

Workflow Repository