Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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)."
}
]
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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`)

Expand Down Expand Up @@ -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.

Expand Down
1 change: 1 addition & 0 deletions lint-codeceptjs-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
plugins/codeceptjs/skills/lint-codeceptjs-tests
104 changes: 104 additions & 0 deletions plugins/codeceptjs/skills/lint-codeceptjs-tests/SKILL.md
Original file line number Diff line number Diff line change
@@ -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