CodeceptJS
CodeceptJS is an open-source, full-featured End-to-End (E2E) testing framework for Node.js, designed to make acceptance tests human-readable and maintainable. It currently offers a stable version 3.7.8, with version 4.x actively under development as Release Candidates, indicating a continuous release cadence with frequent updates and significant upcoming changes. A key differentiator is its synchronous test syntax, which allows test scenarios to be written linearly without explicit handling of promises or async/await, greatly simplifying test authoring from a user's perspective. It abstracts away the underlying browser automation drivers, supporting various helpers like Playwright, Puppeteer, WebDriver, TestCafe, and Appium, enabling testers to choose their preferred backend while keeping test scripts consistent. This framework focuses on behavioral-driven development (BDD) by providing a natural language API via the `I` object (or `actor`), making tests accessible even to non-technical stakeholders.
Common errors
-
ReferenceError: I is not defined
cause Attempting to run a CodeceptJS test file directly via Node.js (e.g., `node my_test.js`) instead of through the CodeceptJS runner.fixAlways execute CodeceptJS tests using the CodeceptJS CLI: `npx codeceptjs run` or `npx codeceptjs run --steps`. -
Error: Helper 'Playwright' is not defined in config.
cause The specified helper (e.g., Playwright, Puppeteer, WebDriver) is not correctly configured in your `codecept.conf.js` (or `.ts`) file, or the corresponding npm package is not installed.fixEnsure your `codecept.conf.js` has an entry in the `helpers` section for the desired helper (e.g., `Playwright: { url: '...', browser: 'chromium' }`) and that the helper package is installed (e.g., `npm install --save-dev playwright`). -
MultipleElementsFound: Multiple elements found by selector "//button". Specify a more precise selector or use elementIndex option.
cause A selector used in an `I` action (e.g., `I.click('//button')`) matched more than one element on the page, and the helper is in strict mode (default in v4.x).fixRefine your selector to be more specific (e.g., `I.click('//button[contains(., "Submit")]')` or `I.click({ css: 'div.form button.submit' })`), or use the `elementIndex` option if you intentionally want to target a specific one among multiple matches (e.g., `I.click('//button', null, 1)` to click the second matching button).
Warnings
- breaking CodeceptJS v4.x introduces significant internal refactorings, including the elimination of internal globals in favor of a store singleton, which can break existing plugins or custom code relying on these internals. The 'auth' plugin's `loginAs` injection method is known to be broken in v4.x. Additionally, the built-in HTML reporter has been removed, recommending `@testomatio/reporter` as an alternative.
- breaking Version 4.x introduces 'strict mode' for all helpers by default, which improves error reporting but can lead to new 'MultipleElementsFound' errors where previously the first matching element might have been implicitly chosen. Furthermore, there's a fix for `cheerio` ESM import issues in v4.x, indicating a broader shift towards ESM compatibility that might require adjustments in user environments or plugins.
- gotcha CodeceptJS tests are designed to be synchronous in their syntax, which abstracts away promises and `async/await` for typical `I` actions. While this simplifies test writing, users accustomed to explicit asynchronous patterns in JavaScript might mistakenly add `async/await` to `I` actions, which is generally not needed and can sometimes interfere with CodeceptJS's internal promise chain management, particularly when dealing with helper method returns.
- security Several security issues were fixed in version 3.7.8. Running older versions, particularly prior to 3.7.8, could expose your test environment or application under test to known vulnerabilities. It is crucial to keep CodeceptJS and its dependencies updated.
Install
-
npm install codeceptjs -
yarn add codeceptjs -
pnpm add codeceptjs
Imports
- container
const { container } = require('codeceptjs')import { container } from 'codeceptjs' - event
const { event } = require('codeceptjs')import { event } from 'codeceptjs' - I
import type { I } from 'codeceptjs'
Quickstart
import { config } from './codecept.conf';
// codecept.conf.ts (or .js)
// This file defines your CodeceptJS configuration, including helpers.
export const config: CodeceptJS.MainConfig = {
tests: './*_test.ts',
output: './output',
helpers: {
Playwright: {
url: 'http://localhost:8080', // Your application's base URL
show: true, // Show browser UI during tests
browser: 'chromium' // Specify browser (chromium, firefox, webkit)
}
},
bootstrap: null,
mocha: {},
name: 'my-codeceptjs-tests',
plugins: {
pauseOnFail: {},
retryFailedStep: { enabled: true },
tryTo: { enabled: true },
screenshotOnFail: { enabled: true }
}
};
// my_first_test.ts (or .js)
// This file contains your actual test scenarios.
// To run:
// 1. Make sure 'playwright' is installed: `npm i --save-dev playwright`
// 2. Run CodeceptJS: `npx codeceptjs run --steps`
Feature('User Authentication Flow');
Scenario('Verify successful login', async ({ I }) => {
I.amOnPage('/');
I.see('Welcome to My App'); // Assert initial text
I.click('Sign In');
I.seeCurrentUrlEquals('/login');
I.fillField('Username', 'testuser');
I.fillField('Password', 'correctpassword');
I.click('Login Button');
I.see('Welcome, testuser!'); // Assert post-login message
I.seeCurrentUrlEquals('/dashboard');
}).tag('smoke');
Scenario('Verify invalid login attempt', async ({ I }) => {
I.amOnPage('/login');
I.fillField('Username', 'invaliduser');
I.fillField('Password', 'wrongpassword');
I.click('Login Button');
I.see('Invalid credentials'); // Assert error message
I.seeCurrentUrlEquals('/login');
}).tag('negative');