testeiya 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +312 -27
- package/dist/prompt/index.js +6 -2
- package/dist/prompt/index.js.map +1 -1
- package/dist/prompt/print.js +8 -0
- package/dist/prompt/print.js.map +1 -1
- package/dist/prompt/system-prompt.js +14 -4
- package/dist/prompt/system-prompt.js.map +1 -1
- package/dist/prompt/testomatio.js +3 -3
- package/dist/prompt/tools.js +15 -7
- package/dist/prompt/tools.js.map +1 -1
- package/dist/src/args.js +147 -47
- package/dist/src/args.js.map +1 -1
- package/dist/src/cli.js +50 -14
- package/dist/src/cli.js.map +1 -1
- package/dist/src/doctor.js +186 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/env.js +29 -5
- package/dist/src/env.js.map +1 -1
- package/dist/src/mcp.js +3 -3
- package/dist/src/mcp.js.map +1 -1
- package/dist/src/model.js +15 -10
- package/dist/src/model.js.map +1 -1
- package/dist/src/models.js +38 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/output.js +185 -0
- package/dist/src/output.js.map +1 -0
- package/dist/src/run.js +116 -24
- package/dist/src/run.js.map +1 -1
- package/dist/src/session.js +38 -23
- package/dist/src/session.js.map +1 -1
- package/dist/src/sessions.js +61 -0
- package/dist/src/sessions.js.map +1 -0
- package/package.json +7 -3
- package/prompt/index.ts +11 -2
- package/prompt/print.ts +9 -0
- package/prompt/system-prompt.ts +18 -4
- package/prompt/testomatio.ts +3 -3
- package/prompt/tools.ts +15 -7
- package/skills/codeceptjs/ci-fix-tests/SKILL.md +119 -0
- package/skills/codeceptjs/codeceptjs-auth/SKILL.md +141 -0
- package/skills/codeceptjs/codeceptjs-exploration/SKILL.md +100 -0
- package/skills/codeceptjs/codeceptjs-fundamentals/SKILL.md +196 -0
- package/skills/codeceptjs/codeceptjs-run-analysis/SKILL.md +83 -0
- package/skills/codeceptjs/debugging-codeceptjs-tests/SKILL.md +126 -0
- package/skills/codeceptjs/migrate-codeceptjs-4/SKILL.md +109 -0
- package/skills/codeceptjs/migrate-cypress-to-codeceptjs/SKILL.md +295 -0
- package/skills/codeceptjs/migrate-protractor-to-codeceptjs/SKILL.md +339 -0
- package/skills/codeceptjs/migrate-selenium-java-to-codeceptjs/SKILL.md +459 -0
- package/skills/codeceptjs/migrate-testcafe-to-codeceptjs/SKILL.md +338 -0
- package/skills/codeceptjs/refactoring-codeceptjs-tests/SKILL.md +78 -0
- package/skills/codeceptjs/writing-codeceptjs-tests/SKILL.md +102 -0
- package/skills/playwright/playwright-best-practices/SKILL.md +303 -0
- package/skills/playwright/playwright-best-practices/advanced/authentication-flows.md +360 -0
- package/skills/playwright/playwright-best-practices/advanced/authentication.md +871 -0
- package/skills/playwright/playwright-best-practices/advanced/clock-mocking.md +364 -0
- package/skills/playwright/playwright-best-practices/advanced/mobile-testing.md +409 -0
- package/skills/playwright/playwright-best-practices/advanced/multi-context.md +288 -0
- package/skills/playwright/playwright-best-practices/advanced/multi-user.md +393 -0
- package/skills/playwright/playwright-best-practices/advanced/network-advanced.md +452 -0
- package/skills/playwright/playwright-best-practices/advanced/third-party.md +464 -0
- package/skills/playwright/playwright-best-practices/architecture/pom-vs-fixtures.md +363 -0
- package/skills/playwright/playwright-best-practices/architecture/test-architecture.md +369 -0
- package/skills/playwright/playwright-best-practices/architecture/when-to-mock.md +383 -0
- package/skills/playwright/playwright-best-practices/browser-apis/browser-apis.md +391 -0
- package/skills/playwright/playwright-best-practices/browser-apis/iframes.md +403 -0
- package/skills/playwright/playwright-best-practices/browser-apis/service-workers.md +504 -0
- package/skills/playwright/playwright-best-practices/browser-apis/websockets.md +403 -0
- package/skills/playwright/playwright-best-practices/core/annotations.md +424 -0
- package/skills/playwright/playwright-best-practices/core/assertions-waiting.md +361 -0
- package/skills/playwright/playwright-best-practices/core/configuration.md +452 -0
- package/skills/playwright/playwright-best-practices/core/fixtures-hooks.md +417 -0
- package/skills/playwright/playwright-best-practices/core/global-setup.md +434 -0
- package/skills/playwright/playwright-best-practices/core/locators.md +242 -0
- package/skills/playwright/playwright-best-practices/core/page-object-model.md +315 -0
- package/skills/playwright/playwright-best-practices/core/projects-dependencies.md +453 -0
- package/skills/playwright/playwright-best-practices/core/test-data.md +492 -0
- package/skills/playwright/playwright-best-practices/core/test-suite-structure.md +361 -0
- package/skills/playwright/playwright-best-practices/core/test-tags.md +298 -0
- package/skills/playwright/playwright-best-practices/debugging/console-errors.md +420 -0
- package/skills/playwright/playwright-best-practices/debugging/debugging.md +504 -0
- package/skills/playwright/playwright-best-practices/debugging/error-testing.md +360 -0
- package/skills/playwright/playwright-best-practices/debugging/flaky-tests.md +496 -0
- package/skills/playwright/playwright-best-practices/frameworks/angular.md +530 -0
- package/skills/playwright/playwright-best-practices/frameworks/nextjs.md +469 -0
- package/skills/playwright/playwright-best-practices/frameworks/react.md +531 -0
- package/skills/playwright/playwright-best-practices/frameworks/vue.md +574 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +468 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/docker.md +283 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/github-actions.md +546 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/gitlab.md +397 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/other-providers.md +521 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +371 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/performance.md +453 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/reporting.md +424 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +497 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/accessibility.md +359 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/api-testing.md +719 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/browser-extensions.md +506 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/canvas-webgl.md +493 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/component-testing.md +500 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/drag-drop.md +576 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/electron.md +509 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/file-operations.md +377 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/file-upload-download.md +562 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/forms-validation.md +561 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/graphql-testing.md +331 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/i18n.md +508 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/performance-testing.md +476 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/security-testing.md +430 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/visual-regression.md +634 -0
- package/skills/playwright/playwright-cli/SKILL.md +420 -0
- package/skills/playwright/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright/playwright-cli/references/video-recording.md +143 -0
- package/skills/skills.lock.json +39 -36
- package/skills/testomatio/explorbot/explorbot-fundamentals/SKILL.md +76 -0
- package/skills/testomatio/explorbot/explorbot-fundamentals/references/no-install.md +36 -0
- package/skills/testomatio/explorbot/explorbot-plan/SKILL.md +108 -0
- package/skills/testomatio/explorbot/explorbot-setup/SKILL.md +86 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/SKILL.md +111 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/references/answer-shapes.md +116 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/references/examples.md +157 -0
- package/skills/testomatio/qa-process/qa-lead-strategy-advisor/SKILL.md +91 -0
- package/skills/testomatio/qa-process/qa-lead-strategy-advisor/references/output-format.md +71 -0
- package/skills/testomatio/qa-process/testing-workflow/SKILL.md +227 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/CLAUDE.md +56 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/SKILL.md +242 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/CODECEPTJS_BEST_PRACTICES.md +182 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/FINAL_SUMMARY_TEMPLATE.md +22 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/PLAYWRIGHT_BEST_PRACTICES.md +90 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/POM_BEST_PRACTICES.md +53 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/TEST_DATA_MANAGEMENT.md +52 -0
- package/skills/testomatio/test-automation/debug-fix-failed-flaky-autotests/SKILL.md +107 -0
- package/skills/testomatio/test-automation/debug-fix-failed-flaky-autotests/references/DEBUGGING_QUICK_REFERENCE.md +113 -0
- package/skills/testomatio/test-automation/qa-automation-test-consolidation/SKILL.md +29 -0
- package/skills/testomatio/test-automation/qa-data-seeder/SKILL.md +83 -0
- package/skills/testomatio/test-automation/run-tests-with-testomatio-reporter/SKILL.md +153 -0
- package/skills/testomatio/test-automation/setup-change-aware-pr-testing/SKILL.md +190 -0
- package/skills/testomatio/test-automation/setup-ci-automation/SKILL.md +76 -0
- package/skills/testomatio/test-automation/testomat-allure-adapter/SKILL.md +289 -0
- package/skills/testomatio/test-management/detect-duplicate-test-cases/SKILL.md +86 -0
- package/skills/testomatio/test-management/detect-duplicate-test-cases/references/DUPLICATE_INSTRUCTIONS.md +54 -0
- package/skills/testomatio/test-management/improve-test-cases/SKILL.md +114 -0
- package/skills/testomatio/test-management/improve-test-cases/references/TESTOMAT_MARKDOWN_EXAMPLE.md +66 -0
- package/skills/testomatio/test-management/pull-request-diff-analyzer/SKILL.md +141 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/SKILL.md +354 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_ARTIFACTS.md +82 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_HTML_REPORT.md +37 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_REPORTERS_CONFIG.md +118 -0
- package/skills/testomatio/test-management/qa-pr-requirements-analyzer/SKILL.md +149 -0
- package/skills/testomatio/test-management/qa-pr-requirements-analyzer/references/summary-example.md +54 -0
- package/skills/testomatio/test-management/qa-requirement-reviewer/SKILL.md +126 -0
- package/skills/testomatio/test-management/qa-requirement-reviewer/references/requirements_reviewer_examples.md +128 -0
- package/skills/testomatio/test-management/qa-split-testing-levels-pyramid/SKILL.md +55 -0
- package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/SKILL.md +220 -0
- package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/references/qa-sprint-report.md +126 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/SKILL.md +174 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/references/COVERAGE_FILE_FORMAT.md +138 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/references/E2E_FRAMEWORKS.md +65 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/scripts/check-coverage.mjs +40 -0
- package/skills/testomatio/test-management/qa-thinking/SKILL.md +36 -0
- package/skills/testomatio/test-management/qa-write-test-cases/SKILL.md +267 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/test-case-format.md +387 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/testomat-tms-guide.md +72 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/writing-rule.md +159 -0
- package/skills/testomatio/test-management/scan-automation-project/SKILL.md +152 -0
- package/skills/testomatio/test-management/sync-test-cases-with-tms/SKILL.md +107 -0
- package/skills/testomatio/test-management/sync-test-cases-with-tms/references/TESTOMATIO_CLI.md +140 -0
- package/skills/testomatio/test-management/testomatio-mcp/SKILL.md +195 -0
- package/skills/testomatio/test-management/testomatio-mcp/references/MCP_SETUP.md +177 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codeceptjs-auth
|
|
3
|
+
description: >
|
|
4
|
+
Use when a CodeceptJS test needs login, user roles, or session reuse — or
|
|
5
|
+
when another CodeceptJS skill identifies authorization is required. Also on
|
|
6
|
+
auth-related test failures. Trigger on login, sign-in, sign-up,
|
|
7
|
+
authentication, sessions, "logged in", admin/editor/user roles.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# CodeceptJS Auth Plugin
|
|
11
|
+
|
|
12
|
+
The `auth` plugin logs each user in once, captures cookies (or localStorage/token via overrides), and restores the session for subsequent tests. Stale sessions trigger a fresh login automatically.
|
|
13
|
+
|
|
14
|
+
If the project already has `auth` configured (fundamentals' discovery output), **reuse** its existing inject name and user keys — don't reconfigure.
|
|
15
|
+
|
|
16
|
+
## Decide first — ask the user
|
|
17
|
+
|
|
18
|
+
Four answers shape the plugin. Don't guess any.
|
|
19
|
+
|
|
20
|
+
1. **Is a session needed at all?** Public flows (landing, signup) → skip the plugin.
|
|
21
|
+
2. **One user or many?** Default one; add more only when actually exercised.
|
|
22
|
+
3. **If many — what splits them?** Role, workspace/tenant, plan tier, sign-in provider, per-test fixture — real systems vary. Ask; use the answer to name `users.<key>` entries.
|
|
23
|
+
4. **What's the auth type?**
|
|
24
|
+
- **Form** — default; canonical shape below
|
|
25
|
+
- **OAuth / SSO** — click provider button, drive the IdP page (often separate origin)
|
|
26
|
+
- **Magic link / passwordless** — UI flow rarely worth automating; prefer an API mint or reading the link from a test mailbox
|
|
27
|
+
- **API token** — skip the form; write the token into `localStorage` via `executeScript`, or `I.setCookie(...)`
|
|
28
|
+
- **2FA / OTP** — async `login`; fetch the code from a test mailbox / backdoor before submitting
|
|
29
|
+
|
|
30
|
+
## Rules
|
|
31
|
+
|
|
32
|
+
1. **Login flow never lives in the conf.** Put it in `steps_file.js` (if included) or a page object; conf only references it: `login: (I) => I.login()`.
|
|
33
|
+
2. **Credentials from env only** — `.env` loaded via `process.loadEnvFile()` (no dotenv dependency). Passwords wrapped with `secret(...)`. No literals anywhere — conf, steps file, test, git history.
|
|
34
|
+
3. **`.env` is gitignored; `.env.example` is committed** with names, no values. Gitignore `output/*_session.json` too.
|
|
35
|
+
|
|
36
|
+
## Canonical shape
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// codecept.conf.js — first line of the file
|
|
40
|
+
process.loadEnvFile()
|
|
41
|
+
|
|
42
|
+
export const config = {
|
|
43
|
+
include: { I: './steps_file.js' },
|
|
44
|
+
plugins: {
|
|
45
|
+
auth: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
saveToFile: true,
|
|
48
|
+
users: {
|
|
49
|
+
admin: {
|
|
50
|
+
login: (I) => I.login(),
|
|
51
|
+
check: (I) => I.see('Welcome, User', '.navbar'),
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
// steps_file.js
|
|
61
|
+
import { secret } from 'codeceptjs'
|
|
62
|
+
const { I } = inject()
|
|
63
|
+
|
|
64
|
+
export default function () {
|
|
65
|
+
return actor({
|
|
66
|
+
login() {
|
|
67
|
+
I.amOnPage('/login')
|
|
68
|
+
I.fillField('Email', process.env.ADMIN_EMAIL)
|
|
69
|
+
I.fillField('Password', secret(process.env.ADMIN_PASSWORD))
|
|
70
|
+
I.click('Sign in')
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
# .env (gitignored) # .env.example (committed)
|
|
78
|
+
USER_EMAIL=... USER_EMAIL=
|
|
79
|
+
USER_PASSWORD=<secret> USER_PASSWORD=
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Pre-flight (before writing config)
|
|
83
|
+
|
|
84
|
+
1. **Read the real login page** — MCP `run_code` to `/login`, inspect the ARIA snapshot (`codeceptjs-exploration`). Field labels / `name` / `id` / submit control from the actual page, not guesses. Unclear authorization mechanism → ask the user.
|
|
85
|
+
2. **Pick a role-specific post-login marker** — something rendered only for *this* user (navbar username, `data-user-role`).
|
|
86
|
+
3. **Confirm session storage** — cookies (default) for server-rendered apps; localStorage/sessionStorage for SPAs. Verify after a manual login with `I.executeScript(() => Object.keys(localStorage))`. Cookie fetch/restore silently no-op against token storage.
|
|
87
|
+
|
|
88
|
+
## Verify
|
|
89
|
+
|
|
90
|
+
Run a one-Scenario file that calls `login(<role>)` then asserts on the post-login marker:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx codeceptjs run --grep '<scenario>' --debug # real run, not dry — dry-run doesn't init plugins
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Enable `saveToFile: true` only after this round-trip succeeds — a bad saved session masks a broken `login`.
|
|
97
|
+
|
|
98
|
+
Then wire into hooks/tests: `Before(({ login }) => login())` for suite-wide, or per-test as needed.
|
|
99
|
+
|
|
100
|
+
## Multi-role shape
|
|
101
|
+
|
|
102
|
+
Only after question 3 is answered. Keys named after whatever splits users *in this system*; one matching actor method per key:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
users: {
|
|
106
|
+
admin: { login: (I) => I.loginAsAdmin() },
|
|
107
|
+
workspaceB: { login: (I) => I.loginToWorkspaceB() },
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Don't parameterise into a single `login(key)` — the plugin keys sessions by name, explicit methods read better. Switch mid-Scenario: `session('<key>')` opens a parallel browser context (fundamentals § Writing tests).
|
|
112
|
+
|
|
113
|
+
## Token / localStorage auth
|
|
114
|
+
|
|
115
|
+
Override `fetch` / `restore` when sessions live outside cookies:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
admin: {
|
|
119
|
+
login: (I) => I.loginAsAdmin(),
|
|
120
|
+
check: (I) => I.see('Admin', '.navbar'),
|
|
121
|
+
fetch: (I) => I.executeScript(() => localStorage.getItem('session_id')),
|
|
122
|
+
restore: (I, session) => {
|
|
123
|
+
I.amOnPage('/')
|
|
124
|
+
I.executeScript((s) => localStorage.setItem('session_id', s), session)
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`check(I, session)` receives whatever `fetch` returned — throw inside `check` to force fresh login (e.g. `/me` endpoint shows wrong user).
|
|
130
|
+
|
|
131
|
+
## Pitfalls
|
|
132
|
+
|
|
133
|
+
- Credentials inlined in conf/test — always env-driven + `secret()`.
|
|
134
|
+
- Forgetting to gitignore `.env` and `output/*_session.json` — both leak credentials.
|
|
135
|
+
|
|
136
|
+
## Related skills
|
|
137
|
+
|
|
138
|
+
- `codeceptjs-fundamentals` — secrets rule, sessions, config mutation trap
|
|
139
|
+
- `codeceptjs-exploration` — reading the live login page
|
|
140
|
+
- `writing-codeceptjs-tests` / `refactoring-codeceptjs-tests` — invoke this skill when auth is identified
|
|
141
|
+
- `debugging-codeceptjs-tests` — auth-related failure patterns
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codeceptjs-exploration
|
|
3
|
+
description: >
|
|
4
|
+
Use when an agent needs to learn what's on a page in CodeceptJS — read the
|
|
5
|
+
ARIA tree, inspect candidate elements, pick or disambiguate a stable locator.
|
|
6
|
+
Drives the live browser via MCP `run_code` / `snapshot`. Invoked by
|
|
7
|
+
writing-codeceptjs-tests, debugging-codeceptjs-tests, and
|
|
8
|
+
refactoring-codeceptjs-tests whenever page inspection is needed.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CodeceptJS Page Exploration
|
|
12
|
+
|
|
13
|
+
Authoring a test, debugging a failure, and refactoring a stale locator share one task: open a page, find the right element, pick a stable locator. This is that playbook.
|
|
14
|
+
|
|
15
|
+
## Tools
|
|
16
|
+
|
|
17
|
+
- **`run_code`** — runs CodeceptJS code, returns produced values, captures `console.*`, saves a final-state snapshot. For *do something and look at the result*.
|
|
18
|
+
- **`snapshot`** — captures state without acting (URL, cookies, localStorage, HTML, ARIA, screenshot, console). For "what's on the page right now".
|
|
19
|
+
|
|
20
|
+
Artifact sources, in preference order:
|
|
21
|
+
|
|
22
|
+
1. **ARIA snapshot** — structured, no styling noise, easy duplicate/accessibility-name scanning
|
|
23
|
+
2. **Screenshot** — visual confirmation; catches layout breaks ARIA can't show
|
|
24
|
+
3. **HTML** — only when ARIA lacks context (custom widgets without accessible names, attribute-driven behaviour)
|
|
25
|
+
|
|
26
|
+
## Inspect an element
|
|
27
|
+
|
|
28
|
+
`I.grabWebElement(locator)` → one WebElement; `I.grabWebElements(locator)` → array. Same cross-helper API on Playwright / Puppeteer / WebDriver.
|
|
29
|
+
|
|
30
|
+
| You want to … | Method |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Confirm rendered / visible / enabled | `exists()`, `isVisible()`, `isEnabled()` |
|
|
33
|
+
| Read text / value / attribute / property | `getText()`, `getValue()`, `getAttribute(n)`, `getProperty(n)` |
|
|
34
|
+
| Position on page | `getBoundingBox()` — flags offscreen / zero-sized |
|
|
35
|
+
| Rendered markup | `toOuterHTML()`, `toSimplifiedHTML(300)` (truncated, MCP-friendly) |
|
|
36
|
+
| Stable selector for a fix | `toAbsoluteXPath()` |
|
|
37
|
+
| Inside an iframe | `inIframe(async (body) => { ... })` |
|
|
38
|
+
| Drill into children | `$(loc)`, `$$(loc)` |
|
|
39
|
+
| Browser-side function | `evaluate(fn, ...args)` |
|
|
40
|
+
|
|
41
|
+
## Discover candidates when the obvious locator misses
|
|
42
|
+
|
|
43
|
+
When `Edit` matches nothing, the control may say "Change", carry `aria-label="Edit user"`, or live in `.btn-edit`. Cast a wide net with a permissive XPath via `I.grabWebElements`, then disambiguate.
|
|
44
|
+
|
|
45
|
+
OR together in the XPath:
|
|
46
|
+
|
|
47
|
+
- visible text — `text()` (or `.` for descendants)
|
|
48
|
+
- attributes — `@class`, `@aria-label`, `@title`, `@data-action`, `@id`
|
|
49
|
+
- **synonyms** — edit/change/modify; delete/remove/trash; submit/send/save
|
|
50
|
+
|
|
51
|
+
Case-insensitive via `translate(...)`:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
//*[contains(translate(., 'EDIT', 'edit'), 'edit')
|
|
55
|
+
or contains(translate(@class, 'EDIT', 'edit'), 'edit')
|
|
56
|
+
or contains(translate(@aria-label, 'EDIT', 'edit'), 'edit')
|
|
57
|
+
or contains(translate(., 'CHANGE', 'change'), 'change')]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then iterate `toSimplifiedHTML(150)` over the results, pick the right candidate, commit a stable locator from its discriminating attribute or text.
|
|
61
|
+
|
|
62
|
+
## Pick a stable locator
|
|
63
|
+
|
|
64
|
+
Two decisions in order: **which region scopes the lookup** (context), **what identifies the element inside it**. Region first keeps the identifier short and semantic — the discriminator found during disambiguation belongs in the context argument:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
I.click('Edit user', '.user-row') // ✅ region + what the user sees
|
|
68
|
+
I.click('#user-row-42 button.edit') // ❌ same element, brittle, unreadable
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Stable regions: landmarks (`nav`, `main`, `{ role: 'dialog' }`), app-shell containers (`.sidebar`, `.toolbar`, `.modal`), rows/cards identified by data via `locate(...)`. Identifier priority (full rationale: `codeceptjs-fundamentals` § Locators):
|
|
72
|
+
|
|
73
|
+
1. Visible label / accessible name — plain string already matches `aria-label`; don't expand to `{ css: '[aria-label="..."]' }`
|
|
74
|
+
2. ARIA role when ambiguous within context or role is part of the check
|
|
75
|
+
3. `$name` via `customLocator` when team test attributes exist
|
|
76
|
+
4. Composed CSS, still scoped: `I.click('button.edit', '#user-row-42')`
|
|
77
|
+
5. `toAbsoluteXPath()` — last resort; flag the team to add a `data-testid`
|
|
78
|
+
|
|
79
|
+
**Never commit an unverified locator** — confirm via `run_code` (`I.seeElement(loc, context)` or `grabWebElement(loc)`) that it matches exactly one element.
|
|
80
|
+
|
|
81
|
+
## Common patterns
|
|
82
|
+
|
|
83
|
+
- Strict mode 2+ matches → `grabWebElements('Save')` + `toSimplifiedHTML(200)` each, find discriminator, pass as context: `I.click('Save', '.modal')`
|
|
84
|
+
- Button rendered but doesn't act → `grabWebElement('Submit')` + `isEnabled()` + `getBoundingBox()` — disabled? offscreen? zero-sized?
|
|
85
|
+
- Wrong row in a list → `grabWebElements('.user-row')`, `getText()` per row to identify, `getAttribute('data-id')` for stable hook
|
|
86
|
+
- Inside iframe → `(await I.grabWebElement('iframe.editor')).inIframe(async (body) => body.$('button'))`
|
|
87
|
+
|
|
88
|
+
## Things to avoid
|
|
89
|
+
|
|
90
|
+
- Choosing a locator without seeing candidates first.
|
|
91
|
+
- Committing `toAbsoluteXPath()` when a semantic locator is available.
|
|
92
|
+
- Committing unscoped locators where a context keeps them short.
|
|
93
|
+
- Ignoring the screenshot — "exists in HTML" ≠ "user can see it".
|
|
94
|
+
- `usePlaywrightTo` / `useWebDriverTo` when WebElement methods cover it.
|
|
95
|
+
|
|
96
|
+
## Related skills
|
|
97
|
+
|
|
98
|
+
- `codeceptjs-fundamentals` — locator priority, await rule
|
|
99
|
+
- `writing-codeceptjs-tests` — invokes this during Mode B exploration
|
|
100
|
+
- `debugging-codeceptjs-tests` — invokes this for live inspection; offline variant via `codeceptq`
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codeceptjs-fundamentals
|
|
3
|
+
description: >
|
|
4
|
+
Run first when working with any CodeceptJS 4 project — before writing,
|
|
5
|
+
debugging, refactoring, or migrating tests. Teaches the framework's
|
|
6
|
+
non-obvious rules and runs four-step discovery (`check` → read config →
|
|
7
|
+
`list` → `dry-run`) reporting which helpers, plugins, page objects, custom
|
|
8
|
+
actions, and tests are active. Other CodeceptJS skills depend on this output.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CodeceptJS Fundamentals
|
|
12
|
+
|
|
13
|
+
Two jobs, in order: learn the rules below, then discover what *this* project has configured.
|
|
14
|
+
|
|
15
|
+
## Gate
|
|
16
|
+
|
|
17
|
+
- CodeceptJS 4 is **ESM/TypeScript only**; tests, configs, page objects, helpers use `import`/`export`.
|
|
18
|
+
- No `"type": "module"` in package.json → add it before anything else.
|
|
19
|
+
- TypeScript: config `codecept.conf.ts`, TS loader entry in `require: [...]`.
|
|
20
|
+
- Project on 3.x or CommonJS (`require()`, removed plugins like `autoLogin`, helper `Nightmare`) → stop, recommend `migrate-codeceptjs-4`. Don't patch files piecemeal — migration is whole-project.
|
|
21
|
+
|
|
22
|
+
## Main rule
|
|
23
|
+
|
|
24
|
+
- Tests are written from the user's perspective: a linear scenario of actions, readable as prose.
|
|
25
|
+
- Good: `I.click('Login')`, `I.fillField('Email', ...)`, `I.see('Welcome')`
|
|
26
|
+
- **Tests are declarative, helpers imperative — recommended layering:**
|
|
27
|
+
- Scenario shows *what* the user does via `I.*`; implementation details live below
|
|
28
|
+
- Low-level access (`this.helpers['Playwright'].page`, fetch, filesystem) works fine inside a Scenario, but it's recommended to push it into a helper and expose one `I.*` action instead
|
|
29
|
+
- Keep tests short: repeated sequences → actor method, page object, or step object.
|
|
30
|
+
- Prefer semantic locators over selectors so tests survive markup churn.
|
|
31
|
+
|
|
32
|
+
## Where things go (recommended placement)
|
|
33
|
+
|
|
34
|
+
- Site-wide actions (`login`, dropdowns, rich text editors) → **actor file** (custom steps)
|
|
35
|
+
- Page/screen actions + locators → **page object**; SPA screen = one page object
|
|
36
|
+
- Site-wide widgets (nav, modals, datepickers) → **page fragments / component objects**
|
|
37
|
+
- Low-level driver access (DB connections, email, filesystem, complex mouse) → **helper**
|
|
38
|
+
- Data creation/cleanup via API → **data objects** (REST/GraphQL helper + `_after()` cleanup), or `ApiDataFactory` (`I.have(...)`)
|
|
39
|
+
- Don't overengineer: no page object until an abstraction is reused across tests.
|
|
40
|
+
|
|
41
|
+
## Shortcuts
|
|
42
|
+
|
|
43
|
+
- Login needed → `autoLogin` plugin or actor method, not inline steps per test
|
|
44
|
+
- Test data → create via API before the test, not through the UI
|
|
45
|
+
- Long test → break into several; long tests are fragile and hard to follow
|
|
46
|
+
- Optional UI element / conditional flow → `await tryTo(...)` instead of `if (await I.grab...)` — keeps scenarios linear
|
|
47
|
+
|
|
48
|
+
## Architecture
|
|
49
|
+
|
|
50
|
+
- **Config**: `codecept.conf.{js,ts,mjs,cjs}` at repo root; multiple files selected via `--config <file>`.
|
|
51
|
+
- **Helpers execute; `I` delegates.** Every `I.<method>` is routed to whichever active helper implements it (Playwright, WebDriver, Puppeteer, Appium share one API surface). Active helpers = keys under `helpers`. Tests call the actor, never the engine — backends stay swappable.
|
|
52
|
+
- **DI container** — why it exists:
|
|
53
|
+
- Everything shared (actor, helpers, page objects, support objects) registers under one container; `include` maps names → modules
|
|
54
|
+
- Classes are auto-instantiated by the container — no `new`, no manual wiring
|
|
55
|
+
- **`inject()` returns lazy proxies**: destructuring at module top resolves at call time, so circular page-object references work where plain `import` would give `undefined`
|
|
56
|
+
- Access: destructure in Scenario signature (`Scenario('...', ({ I, loginPage }) => ...)`) or `const { I } = inject()` once per file
|
|
57
|
+
- **Custom helpers** extend `Helper`, register under `helpers`, add new `I.*` methods.
|
|
58
|
+
- **`I` does not exist inside a helper.** Compose via `this.helpers['<HelperName>']` (e.g. `this.helpers['Playwright'].page`, `this.helpers['REST'].sendGetRequest(...)`).
|
|
59
|
+
- **Plugins** are event listeners on lifecycle events (`suite.*`, `test.*`, `step.*`, `hook.*`, `multiple.*`). Full list: `node_modules/codeceptjs/lib/event.js`. Register under `plugins` with `enabled: true`.
|
|
60
|
+
|
|
61
|
+
## Config mutation trap
|
|
62
|
+
|
|
63
|
+
- `@codeceptjs/configure` mutates resolved config at load time (`setHeadlessWhen`, `setBrowser`, ...). Static values can lie — grep for its import before trusting `show:` / `browser:` fields.
|
|
64
|
+
- `setCommonPlugins()`: **enables** `retryFailedStep` + `screenshot`; **registers** (off until `-p`) `pause`, `browser`, `aiTrace`, `heal`.
|
|
65
|
+
|
|
66
|
+
## Plugins worth knowing
|
|
67
|
+
|
|
68
|
+
- `retryFailedStep` — retries transient step failures
|
|
69
|
+
- `screenshot` — screenshots on failure; `slides: true` → `output/records.html` slideshow
|
|
70
|
+
- `pageInfo` — dumps URL/HTML/console on failure
|
|
71
|
+
- `auth` — session reuse for login (see `codeceptjs-auth` skill)
|
|
72
|
+
- `aiTrace` — per-step screenshots/HTML/ARIA/console for AI debugging
|
|
73
|
+
- `pause` — interactive pause
|
|
74
|
+
- `heal` — AI-suggested fixes for broken steps (off in `--debug`)
|
|
75
|
+
- `screencast` — video of the run
|
|
76
|
+
- `customLocator` — maps `$name` prefix to team's test attribute (`data-testid`, `data-qa`)
|
|
77
|
+
- `browser` — CLI-only override of browser helper config (see below)
|
|
78
|
+
|
|
79
|
+
Note: `tryTo`, `retryTo`, `eachElement` are not plugins in 4.x — import them from `codeceptjs/effects`.
|
|
80
|
+
|
|
81
|
+
## Plugins from CLI
|
|
82
|
+
|
|
83
|
+
Any plugin can be enabled/reconfigured per-run with `-p <plugin>`, args chained with `:`:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
npx codeceptjs run -p aiTrace # enable for this run
|
|
87
|
+
npx codeceptjs run -p screenshot:on=step # reconfigure inline
|
|
88
|
+
npx codeceptjs run -p pause:on=file:path=tests/login_test.js;line=43
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- `screenshot`, `pause`, `aiTrace`, `heal` share an `on=` trigger: `fail` (default except aiTrace) | `step` | `test` | `file:path=...;line=N` | `url:pattern=<glob>`
|
|
92
|
+
- `browser` plugin overrides without touching config — CI matrix legs, one-off env variants:
|
|
93
|
+
- `-p browser:hide` / `-p browser:show` / `-p browser:browser=firefox` / `-p browser:windowSize=1280x800`
|
|
94
|
+
- Requires `@codeceptjs/configure`
|
|
95
|
+
|
|
96
|
+
## Effects (`codeceptjs/effects`)
|
|
97
|
+
|
|
98
|
+
Flow-control functions imported from `codeceptjs/effects`. In 4.x these are no longer plugins/globals.
|
|
99
|
+
|
|
100
|
+
- **`tryTo(() => ...)`** — runs steps that may fail without stopping the test; returns `boolean`.
|
|
101
|
+
- **Prefer `tryTo` over `if`:** scenarios should stay linear — instead of branching on a grabbed value to decide whether a UI state exists, attempt the optional steps and branch on the boolean result:
|
|
102
|
+
```js
|
|
103
|
+
const banner = await tryTo(() => { I.see('Cookie banner'); I.click('Accept cookies') })
|
|
104
|
+
if (!banner) I.say('No cookie banner')
|
|
105
|
+
```
|
|
106
|
+
- Auto-retries are disabled inside `tryTo` blocks.
|
|
107
|
+
- **`retryTo(() => ..., maxTries, pollInterval = 200)`** — retries a step block until it succeeds (flaky elements, animations); callback receives the current attempt count.
|
|
108
|
+
- **`hopeThat(() => ...)`** — soft assertions (see Assertions); end with `hopeThat.noErrors()`.
|
|
109
|
+
- **`within(locator | { frame }, fn)`** — scopes resolution to subtree or iframe; can return values (`await`). Prefer the context parameter of individual actions (`I.click('Save', '.toolbar')`) when possible — reserve `within` for genuinely scoped blocks.
|
|
110
|
+
|
|
111
|
+
All effects return Promises — `await` them.
|
|
112
|
+
|
|
113
|
+
## Element-based API (`codeceptjs/els`)
|
|
114
|
+
|
|
115
|
+
Hybrid style: mix `I.*` with direct element access. Import `{ element, eachElement, expectElement, expectAnyElement, expectAllElements } from 'codeceptjs/els'`.
|
|
116
|
+
|
|
117
|
+
- `element(locator, async el => { ... })` — scoped access to one element; chain `el.$(locator)` into children without re-querying
|
|
118
|
+
- `eachElement(locator, async (el, index) => ...)` — iterate collections
|
|
119
|
+
- `expectElement` / `expectAnyElement` / `expectAllElements(locator, fn)` — custom conditions
|
|
120
|
+
- Elements are `WebElement` wrappers — same API on all helpers: `getText()`, `getAttribute()`, `isVisible()`, `isEnabled()`, `getBoundingBox()`, `exists()`, `$$()`
|
|
121
|
+
- Optional purpose string improves debug logs: `element('verify discount applied', '.price', ...)`
|
|
122
|
+
- Use when built-ins don't cover it: collections, layout checks (`getBoundingBox`), per-element loops, chaining ops on one element. Prefer `I.*` for readability otherwise.
|
|
123
|
+
|
|
124
|
+
## Writing tests
|
|
125
|
+
|
|
126
|
+
- Structure: one `Feature(...)` per file, one or more `Scenario(...)` inside. No nested suites, no multiple Features per file.
|
|
127
|
+
- Hooks: `Before`, `After`, `BeforeSuite`, `AfterSuite`, `Fail(...)`.
|
|
128
|
+
- Page object lifecycle hooks: `_before()` (lazy, once per test, on first use), `_after()` (skipped if unused), `_beforeSuite()`, `_afterSuite()`.
|
|
129
|
+
- **`await` required for**: `grab*` methods, imported functions, page-object methods containing async ops (elsewhere: unhandled rejections). Never for plain action steps — the recorder chains them.
|
|
130
|
+
- Secrets: `I.fillField('Password', secret(process.env.PASSWORD))` — masks logs, traces, AI prompts. Import from `codeceptjs`.
|
|
131
|
+
- Sessions: `session(name, fn)` — parallel browser context for multi-user Scenarios (chat, multi-tenant).
|
|
132
|
+
|
|
133
|
+
## Locators
|
|
134
|
+
|
|
135
|
+
- **ARIA locators are strongest** — resilient to CSS refactors, describe what the user sees:
|
|
136
|
+
- `I.click({ role: 'button', name: 'Save' })`
|
|
137
|
+
- Actions accept plain strings (visible text, label, placeholder, `name`, `aria-label`) or objects (`{ css }`, `{ xpath }`, `{ id }`).
|
|
138
|
+
- Plain string already matches `aria-label` — no `'aria-label=...'` prefix needed.
|
|
139
|
+
- **Pass context as last argument** — scoped semantic locator beats long unscoped one:
|
|
140
|
+
- `I.click('Save', '.toolbar')` not `I.click('#toolbar .btn-save')`
|
|
141
|
+
- Avoid style-based class names (`.bg-green`); prefer semantic ones (`.btn-save`).
|
|
142
|
+
- `data-testid`/`data-qa` apps → enable `customLocator`, write `$name`.
|
|
143
|
+
- No semantic name fits → `locate(...)` builder (`.withClass`, `.withText`, `.inside`, `.and`): `locate('.button').withText('Click me')`.
|
|
144
|
+
|
|
145
|
+
## Waiting
|
|
146
|
+
|
|
147
|
+
- Action steps auto-wait for existence + interactability. Add explicit `waitFor*` only when the condition isn't tied to an interaction (modal after network call, spinner hiding).
|
|
148
|
+
- Avoid `I.wait(N)` — last resort.
|
|
149
|
+
|
|
150
|
+
## Assertions
|
|
151
|
+
|
|
152
|
+
Built-in browser assertions come first: `I.see`, `I.seeTextEquals`, `I.seeElement`, `I.seeInField`, `I.seeNumberOfElements`, `I.seeInCurrentUrl` (+ `dontSee*` counterparts). Clear failures, recorder-integrated. `see` matches *visible* text; hidden DOM content needs `seeInSource` / `seeElementInDOM`.
|
|
153
|
+
|
|
154
|
+
For what built-ins don't cover, in order of preference:
|
|
155
|
+
|
|
156
|
+
1. **Reusable custom assertion** in a helper — `I.seeTableIsOrdered('Price', 'desc')`; name positives `see*`, negatives `dontSee*`; use `codeceptjs/assertions` inside, never raw `throw new Error()`
|
|
157
|
+
2. **ExpectHelper** (`@codeceptjs/expect-helper`) — chai matchers on `I`: `I.expectEqual`, `I.expectDeepEqualExcluding`, `I.expectMatchesPattern`, `I.expectJsonSchema`; appears in step log like other steps
|
|
158
|
+
3. **`codeceptjs/assertions`** directly — dependency-free factories: `equals(subject).assert(actual, expected)` / `.negate(...)`; failure messages match `I.see` formatting
|
|
159
|
+
4. **Any library** on grabbed data (`grab*` always needs `await`) — chai/jest/`node:assert`; fails the test but won't show as a step
|
|
160
|
+
|
|
161
|
+
Soft assertions: `hopeThat(() => I.see(...))` from `codeceptjs/effects` — logs each failure and continues; end with `hopeThat.noErrors()` to fail if any were recorded.
|
|
162
|
+
|
|
163
|
+
## Parallel runs
|
|
164
|
+
|
|
165
|
+
- `run-workers <N>` — splits Scenarios across worker threads
|
|
166
|
+
- `run-multiple <profile>` — profiles via `multiple` block in config (browsers, viewports)
|
|
167
|
+
|
|
168
|
+
## Config organization (recommended)
|
|
169
|
+
|
|
170
|
+
- Multiple config files per environment (`codecept.conf.js`, `codecept.ci.conf.js`, ...); share parts via modules in a `config/` dir
|
|
171
|
+
- `.env` files + `dotenv` for secrets/env-specific values
|
|
172
|
+
- Bulk-register page objects/components by spreading exported maps into `include`
|
|
173
|
+
- Pass data from config/bootstrap into tests via `codeceptjs.container.append({ testUser })` — injectable by name
|
|
174
|
+
|
|
175
|
+
## Discover this project
|
|
176
|
+
|
|
177
|
+
In order; skipping steps produces wrong guesses:
|
|
178
|
+
|
|
179
|
+
1. **Verify setup loads**: `npx codeceptjs check -c <config>` — validates everything; output doubles as inventory. Fix failures before continuing.
|
|
180
|
+
2. **Read the active config**: helpers (+ browser/baseURL/viewport/env-driven values), plugins (incl. anything `setCommonPlugins()` injects), AI provider + required env var, env selection mechanism, page objects from `include`, custom helpers.
|
|
181
|
+
3. **List actions**: `npx codeceptjs list -c <config>` (`--docs` adds JSDoc; `--action <name>` for one). The actual `I.*` surface differs from built-ins when custom helpers exist — always check before suggesting a method.
|
|
182
|
+
4. **List tests**: `npx codeceptjs dry-run -c <config>` — `--steps` shows queued actions, `--grep` filters, `--numbers` gives per-test step indices matching MCP `pauseAt`.
|
|
183
|
+
- ⚠ `dry-run --grep` and `run --grep` do **not** select the same set (4.1.0): `run --grep` matches `Feature` + `Scenario`, `dry-run --grep` matches the Scenario title only. `dry-run --grep 'Dialogs'` lists 0 tests where `run --grep 'Dialogs'` executes all 11. Never size a run from a dry-run's grep, and target a whole Feature by file path (`run tests/foo_test.ts`) when the selection must be exact.
|
|
184
|
+
|
|
185
|
+
Gherkin projects: `npx codeceptjs gherkin:steps -c <config>`.
|
|
186
|
+
|
|
187
|
+
Reference docs live under `node_modules/codeceptjs/docs/` — read them instead of guessing APIs.
|
|
188
|
+
|
|
189
|
+
## Report
|
|
190
|
+
|
|
191
|
+
Short prose summary. Must include:
|
|
192
|
+
|
|
193
|
+
- Env-driven values flagged as env-driven (`process.env.BROWSER || 'chromium'`, not just `'chromium'`)
|
|
194
|
+
- Conflicts flagged (static `show: true` vs `setHeadlessWhen(CI)`; `auth` configured but credential env vars missing)
|
|
195
|
+
- No config at root and no `--config` referenced → recommend `npx codeceptjs init .`, stop
|
|
196
|
+
- 3.x/CommonJS detected → recommend `migrate-codeceptjs-4`, stop
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codeceptjs-run-analysis
|
|
3
|
+
description: >
|
|
4
|
+
Use after running CodeceptJS tests with the `aiTrace` plugin enabled and the
|
|
5
|
+
results need review — verify a fix held, investigate a single failure, cluster
|
|
6
|
+
errors across a CI fail-storm, diagnose flakiness across reruns. Invoked by
|
|
7
|
+
other CodeceptJS skills whenever a run has happened. Trigger on "what failed",
|
|
8
|
+
"analyse the run", "cluster these errors", "is it flaky", "did the fix hold".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CodeceptJS Run Analysis
|
|
12
|
+
|
|
13
|
+
After `npx codeceptjs run`, trace artifacts land in `output/`. This skill reads them efficiently — right step, right file, right slice of a giant HTML snapshot — via bash tools rather than re-running through MCP.
|
|
14
|
+
|
|
15
|
+
No single end goal: pick the use case matching the situation. The foundations apply to all of them.
|
|
16
|
+
|
|
17
|
+
## Foundations
|
|
18
|
+
|
|
19
|
+
- **aiTrace must be on.** Everything leans on `output/trace_<TestName>_<hash>/trace.md`. Confirm in the active config (run `codeceptjs-fundamentals` if unknown). Without it there are only screenshots and `pageInfo` dumps — suggest enabling and re-running before deep analysis.
|
|
20
|
+
- `run_step_by_step` is interactive only; `aiTrace` is the sole source of per-step files. Ad-hoc `run_code` / `snapshot` still produce single-shot bundles under `output/trace_run_code_*` / `output/snapshot_*`.
|
|
21
|
+
- **Locate traces**: reruns create new dirs — when unclear, most recent wins (`ls -dt output/trace_*`).
|
|
22
|
+
- **Read trace.md first** — it's the index linking each step to its artifacts.
|
|
23
|
+
- Focus on the failed step; none marked → last step in the trace.
|
|
24
|
+
- Multiple failures marked → the **first** is usually the cause; the rest cascade.
|
|
25
|
+
|
|
26
|
+
### Artifact order for the focus step (`NNNN_<step>`)
|
|
27
|
+
|
|
28
|
+
| Artifact | When |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `NNNN_*_aria.txt` | First read — lean, structured, easy to scan for duplicates |
|
|
31
|
+
| `NNNN_*_screenshot.png` | Visual confirmation — layout, animation, "rendered but wrong" |
|
|
32
|
+
| `NNNN_*_console.json` | JS errors, 4xx/5xx, deprecation warnings explaining vanished elements |
|
|
33
|
+
| `NNNN_*_storage.json` | Cookies + localStorage at this step — first stop when auth suspected |
|
|
34
|
+
| `NNNN_*_page.html` | Last resort, and only via `grep` |
|
|
35
|
+
|
|
36
|
+
### Never read big files whole
|
|
37
|
+
|
|
38
|
+
- HTML snapshots: search with `grep` (text, class, aria-label, `data-*`) — line numbers + context flags keep matches readable.
|
|
39
|
+
- `console.json`: filter with `jq`, don't read every entry.
|
|
40
|
+
- Scanning many files: `grep -l` for filenames only.
|
|
41
|
+
|
|
42
|
+
## Use cases
|
|
43
|
+
|
|
44
|
+
### Verify a fix held
|
|
45
|
+
Locate latest trace → read trace.md → confirm no FAILED markers. Glance at `console.json` for warnings worth fixing while you're there.
|
|
46
|
+
|
|
47
|
+
### Cluster errors across a CI batch
|
|
48
|
+
Extract failing-step lines from every `trace.md`, group by signature (`grep` + `sort` + `uniq -c`), rank by frequency.
|
|
49
|
+
- Same error in many tests = **systemic** (env var, auth, base URL, deploy regression) — fix root cause once, rerun the batch.
|
|
50
|
+
- Different errors per test = local — triage one at a time.
|
|
51
|
+
Start with the most frequent root cause; rerun to see how many tests came back with it.
|
|
52
|
+
|
|
53
|
+
### Diagnose flakiness
|
|
54
|
+
Rerun the same test 5–10 times; compare which step failed in each trace.
|
|
55
|
+
- Different step each run → timing, environment, external service
|
|
56
|
+
- Same step, different state → missing/wrong wait — `diff` the ARIA snapshots of that step between runs
|
|
57
|
+
- `console.json` differs between runs → transient backend/network errors
|
|
58
|
+
- Bounding box differs → layout reflow or late-loading content
|
|
59
|
+
|
|
60
|
+
### Investigate a single failure
|
|
61
|
+
Failed-or-last step → ARIA + screenshot first, console second, HTML last (grep only). Form a hypothesis. Trace not enough / page needs live poking → hand off to `debugging-codeceptjs-tests`.
|
|
62
|
+
|
|
63
|
+
## After analysis
|
|
64
|
+
|
|
65
|
+
- Systemic cause → fix root once (env, auth, deploy), not per test
|
|
66
|
+
- Locator drift → `codeceptjs-exploration`
|
|
67
|
+
- Timing/wait issue → Waiting guidance from fundamentals/writing skills; replace `I.wait(N)` with specific `waitFor*`
|
|
68
|
+
- Resists static analysis → `debugging-codeceptjs-tests` (live MCP loop)
|
|
69
|
+
- Clean pass → done, but glance at `console.json` anyway
|
|
70
|
+
|
|
71
|
+
## Things to avoid
|
|
72
|
+
|
|
73
|
+
- Reading large HTML or `console.json` whole — `grep` / `jq`.
|
|
74
|
+
- Stopping at the last marked failure instead of the first.
|
|
75
|
+
- Triaging individual failures before clustering.
|
|
76
|
+
- Flakiness conclusions from a single run — needs 5+ reruns.
|
|
77
|
+
- Deleting `output/` mid-investigation.
|
|
78
|
+
|
|
79
|
+
## Related skills
|
|
80
|
+
|
|
81
|
+
- `codeceptjs-fundamentals` — what's configured, aiTrace `-p` overrides
|
|
82
|
+
- `codeceptjs-exploration` — locator drift fixes
|
|
83
|
+
- `debugging-codeceptjs-tests` — live loop + offline locator resolution via `codeceptq`
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debugging-codeceptjs-tests
|
|
3
|
+
description: >
|
|
4
|
+
Use when a CodeceptJS 4 test fails, flakes, or behaves unexpectedly. Trigger
|
|
5
|
+
on run errors and stack traces from `npx codeceptjs run`, intermittent
|
|
6
|
+
failures, locator drift, timing issues, "works locally fails in CI", "why
|
|
7
|
+
does this fail", trace/screenshot/console mentions, and breakpoint /
|
|
8
|
+
step-through / "pause at step N" requests.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Debugging CodeceptJS 4 Tests
|
|
12
|
+
|
|
13
|
+
Failures lie — the error usually points at a step that's a side effect of something earlier (auth expired, frame switch missed, network call pending). Reproduce, capture state, read it, then fix.
|
|
14
|
+
|
|
15
|
+
## Paths
|
|
16
|
+
|
|
17
|
+
- **MCP-first (AI agents)**: `run_test` / in-test `pause()` yield control to the agent on the same `I` / browser the test uses. Inspect via `run_code` / `snapshot`; step through via `run_step_by_step` + `continue`.
|
|
18
|
+
- **CLI fallback (humans / CI / framework internals)**: `--debug` → `--verbose` → `DEBUG="codeceptjs:*"`. The DEBUG escape hatch is only for framework-internal suspicion: recorder hangs, plugin races, event leaks, "step never ran". Namespaces: `codeceptjs:recorder`, `codeceptjs:pause`, `codeceptjs:ai`, `codeceptjs:plugin:<name>`.
|
|
19
|
+
|
|
20
|
+
`pause()` adapts to who's driving: TTY → readline REPL; MCP → yields control to the agent; non-TTY non-MCP subprocess → prints a notice and resolves (no CI deadlock).
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. **Fundamentals** — run `codeceptjs-fundamentals`: helper, plugins (`aiTrace`, `screenshot`, `pageInfo`, `retryFailedStep`, `pause`, `auth`), env vars, MCP availability. If `aiTrace` isn't declared, add it once: `plugins: { aiTrace: { enabled: true } }` — most of this skill leans on its output.
|
|
25
|
+
- **Declare once; never edit config to change its trigger.** Override per-run with `-p aiTrace:on=step|fail|test|file|url` (fundamentals § Plugins from CLI). `on=fail` for lean CI repros, `on=step` while diagnosing. Flipping `on:` in config churns the repo and leaks into other runs.
|
|
26
|
+
2. **Reproduce minimally**: `npx codeceptjs run --grep '<scenario>' --steps`. Add `-c codecept.ci.conf.js` if CI-specific. Confirm reproduction before instrumenting.
|
|
27
|
+
3. **Pick tools**:
|
|
28
|
+
- MCP `run_test <test>` — runs in-process; returns reporter result or `{ status: 'paused', pausedAfter, page, suggestions }`
|
|
29
|
+
- MCP `run_step_by_step` + `continue` — pause after every step; for watching the whole flow
|
|
30
|
+
- MCP `run_code` — arbitrary code in the live session; works fresh *and* paused; returns produced values + console output + final-state snapshot
|
|
31
|
+
- MCP `snapshot` — current browser state without acting (URL, cookies, storage, HTML, ARIA, screenshot, console)
|
|
32
|
+
- MCP `list_actions` — sanity-check an `I.*` method exists
|
|
33
|
+
- CLI `npx codeceptjs run --grep '<scenario>' --debug` — first move without MCP; `--verbose` adds promise-queue/retry/timeout logs
|
|
34
|
+
4. **Breakpoint**:
|
|
35
|
+
- In-test `pause()` — best when already editing or breaking inside `within`/loop/hook
|
|
36
|
+
- `pauseAt: N` on `run_test` — no test edit; pauses after the Nth leaf step
|
|
37
|
+
- Find N: `npx codeceptjs dry-run --debug --grep '<scenario>' --numbers --no-ansi` (1-based, per-test; number of the line to stop *after*)
|
|
38
|
+
- While paused: inspect with `run_code`, capture clean state with `snapshot`, walk prior steps in `output/trace_<TestName>_<hash>/trace.md`, release with `continue`
|
|
39
|
+
5. **Read the trace** — hand off to `codeceptjs-run-analysis`; focus on the **first** failed step — late failures are usually side effects of an earlier silent miss. It also covers grepping large HTML, clustering errors across traces, comparing reruns.
|
|
40
|
+
6. **Form a hypothesis**:
|
|
41
|
+
|
|
42
|
+
| Symptom | Likely cause |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Element missing, page is `/login` | Auth: stale session cache, missing env var |
|
|
45
|
+
| Element in HTML but `display: none` | `waitForVisible`, not `waitForElement` |
|
|
46
|
+
| Locator matches 2+ (strict mode) | Scope it: context arg, then ARIA role, then `step.opts({ elementIndex })` |
|
|
47
|
+
| Element present in screenshot N+1, missing in N | Animation / lazy load → `waitForVisible(loc, t)` |
|
|
48
|
+
| 401/403 in console.json | API token expired or env var missing |
|
|
49
|
+
| Steps pass, next `I.see` fails | Frame switch missed → `within({ frame })` |
|
|
50
|
+
| Different result CI vs local | `setHeadlessWhen(CI)`, viewport, timing, env vars |
|
|
51
|
+
| Recorder hangs, step never fires | `DEBUG="codeceptjs:recorder"` |
|
|
52
|
+
| Plugin misbehaves | `DEBUG="codeceptjs:plugin:<name>"` |
|
|
53
|
+
|
|
54
|
+
7. **Verify the fix on the live page** — try the candidate replacement step via `run_code` (works while paused, same `I`) **before editing the file**. Humans at a TTY get the same via in-test `pause()`.
|
|
55
|
+
8. **Apply and re-run**: edit, then `npx codeceptjs run --grep '<scenario>' --steps`; confirm via `codeceptjs-run-analysis` that the failure didn't shift steps. Leave a one-line `Why:` comment when the fix introduces `waitFor*` or `step.opts` — those comments are worth keeping.
|
|
56
|
+
|
|
57
|
+
## Query trace HTML with `codeceptq`
|
|
58
|
+
|
|
59
|
+
`aiTrace` writes per-step `<NNNN>_<step>_page.html` snapshots (one element per line — line numbers map 1:1 to elements). `codeceptq` resolves any CodeceptJS locator against a saved snapshot.
|
|
60
|
+
|
|
61
|
+
- **Never load page HTML into context manually** — snapshots are thousands of lines; `codeceptq` returns only matched elements with their line numbers.
|
|
62
|
+
- Test candidate locators offline before applying via `run_code` — a hit is a green light to try live, not a guarantee (visibility, re-renders).
|
|
63
|
+
- Multiple matches → don't write a brittler XPath; disambiguate with `step.opts({ elementIndex })` following the order `codeceptq` prints.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx codeceptq '#submit-btn' --file output/trace_*/0007_*_page.html # CSS
|
|
67
|
+
npx codeceptq 'Email' --field --file output/trace_*/0003_*_page.html # semantic field
|
|
68
|
+
npx codeceptq 'Save' '.modal' --click --file output/trace_*/0005_*_page.html # scoped clickable
|
|
69
|
+
npx codeceptq 'Username' --field --json --file ... # machine-readable
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Key flags: `--field/--click/--checkable/--select` force semantic strategies; `--xpath`/`--css` override auto-detection (a bare tag name like `select.foo` is treated as fuzzy text); exit codes `0` match / `1` none / `2` invalid input.
|
|
73
|
+
|
|
74
|
+
> ⚠ **The `[context]` second positional does not scope** (CodeceptJS 4.1.0). It prints `N matches within '<ctx>'` but returns page-wide results — `lib/command/query.js` evaluates an absolute XPath (`//…`) against the context node, and `//foo` re-roots at the document. It will report a match inside a container that does not hold the element. To check a scoped locator offline, pass one composed selector (`codeceptq '.modal button[aria-label="Save"]'`) and compare its count against the unscoped form; a context-dependent locator is only truly verified by running the step.
|
|
75
|
+
|
|
76
|
+
## Inspect deeper
|
|
77
|
+
|
|
78
|
+
Hand off to `codeceptjs-exploration` when the trace says *what* failed but you need more page-state detail ("is this button actually disabled?", "are there really two Save buttons?"). Debug-specific reaches:
|
|
79
|
+
|
|
80
|
+
- Button rendered but click had no effect → `grabWebElement('Submit')` + `isEnabled()` + `getBoundingBox()` (disabled? offscreen?)
|
|
81
|
+
- Strict-mode multi-match → exploration's broad-XPath iterate-and-disambiguate pattern
|
|
82
|
+
- Iframe content → wrap failing steps in `within({ frame })`
|
|
83
|
+
|
|
84
|
+
Prefer this over `usePlaywrightTo`/`useWebDriverTo` for inspection — same code across helpers, less boilerplate.
|
|
85
|
+
|
|
86
|
+
## Native helper escape hatch
|
|
87
|
+
|
|
88
|
+
Only when the `I.*` surface truly doesn't cover it (network interception, storage manipulation, helper-only APIs):
|
|
89
|
+
|
|
90
|
+
- Playwright: `I.usePlaywrightTo('label', async ({ browser, browserContext, page }) => { ... })`
|
|
91
|
+
- Puppeteer: `I.usePuppeteerTo('label', async ({ page }) => { ... })`
|
|
92
|
+
- WebDriver: `I.useWebDriverTo('label', async ({ browser }) => { ... })`
|
|
93
|
+
|
|
94
|
+
The label shows up in step output and traces. Works inside MCP `run_code` too. These couple tests to a specific helper — last resort.
|
|
95
|
+
|
|
96
|
+
## Helper gotchas
|
|
97
|
+
|
|
98
|
+
- Playwright: `strict: true` throws on multi-match; prefer `'load'`/`'domcontentloaded'` over `'networkidle'`; `trace: 'on'` → `output/trace.zip` (`npx playwright show-trace`)
|
|
99
|
+
- Puppeteer: `'networkidle0'` hangs on long-polling pages — use `'networkidle2'` or `'domcontentloaded'`
|
|
100
|
+
- WebDriver: `smartWait` covers actions only, not assertions; `executeScript` args must be JSON-serializable
|
|
101
|
+
|
|
102
|
+
## Auth-related failures
|
|
103
|
+
|
|
104
|
+
Redirect to `/login` mid-test or 401/403 in console → fix **auth**, not the failing step: check the plugin's `check`, credential env vars, and stale cached session under `output/<role>_session.json` (delete to force re-login). Full pattern in `codeceptjs-auth`.
|
|
105
|
+
|
|
106
|
+
## Flakiness and waits
|
|
107
|
+
|
|
108
|
+
Most "intermittent" failures are missed waits. Use trace HTML/ARIA to find the actual gating element instead of adding generic delay (fundamentals § Waiting has the mapping). `I.wait(N)` confirms a timing hypothesis while debugging — replace with the specific `waitFor*` before committing.
|
|
109
|
+
|
|
110
|
+
## Things to avoid
|
|
111
|
+
|
|
112
|
+
- Fixing from the error message without reading the trace.
|
|
113
|
+
- Editing the test before verifying the fix via `run_code`.
|
|
114
|
+
- Committing `pause()` calls — debugging tool only.
|
|
115
|
+
- Blind `waitFor*` instead of identifying the real gating element.
|
|
116
|
+
- Leaving `I.wait(N)` in committed tests.
|
|
117
|
+
- Editing `aiTrace`'s `on:` in config between runs — declare once, override per-run.
|
|
118
|
+
- Skipping the config check — `setHeadlessWhen(CI)` / env-driven URLs explain many "works locally fails in CI".
|
|
119
|
+
- Hiding failures with `retries` instead of fixing the cause.
|
|
120
|
+
|
|
121
|
+
## Related skills
|
|
122
|
+
|
|
123
|
+
- `codeceptjs-fundamentals` — effects, plugins-from-CLI, waiting rules
|
|
124
|
+
- `codeceptjs-exploration` — WebElement inspection, broad-XPath disambiguation
|
|
125
|
+
- `codeceptjs-run-analysis` — trace.md walking, error clustering, rerun comparison
|
|
126
|
+
- `codeceptjs-auth` — auth failure patterns
|