docs: 4.x migration guide and ESM-only code samples#5538
Open
docs: 4.x migration guide and ESM-only code samples#5538
Conversation
- Add docs/migration-4.md covering ESM switch, removed helpers (Nightmare/Protractor/TestCafe/AI/SoftExpect), removed plugins (autoLogin/tryTo/retryTo/eachElement/allure/htmlReporter/wdio/etc.), Vercel AI SDK, Joi → Zod, restart=browser removal, Custom Locator Strategy removal, within → effect, noGlobals: true default, wait* relative URL resolution, strict mode, elementIndex, CLI plugin args, workers events, TypeScript loader changes. - Document hopeThat (soft assertions) in docs/effects.md as the replacement for SoftExpectHelper; clarify it works with any assertion library. - Convert ~70 CJS code samples across 19 docs to ESM (require/module.exports/exports.config → import/export default). - Fix dynamic require in pageobjects.md → static import. - Update Anthropic example in ai.md to claude-sonnet-4-6 and OpenAI example to gpt-5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- data.md: faker is a named export; restore `import { faker }`
and update the install hint from the legacy `faker` package
to `@faker-js/faker`.
- internal-api.md: lead with the named-import form and demote
the `codeceptjs` global to a footnote (it only exists when
`noGlobals: false`).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* `@codeceptjs/configure` and `@codeceptjs/expect-helper` both do
`require('codeceptjs')` from inside their own packages. End users
installing codeceptjs into a project's node_modules resolve fine —
but in this repo (where the project IS codeceptjs) Node has nothing
at node_modules/codeceptjs to resolve to, so those imports throw and
helper/plugin loading fails on every CI run. Add `npm link && npm
link codeceptjs` after install in playwright/puppeteer/webdriver/
plugin/dtslint/test workflows. Documented in CLAUDE.md.
* `lib/plugin/browser.js`: route through `setBrowserConfig` from
`@codeceptjs/configure` instead of duplicating the helper-mutation
logic inline. The configure dep is the right primitive — removing
the duplicate, single source of truth.
* `typings/index.d.ts`: drop `/// <reference types="joi" />`. joi is
not used in any public type, the directive was leftover from a prior
incarnation, and it broke `dtslint` (which looks for `@types/joi`,
doesn't exist) and the def-runner test (failed-resolution alignment
produced an undefined `resolutionDiagnostics` access in newer TS).
* Docs: `docs/configuration.md` setCommonPlugins table aligned with
4.x plugin set (no eachElement, pauseOn instead of pauseOnFail);
`docs/plugins.md` regen with aiTrace section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* `@codeceptjs/configure` is now imported dynamically. If it's not
installed (e.g. user pinned a stripped-down dep set), the plugin
prints a one-line hint and skips the override instead of crashing.
* Arg parsing rewritten as small composable functions: `parseArgs` →
`parseArg` → `parseValue`. Uses `String.split('=')` instead of
manual `indexOf`/`slice`. The hot loop is now a `reduce`.
* Drop number coercion — values stay as strings; helpers (and
setBrowserConfig's regex parsers) coerce as needed. `true`/`false`
still become real booleans for boolean-typed helper options.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both `@codeceptjs/configure@^4.0.0-beta.2` and `@codeceptjs/expect-helper@^4.0.0-beta.3` are now native ESM with codeceptjs declared as an optional peer dep, matching CodeceptJS 4.x. Caret ranges pick up future 4.x betas, RCs, and the eventual stable release without further package.json edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reframe semantic locators (`I.click('Save', '.header')`) as the
recommended default for stable scenarios, not a prototyping
shortcut. Combined with a context, they read like prose, survive
ARIA/CSS refactors, and disambiguate duplicate labels — so they're
more precise than ARIA or CSS used alone.
- Intro: lead with the "semantic + context" recipe.
- Locator-types table: split semantic into "with context" (default)
and "no context" (unique label / prototyping); document the
combined pattern as a first-class type.
- Semantic section: front-load the "pair with a context" guidance
and drop the "switch to strict locators once stable" line.
- Context section: explain why scoping every action is the
default, not the special case.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The workaround was needed only while @codeceptjs/configure and
@codeceptjs/expect-helper did `require('codeceptjs')` at load time.
After the configure import in lib/plugin/browser.js was made
optional and @codeceptjs/expect-helper was pinned to ^4.0.0-beta.3,
nothing in the repo's runtime depends on a self-resolving
node_modules/codeceptjs entry — `npm link` is dead code.
- Remove the `- run: npm link && npm link codeceptjs` step (and
surrounding comment block) from dtslint, playwright, plugin,
puppeteer, webdriver workflows, and both jobs in test.yml.
- Drop the matching "Local Development Setup" section from CLAUDE.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…kage
@codeceptjs/configure and @codeceptjs/expect-helper both do top-level
`import 'codeceptjs'`. Both passing through the test config (e.g. the
`Expect: { require: '@codeceptjs/expect-helper' }` line in the
acceptance configs) means CodeceptJS itself can't start in CI without
node_modules/codeceptjs resolving — and the runtime deps load before
any helper or test does, so disabling `codecept check` alone wasn't
enough.
Replace the previous `npm link && npm link codeceptjs` workaround with
a single `ln -sfn .. node_modules/codeceptjs`. One symlink, no global
npm state.
Workflows updated: test, dtslint, playwright, puppeteer, webdriver, plugin.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codeceptjs/configure and @codeceptjs/expect-helper currently do top-level
\`import 'codeceptjs'\`, which can't resolve inside this repo's CI (the
project IS the codeceptjs package, so npm doesn't drop a node_modules
entry to resolve to). The CI symlink works around it; the proper fix is
to give those packages an in-process handle so they don't need to look
up codeceptjs through Node's bare-specifier resolution.
This change is the codeceptjs-side prep:
- lib/host.js — sets globalThis.codeceptjs = { config, container, event,
output, recorder, Helper } as a side-effect on import. Idempotent;
matches the global @codeceptjs/helper already consults
(\`global.codeceptjs || require('codeceptjs')\`).
- lib/codecept.js + lib/plugin/browser.js — eager import of host.js so
the registry is populated before the user's codecept.conf.js loads
any companion package.
Once @codeceptjs/configure and @codeceptjs/expect-helper ship versions
that read from globalThis.codeceptjs (instead of \`import 'codeceptjs'\`),
the CI symlink can be removed. Drop-in replacements for both packages
are in scripts/upstream-patches/ — apply them upstream and bump versions
in package.json.
End-user projects are unaffected: globalThis.codeceptjs is set in normal
runs too, so the new code path is the same code path everyone takes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…This @codeceptjs/configure@4.0.0-beta.4 and @codeceptjs/expect-helper@4.0.0-beta.5 no longer do top-level `import 'codeceptjs'` — they read from the globalThis.codeceptjs registry the runner sets up in lib/host.js. The self-symlink that fed them a resolvable codeceptjs package in CI is no longer needed. - Bump @codeceptjs/configure to ^4.0.0-beta.4 - Bump @codeceptjs/expect-helper to ^4.0.0-beta.5 - Remove the `ln -sfn .. node_modules/codeceptjs` step from dtslint, playwright, plugin, puppeteer, webdriver, and test workflows - Delete scripts/upstream-patches/ — the patches it documented are now released in the companion packages Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/migration-4.md— a complete 3.x → 4.x migration guide covering the ESM switch, removed helpers/plugins, AI-config replacement (Vercel AI SDK), Joi → Zod,restart: 'browser'removal,withinbecoming an effect,noGlobals: trueas the new default,wait*URL resolution, strict mode, CLI plugin args, workers events, and TypeScript loader changes.hopeThatindocs/effects.mdas the soft-assertion replacement for the removedSoftExpectHelper. Clarifies that it works with any assertion library (built-inI.see*,assert, chai, jest matchers, etc.).require()→import,module.exports→export default,exports.config→export const config. Fixed one dynamic-import-at-top-level regression inpageobjects.md.import 'dotenv/config'inbest.md,import electron from 'electron'inplaywright.md, prose aroundrequire('codeceptjs')updated inhooks.md/internal-api.md.Files
docs/migration-4.mdai,api,basics,bdd,best,commands,configuration,custom-helpers,data,effects,hooks,index,installation,internal-api,pageobjects,parallel,playwright,plugins,puppeteer,reports,secrets,translation,tutorial,webdriverdocs/migration-4.mdintentionally keepsrequire()/module.exportsin its 3.x: before-snippets so users can see what they had.docs/api.md's Joi-migration note and theFor CommonJS Projects (CodeceptJS 3.x)block indocs/configuration.mdare left as CJS for the same reason.Test plan
npm run docsor whichever pipeline) and confirm the new migration guide appears in the sidebar.docs/custom-helpers.md,docs/internal-api.md) by copying it into a freshnpm init-style ESM project and confirming the import resolves.docs/effects.mdrenders thehopeThatexample correctly./effects#hopethat,/locators#aria-locators,/auth,/aitrace,/mcp, etc.) resolve.🤖 Generated with Claude Code