codeceptjs
Advanced tools
Changelog
3.7.2
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
🐛 Bug Fixes
📖 Documentation
Changelog
3.7.0
This release introduces major new features and internal refactoring. It is an important step toward the 4.0 release planned soon, which will remove all deprecations introduced in 3.7.
🛩️ Features
A new Els API for direct element interactions has been introduced. This API provides low-level element manipulation functions for more granular control over element interactions and assertions:
element()
- perform custom operations on first matching elementeachElement()
- iterate and perform operations on each matching elementexpectElement()
- assert condition on first matching elementexpectAnyElement()
- assert condition matches at least one elementexpectAllElements()
- assert condition matches all elementsExample using all element functions:
const { element, eachElement, expectElement, expectAnyElement, expectAllElements } = require('codeceptjs/els')
// ...
Scenario('element functions demo', async ({ I }) => {
// Get attribute of first button
const attr = await element('.button', async el => await el.getAttribute('data-test'))
// Log text of each list item
await eachElement('.list-item', async (el, idx) => {
console.log(`Item ${idx}: ${await el.getText()}`)
})
// Assert first submit button is enabled
await expectElement('.submit', async el => await el.isEnabled())
// Assert at least one product is in stock
await expectAnyElement('.product', async el => {
return (await el.getAttribute('data-status')) === 'in-stock'
})
// Assert all required fields have required attribute
await expectAllElements('.required', async el => {
return (await el.getAttribute('required')) !== null
})
})
Els functions expose the native API of Playwright, WebDriver, and Puppeteer helpers. The actual el
API will differ depending on which helper is used, which affects test code interoperability.
Effects is a new concept that encompasses all functions that can modify scenario flow. These functions are now part of a single module. Previously, they were used via plugins like tryTo
and retryTo
. Now, it is recommended to import them directly:
const { tryTo, retryTo } = require('codeceptjs/effects')
Scenario(..., ({ I }) => {
I.amOnPage('/')
// tryTo returns boolean if code in function fails
// use it to execute actions that may fail but not affect the test flow
// for instance, for accepting cookie banners
const isItWorking = tryTo(() => I.see('It works'))
// run multiple steps and retry on failure
retryTo(() => {
I.click('Start Working!');
I.see('It works')
}, 5);
})
Previously tryTo
and retryTo
were available globally via plugins. This behavior is deprecated as of 3.7 and will be removed in 4.0. Import these functions via effects instead. Similarly, within
will be moved to effects
in 4.0.
check
command addednpx codeceptjs check
This command can be executed locally or in CI environments to verify that tests can be executed correctly.
It checks:
And will attempt to open and close a browser if a corresponding helper is enabled. If something goes wrong, the command will fail with a message. Run npx codeceptjs check
on CI before actual tests to ensure everything is set up correctly and all services and browsers are accessible.
For GitHub Actions, add this command:
steps:
# ...
- name: check configuration and browser
run: npx codeceptjs check
- name: run codeceptjs tests
run: npx codeceptjs run-workers 4
This AI plugin analyzes failures in test runs and provides brief summaries. For more than 5 failures, it performs cluster analysis and aggregates failures into groups, attempting to find common causes. It is recommended to use Deepseek R1 model or OpenAI o3 for better reasoning on clustering:
• SUMMARY The test failed because the expected text "Sign in" was not found on the page, indicating a possible issue with HTML elements or their visibility.
• ERROR expected web application to include "Sign in"
• CATEGORY HTML / page elements (not found, not visible, etc)
• URL http://127.0.0.1:3000/users/sign_in
For fewer than 5 failures, they are analyzed individually. If a visual recognition model is connected, AI will also scan screenshots to suggest potential failure causes (missing button, missing text, etc).
This plugin should be paired with the newly added pageInfo
plugin which stores important information like URL, console logs, and error classes for further analysis.
auth
is the new name for the autoLogin plugin and aims to solve common authorization issues. In 3.7 it can use Playwright's storage state to load authorization cookies in a browser on start. So if a user is already authorized, a browser session starts with cookies already loaded for this user. If you use Playwright, you can enable this behavior using the loginAs
method inside a BeforeSuite
hook:
BeforeSuite(({ loginAs }) => loginAs('user'))
The previous behavior where loginAs
was called from a Before
hook also works. However, cookie loading and authorization checking is performed after the browser starts.
Meta information in key-value format can be attached to Scenarios to provide more context when reporting tests:
// add Jira issue to scenario
Scenario('...', () => {
// ...
}).meta('JIRA', 'TST-123')
// or pass meta info in the beginning of scenario:
Scenario('my test linked to Jira', meta: { issue: 'TST-123' }, () => {
// ...
})
By default, Playwright helpers add browser and window size as meta information to tests.
Custom Steps or Sections API introduced to group steps into sections:
const { Section } = require('codeceptjs/steps');
Scenario({ I } => {
I.amOnPage('/projects');
// start section "Create project"
Section('Create a project');
I.click('Create');
I.fillField('title', 'Project 123')
I.click('Save')
I.see('Project created')
// calling Section with empty param closes previous section
Section()
// previous section automatically closes
// when new section starts
Section('open project')
// ...
});
To hide steps inside a section from output use Section().hidden()
call:
Section('Create a project').hidden()
// next steps are not printed:
I.click('Create')
I.fillField('title', 'Project 123')
Section()
Alternative syntax for closing section: EndSection
:
const { Section, EndSection } = require('codeceptjs/steps');
// ...
Scenario(..., ({ I }) => // ...
Section('Create a project').hidden()
// next steps are not printed:
I.click('Create');
I.fillField('title', 'Project 123')
EndSection()
Also available BDD-style pre-defined sections:
const { Given, When, Then } = require('codeceptjs/steps');
// ...
Scenario(..., ({ I }) => // ...
Given('I have a project')
// next steps are not printed:
I.click('Create');
I.fillField('title', 'Project 123')
When('I open project');
// ...
Then('I should see analytics in a project')
//....
Better syntax to set general step options for specific tests.
Use it to set timeout or retries for specific steps:
const step = require('codeceptjs/steps');
Scenario(..., ({ I }) => // ...
I.click('Create', step.timeout(10).retry(2));
//....
Alternative syntax:
const { stepTimeout, stepRetry } = require('codeceptjs/steps');
Scenario(..., ({ I }) => // ...
I.click('Create', stepTimeout(10));
I.see('Created', stepRetry(2));
//....
This change deprecates previous syntax:
I.limitTime().act(...)
=> replaced with I.act(..., stepTimeout())
I.retry().act(...)
=> replaced with I.act(..., stepRetry())
Step options should be passed as the very last argument to I.action()
call.
Step options can be used to pass additional options to currently existing methods:
const { stepOpts } = require('codeceptjs/steps')
I.see('SIGN IN', stepOpts({ ignoreCase: true }))
Currently this works only on see
and only with ignoreCase
param.
However, this syntax will be extended in next versions.
API for direct access to test object inside Scenario or hooks to add metadata or artifacts:
BeforeSuite(({ suite }) => {
// no test object here, test is not created yet
})
Before(({ test }) => {
// add artifact to test
test.artifacts.myScreenshot = 'screenshot'
})
Scenario('test store-test-and-suite test', ({ test }) => {
// add custom meta data
test.meta.browser = 'chrome'
})
After(({ test }) => {})
Object for suite
is also injected for all Scenario and hooks.
NL
translation introduced by @ebo-zig in #4784:codeceptjs run
fails on CI if no tests were executed. This helps to avoid false positive checks. Use DONT_FAIL_ON_EMPTY_RUN
env variable to disable this behaviorheal
plugin (which heals failing tests on the fly) shown in run-workers
commandplugin/standatdActingHelpers
replaced with Container.STANDARD_ACTING_HELPERS
BeforeSuite
and AfterSuite
This section is listed briefly. A new dedicated page for internal API concepts will be added to documentation
lib/mocha
lib/step
HelperStep
, MetaStep
, FuncStep
, CommentStep
step.addToRecorder()
to schedule test execution as part of global promise chainevent.all.result
now sends Result object with all failures and stats includedrun-workers
refactored to use Result
to send results from workers to main processlistener/timeout
=> globalTimeout
store
to share data on current state between different parts of systemevents
API improved
event.hook.passed
, event.hook.finished
event.test.failed
, event.test.finished
always sends Test. If test has failed in Before
or BeforeSuite
hook, event for all failed test in this suite will be sentevent.test.failed