From 3e8e5047b7929ad831b5a4912de39d82a50fc346 Mon Sep 17 00:00:00 2001 From: Denys Kuchma Date: Mon, 12 Oct 2026 21:10:31 +0200 Subject: [PATCH] add lint-codeceptjs-tests skill for @codeceptjs/lint --- .claude-plugin/marketplace.json | 4 +- README.md | 5 +- lint-codeceptjs-tests | 1 + .../skills/lint-codeceptjs-tests/SKILL.md | 104 ++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 lint-codeceptjs-tests create mode 100644 plugins/codeceptjs/skills/lint-codeceptjs-tests/SKILL.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8fec8ac..61a38ee 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,7 +1,7 @@ { "name": "codeceptjs-skills", "metadata": { - "description": "Official CodeceptJS 4 skills — orientation, authoring, debugging, refactoring, and CI auto-repair for any AI agent that supports the Agent Skills standard." + "description": "Official CodeceptJS 4 skills — orientation, authoring, linting, debugging, refactoring, and CI auto-repair for any AI agent that supports the Agent Skills standard." }, "owner": { "name": "CodeceptJS" @@ -10,7 +10,7 @@ { "name": "codeceptjs", "source": "./plugins/codeceptjs", - "description": "Thirteen skills covering everything an AI agent needs to write, debug, refactor, migrate, and fix CodeceptJS 4 tests — a primer (codeceptjs-fundamentals), live page exploration (codeceptjs-exploration), trace analysis (codeceptjs-run-analysis), the auth plugin recipe (codeceptjs-auth), four action skills (writing, debugging, refactoring, ci-fix), and five migration skills (migrate-codeceptjs-4 for the 3.x→4.x upgrade, plus migrate-cypress / migrate-protractor / migrate-testcafe / migrate-selenium-java-to-codeceptjs)." + "description": "Fourteen skills covering everything an AI agent needs to write, lint, debug, refactor, migrate, and fix CodeceptJS 4 tests — a primer (codeceptjs-fundamentals), live page exploration (codeceptjs-exploration), trace analysis (codeceptjs-run-analysis), the auth plugin recipe (codeceptjs-auth), five action skills (writing, linting, debugging, refactoring, ci-fix), and five migration skills (migrate-codeceptjs-4 for the 3.x→4.x upgrade, plus migrate-cypress / migrate-protractor / migrate-testcafe / migrate-selenium-java-to-codeceptjs)." } ] } diff --git a/README.md b/README.md index f1be1e3..2f2215c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CodeceptJS Skills -AI agent skills for working with [CodeceptJS 4](https://codecept.io). Thirteen skills covering project orientation, authoring, debugging, refactoring, migration, and CI auto-repair — all written against the [Agent Skills](https://agentskills.io) open standard. +AI agent skills for working with [CodeceptJS 4](https://codecept.io). Fourteen skills covering project orientation, authoring, debugging, refactoring, migration, CI auto-repair, and linting — all written against the [Agent Skills](https://agentskills.io) open standard. ## Install @@ -13,7 +13,7 @@ From inside Claude Code: /plugin install codeceptjs@codeceptjs-skills ``` -That registers this repo as a marketplace and installs the `codeceptjs` plugin — all 13 skills, ready to invoke as `/codeceptjs-fundamentals`, `/writing-codeceptjs-tests`, etc. +That registers this repo as a marketplace and installs the `codeceptjs` plugin — all 14 skills, ready to invoke as `/codeceptjs-fundamentals`, `/writing-codeceptjs-tests`, etc. ### Any other supported agent (`npx skills`) @@ -52,6 +52,7 @@ If you can't run the CLI (locked-down environment, custom layout, etc.), each `< | [`debugging-codeceptjs-tests`](./debugging-codeceptjs-tests/SKILL.md) | A test is failing or flaky. Primary path: drop `pause()` in the test (or pass `pauseAt: N` to MCP `run_test`, with N from `dry-run --numbers`), inspect via `run_code` / `snapshot`, release with `continue`. CLI fallback (`--debug`, `DEBUG="codeceptjs:*"`) for humans, CI repros, and framework-internal issues. | | [`refactoring-codeceptjs-tests`](./refactoring-codeceptjs-tests/SKILL.md) | Cleaning up an existing suite — extracting page objects, taming long locators, moving raw JS into custom helpers. Targeted (one file) or global. Proposes before applying. | | [`ci-fix-tests`](./ci-fix-tests/SKILL.md) | Non-interactive CI mode: a run failed; auto-attempt safe fixes (locator drift, missing waits), rerun only the failing scenarios, roll back if no improvement, always write `output/ci-fix.md`. | +| [`lint-codeceptjs-tests`](./lint-codeceptjs-tests/SKILL.md) | The suite needs a static quality gate — before commit, in PR review, or in CI. Runs `@codeceptjs/lint` (AST-based, no browser) to catch fixed sleeps (`I.wait`, `setTimeout`), `if` in tests, raw `fetch()`, missing `await` on grabbers, plain-text credentials, and leftover `.only`/`pause()`; maps each finding to its fix and wires the CI step / Claude Code hook. | `codeceptjs-fundamentals`, `codeceptjs-exploration`, `codeceptjs-run-analysis`, and `codeceptjs-auth` are utility skills that the four action skills (writing, debugging, refactoring, ci-fix) invoke as needed. Users typically trigger an action skill; the utility skills get pulled in automatically. diff --git a/lint-codeceptjs-tests b/lint-codeceptjs-tests new file mode 100644 index 0000000..34fffdc --- /dev/null +++ b/lint-codeceptjs-tests @@ -0,0 +1 @@ +plugins/codeceptjs/skills/lint-codeceptjs-tests \ No newline at end of file diff --git a/plugins/codeceptjs/skills/lint-codeceptjs-tests/SKILL.md b/plugins/codeceptjs/skills/lint-codeceptjs-tests/SKILL.md new file mode 100644 index 0000000..d7f015d --- /dev/null +++ b/plugins/codeceptjs/skills/lint-codeceptjs-tests/SKILL.md @@ -0,0 +1,104 @@ +--- +name: lint-codeceptjs-tests +description: > + Use when a CodeceptJS 4 suite needs a static quality gate — before committing + tests, reviewing a PR that touches tests, hardening CI, or on direct asks: + "lint the tests", "find I.wait / setTimeout sleeps", "leftover .only or + pause()", "missing await on grab", "passwords printed in logs", "why are + tests slow/flaky". Runs `@codeceptjs/lint` — an AST-based linter that needs + no CodeceptJS install and no browser. +--- + +# Lint CodeceptJS 4 Tests + +`@codeceptjs/lint` reads tests, page objects and helpers as an AST and reports the smells that make suites slow, flaky or leaky — fixed sleeps, `if` branching, raw `fetch`, missing `await` on grabbers, plain-text credentials, leftover `.only`/`pause()`. One finding per line; exit codes `0` / `1` (errors found) / `2` (bad input, unparsable file) drop straight into CI. + +## Commands + +```bash +npx @codeceptjs/lint # files from codecept.conf.js in cwd +npx @codeceptjs/lint tests/ pages/login.js # explicit paths (no config needed) +npx @codeceptjs/lint -r no-pause -r no-only # only these rules (or --rules a,b) +npx @codeceptjs/lint rules # list rules + defaults +npx @codeceptjs/lint --json # file, line, column, rule, level, message, source +npx @codeceptjs/lint -c e2e/codecept.conf.js # config in another directory +``` + +Without paths it reads `codecept.conf.js|ts|cjs|mjs` and lints everything matched by `tests`, local `include` files (page objects, steps file) and helpers loaded via `require`. TypeScript is parsed with Node's type stripping (Node 22.13+); `enum`/`namespace` report as parse errors. A TS config importing `./x.js` for an `x.ts` file (tsx convention) loads when the project has `tsx` installed. + +## Rules and the fix for each + +| Rule | Default | Detects → fix | +|---|---|---| +| `no-fixed-wait` | error | `I.wait(5)` → `I.waitForElement` / `I.waitForText` / `I.see` | +| `no-sleep` | error | bare and `window.`/`globalThis.` `setTimeout`, incl. `await new Promise(r => setTimeout(r, ms))` and `timers/promises`, outside helpers → condition wait | +| `no-if-in-test` | error | `if` inside a Scenario/hook → `tryTo()` from `codeceptjs/effects` | +| `no-fetch` | error | `fetch()` (incl. `window.fetch`, `globalThis.fetch`) outside helpers → REST helper `I.sendGetRequest` / `I.sendPostRequest` | +| `no-console` | warn | `console.*` outside helpers → `I.say()` (lands in the report) | +| `no-only` | error on CI, warn locally | `Scenario.only`, `Feature.only`, `Data(...).only` → remove before commit | +| `no-pause` | error on CI, warn locally | `pause()`, `this.pause()` → remove before commit | +| `no-skip` | warn | `Scenario.skip`, `Feature.skip`, `xScenario`, `xFeature` → intentional? suppress with a comment explaining why | +| `secret-credentials` | error | credential-ish `process.env.X` / `process.env['X']` or a password/token/secret/api-key locator passed to `I.*` → wrap with `secret()` | +| `await-grab` | error | `I.grab*()` assigned, destructured or passed without `await` (`await Promise.all([...])` and `.then()` chains are fine) → add `await` | +| `no-actor-in-helper` | error | `I` inside a class extending `Helper` → `this.helpers['Name']` | +| `raw-browser-in-test` | warn | `I.use*To`, `I.executeScript` in a Scenario → move into a helper or page object | + +"On CI" = the `CI` env var is set — local debugging stubs (`pause()`, `.only`) stay warnings so they don't fail the lint while investigating. + +## Configuring per project + +Levels live in the config, next to the tests they govern: + +```js +export const config = { + tests: './*_test.js', + lint: { + rules: { 'no-if-in-test': 'warn', 'raw-browser-in-test': 'off' }, + }, +} +``` + +Levels: `error`, `warn`, `off`. For a single deliberate case, suppress inline — rule id required, never disable a rule project-wide for one line: + +```js +I.wait(1) // codeceptjs-lint-disable-line no-fixed-wait +``` + +## Workflow + +1. Run `npx @codeceptjs/lint` at the project root; if no config loads (secrets, tsx-less TS config), pass paths explicitly. +2. Fix errors first (they fail CI), warnings by judgment. Triage by cost: sleeps and missing `await` are the flakiness drivers; `secret()` fixes are one-line. +3. For bulk cleanup, feed `--json` output to drive file-by-file edits — the `source` field holds the offending line (truncated to 120 chars). +4. Add the gate so it stays clean: + +```yaml +# CI, before codeceptjs run +- run: npx @codeceptjs/lint +``` + +For agent-driven work, a Claude Code `PreToolUse` hook blocks edits that *add* a new error (pre-existing errors and warnings never block; a failing hook allows the edit): + +```json +{ + "hooks": { + "PreToolUse": [ + { "matcher": "Write|Edit|MultiEdit", "hooks": [{ "type": "command", "command": "npx @codeceptjs/lint --hook claude" }] } + ] + } +} +``` + +## Things to avoid + +- "Fixing" `await-grab` by deleting the `await` usage — the grab result is a promise, the fix is `await`, not removal. +- Replacing `I.wait` with a longer `I.wait`. +- Suppressing `no-if-in-test` when the branch is load-bearing — that's `tryTo()` or a helper's job. +- Adding the CI step before triaging existing findings — the suite goes red on day one. +- Skipping the hook's config scope check — it only lints files the config covers. + +## Related skills + +- `debugging-codeceptjs-tests` — `I.wait(N)` as a timing probe is fine mid-debug, lint-clean it before committing +- `refactoring-codeceptjs-tests` — bulk cleanup of a lint-red suite (extract helpers, tame locators) +- `writing-codeceptjs-tests` — write clean tests from the start +- `ci-fix-tests` — run the lint gate first so CI fixes don't reintroduce smells