Tags: codeceptjs/CodeceptJS
Tags
fix(Playwright): skip visibleLocator for scrollTo and grab* methods (#… …5712) scrollTo must reach elements that scrolling reveals: scroll-reveal elements hidden with visibility:hidden, empty anchors and zero-height infinite-scroll sentinels. Playwright's visible() drops them, so scrollTo failed with "element not found". Off-screen and opacity:0 elements were never affected. grab* methods read hidden elements on purpose: csrf-token meta tags, hidden inputs, collapsed content. They skip the filter too, which also makes grabTextFrom consistent with the rest of the family. stepOpts({ visibleLocator: true }) still re-enables the filter for a single step. Claude-Session: https://claude.ai/code/session_01Gaie9qVda6jpWHogaHfnHZ Co-authored-by: DavertMik <davert@testomat.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat(Playwright): visibleLocator config option (#5707) Appends Playwright's locator.visible() (1.63+) to locators, so actions match only visible elements. Resolved per step: stepOpts({ visibleLocator }) overrides the helper config, following exact/strictMode/elementIndex. seeElementInDOM, dontSeeElementInDOM and seeNumberOfElements opt out by setting the step option, since they assert DOM presence regardless of visibility. Claude-Session: https://claude.ai/code/session_01D6RydiYkagn6C8Pts2Leou Co-authored-by: DavertMik <davert@testomat.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat: checkOption finds checkables by ARIA role (#5704) * feat: checkOption finds checkables by ARIA role `checkOption('Accept terms')` failed on every headless component library. Radix renders a checkbox as `<button role="checkbox" aria-checked>`, Base UI as `<span role="checkbox">`; neither is an `<input>`, and all three strategies in `Locator.checkable` hard-code `.//input[@type='checkbox' or @type='radio']`. Playwright's `findCheckable` now runs a `getByRole('checkbox'|'radio'|'switch', { name })` pass — exact across the three roles first, then substring — mirroring what `findClickable` already does for `button`/`link`. Native inputs expose those roles too, so the pass is a superset of the XPath strategies it precedes. `seeCheckboxIsChecked` / `dontSeeCheckboxIsChecked` route through the same lookup and are fixed by it. WebDriver and Puppeteer already had an ARIA fallback but ran it *after* the label XPath, which is too late. Base UI renders a hidden mirror `<input>`, moves the author's id onto it and points `<label for>` at it, so the label XPath succeeds and resolves a 1x1 `aria-hidden` input at x:-1,y:-1 — the click is then intercepted or reported outside the viewport. `aria-hidden` keeps that input out of the accessibility tree, so the ARIA lookup lands on the visible control instead. Both fallbacks now run before the label XPath. Adds Radix and Base UI fixtures under /form/checkable and a shared spec block asserting `aria-checked` flips on the visible element. Radix checkables stay skipped on WebDriver: webdriverio's `aria/` selector resolves `<label for>` to input/textarea only, and a Radix `<button role=checkbox>` has no accessible name of its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcwzSXPnfaig8nBZD2Vxfi * fix: role-restrict the hoisted ARIA checkable lookup Moving the accessible-name lookup above the label XPath fixed Base UI but widened the net: `aria/…` and `::-p-aria(…)` match on name alone, so a heading sharing a checkbox label's text now won on document order where `byText` previously reached the input. Measured on the new collision fixture, both returned `[H2, INPUT#terms-box]`. Puppeteer loops the three checkable roles as `::-p-aria([name][role])`, following the buildRoleSelector convention already in the file. `::-p-aria` matches names exactly and case-sensitively, so one pass per role is enough; a name that cannot be parsed falls through to the XPath as before. WebDriver has no attribute filter on `aria/`, so its results are post-filtered to `input[type=checkbox|radio]` and `[role=checkbox|radio|switch]` in a single `browser.execute` round trip regardless of match count, using the `execute(fn, ...elements)` form already used in the file. Both now resolve `[INPUT#terms-box]`, matching Playwright's role-scoped pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcwzSXPnfaig8nBZD2Vxfi --------- Co-authored-by: DavertMik <davert@testomat.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(junit): report suite hook failures via hook.failed event (#5657) * fix(junit): report suite hook failures via hook.failed event (#5645) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test): vendor CodeMirror 6 bundle so richtext tests don't depend on esm.sh The CodeMirror 6 rich-text fixture imported codemirror@6.0.1 from esm.sh, which fans out to the entire @codemirror/* + @lezer/* module graph over many serial requests. In CI this reliably exceeded the 30s waitForFunction timeout, so window.__editorReady never became true and all four CodeMirror 6 fillField tests timed out across Playwright, Puppeteer and WebDriver. Pre-existing on 4.x and unrelated to the junit change on this branch. Vendor the self-contained esm.sh bundle locally and import it same-origin, making the test network-independent and deterministic. Exclude the vendored blob from eslint and prettier. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: DavertMik <davert@testomat.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
fix(typescript): unique temp file names to fix run-multiple race (#5642… …) (#5643) Transpiled TypeScript files were written to a fixed "<source>.temp.mjs" path next to the source. Under run-multiple, every forked worker transpiles the same files to the same temp paths and cleans them up independently, so one worker's cleanup deletes files the others still need to import — surfacing as "Cannot find module *.temp.mjs". Include process.pid plus a random suffix in the temp file name so each worker writes (and removes) its own files. The names still end in ".temp.mjs", so stack-trace remapping and fixErrorStack keep working. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
fix(core): load Mocha test files as ES Modules so internal-API import…
…s resolve to the live instance
Test files were loaded with synchronous require(), which under tsx/cjs
created a second CommonJS copy of lib/* modules. A test's
`import { config } from "codeceptjs"` then resolved to a disconnected copy
whose module-level singletons were never populated (#5636).
Load test files through `await import()` instead — the same way the
container already loads helpers — so the whole run shares one ES module
graph and plain imports are honest. New lib/mocha/loadTests.js mirrors
Mocha's loadFiles (lazyLoadFiles + per-file pre-require/require/post-require)
to preserve teardown hooks, the gherkin .feature path, and the
dup/missing-Feature validation.
All synchronous mocha.loadFiles() sites converted: codecept.run(), rerun,
workers (parent grouping + worker threads), dry-run, and check.
TypeScript: tsx/cjs is a require hook and can no longer transpile test
files loaded via import(). requireModules() auto-maps tsx/cjs -> tsx/esm
with a deprecation notice; tsx/esm needs "type": "module" in package.json
(init now writes it, and an ERR_REQUIRE_CYCLE_MODULE guard points users to it).
BREAKING CHANGE: the programmatic Workers grouping API
(createGroupsOfTests, createGroupsOfSuites, addTestFiles, splitTestsByGroups)
is now async. TypeScript projects must set "type": "module" in package.json.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(deps): don't auto-install detox & react-native (#5620) (#5621) @codeceptjs/detox-helper was listed under optionalDependencies, which npm/pnpm install by default. It hard-depends on detox and react-native, so every codeceptjs install pulled in those heavy packages (and the dtrace-provider build script) even though core never requires the Detox helper — it is a user-configured external helper. Move it to devDependencies (still needed for in-repo helper docs generation). Users who need the Detox helper install it separately. Co-authored-by: DavertMik <davert@testomat.io> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
PreviousNext

