@testspectra/skills 1.2.22 → 1.3.0
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 +1 -0
- package/dist/skills/debugging-runs/SKILL.md +51 -0
- package/dist/skills/lifecycle-hooks/SKILL.md +5 -0
- package/dist/skills/network-interception/SKILL.md +2 -1
- package/dist/skills/workspace-structure/SKILL.md +1 -0
- package/package.json +1 -1
- package/skills/debugging-runs/SKILL.md +51 -0
- package/skills/lifecycle-hooks/SKILL.md +5 -0
- package/skills/network-interception/SKILL.md +2 -1
- package/skills/workspace-structure/SKILL.md +1 -0
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ overrides the saved selection for a single invocation.
|
|
|
53
53
|
| Skill | Covers |
|
|
54
54
|
| :--------------------------- | :------------------------------------------------------------------------------------------------ |
|
|
55
55
|
| `workspace-structure` | Directory layout, zero-import architecture, file suffixes, `spectra.config.ts`, core CLI commands |
|
|
56
|
+
| `debugging-runs` | Reading a failing or slow run: failure context, warnings, intercept records, `spectra diagnose` |
|
|
56
57
|
| `spec-and-suite-authoring` | `suite.md` / `spec.md` frontmatter, the paired `*.test.ts` script, every `spectra lint` rule |
|
|
57
58
|
| `page-objects-and-selectors` | Page Object pattern (`Spectra.get`/`getAll`), the `~`/`#` selector contract |
|
|
58
59
|
| `matchers-and-assertions` | Full element action/assertion/collection matcher and global `Spectra.*` command reference |
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debugging-runs
|
|
3
|
+
description: How to read a failing or slow `spectra run` — the failure context, the warnings, the step lines, the network and intercept records — and `spectra diagnose` for failures that pass with `--delay`. Use whenever a test fails, times out, or a run slows down, before changing the script.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Debugging a run
|
|
7
|
+
|
|
8
|
+
Read what the run already reports before you change a script or add a wait. Every signal below is
|
|
9
|
+
printed by `spectra run` (plain output, CI, or an agent's shell) and saved under `.testspectra/reports/`.
|
|
10
|
+
|
|
11
|
+
## 1. Signals and what they mean
|
|
12
|
+
|
|
13
|
+
| Signal | Meaning | Do |
|
|
14
|
+
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
15
|
+
| `── failure context ──` (`[TESTSPECTRA_FAILURE_CONTEXT]` as JSON) | The page when the test failed: last step, URL, focused element, open dialogs, input rates, CDP calls, a screenshot | Open the screenshot; check the focused element and the dialogs against what the step expected |
|
|
16
|
+
| `"resolved":"<button aria-label=…>"` on a click/type step | The element the action actually hit | If it is not the one you meant, the lookup is wrong (a position, a repeated name) |
|
|
17
|
+
| `⚠ the page received N keydown events/s` | Input is repeating (a stuck key, a script re-dispatching) | Find the step named in the warning; the page is unusable after it |
|
|
18
|
+
| `⚠ the page's main thread is busy` / `CDP command … timed out during step #N` | The page did not answer | Look for an input storm or long tasks first, not for a longer timeout |
|
|
19
|
+
| `[TESTSPECTRA_INTERCEPT] '<pattern>' (METHOD) answered METHOD <url>` | Which mock answered which request | A URL you did not mean: narrow the pattern (a glob matches the whole URL) |
|
|
20
|
+
| `⚠ intercept '<pattern>' … answered no request` | The mock never matched | Check its URL and method |
|
|
21
|
+
| `[TESTSPECTRA_STATE_CARRIED] … sessionStorage: <keys>` | Storage the previous test case left (`isolation: 'suite'`) | A test that passes alone but fails in the suite: clear those keys in `beforeEach`, or set `webConfig.isolation: 'testcase'` |
|
|
22
|
+
| `⚠ another spectra run (pid …) is testing <url>` | Two runs share one server and reset each other's data | Stop one; results of both runs are unreliable |
|
|
23
|
+
| `Typed text did not reach … (focus was on …; the field is …)` | The keystrokes went elsewhere, or the field was disabled/inert | Wait for the state that enables the field |
|
|
24
|
+
|
|
25
|
+
`network-resources.json` holds every request with its HTTP method, request body and, when a mock
|
|
26
|
+
answered it, `interceptedBy`. The terminal no longer prints one line per request; set
|
|
27
|
+
`TESTSPECTRA_STREAM_NETWORK=1` to stream them.
|
|
28
|
+
|
|
29
|
+
## 2. A test that passes with `--delay`
|
|
30
|
+
|
|
31
|
+
It waits for no state. Ask the runner which step:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
spectra diagnose --spec <id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It reruns the spec with a wait after one step at a time, closest to the failure first, and prints
|
|
38
|
+
the step the test must wait after (`before step #33: click <button aria-label="Close dialog">`).
|
|
39
|
+
Put a `should*` assertion there for the state the app reaches — never a sleep. A global
|
|
40
|
+
`--delay` hides transient states a spec checks on purpose ("Checking availability…").
|
|
41
|
+
|
|
42
|
+
## 3. Probes, when the signals are not enough
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
await Spectra.browser.addInitScript(source); // runs in every document from its first instant
|
|
46
|
+
const stop = Spectra.onConsole(({ type, text }) => { /* … */ });
|
|
47
|
+
await Spectra.browser.cdp('Performance.getMetrics');
|
|
48
|
+
await Spectra.sleep(500); // probes only
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Delete a probe spec when you are done.
|
|
@@ -25,6 +25,11 @@ screenshots) that shouldn't be duplicated inside every `it()` body.
|
|
|
25
25
|
test genuinely depends on (navigating to `/login`, clearing storage) in a **suite** hook instead,
|
|
26
26
|
not a global one, or the test will fail/behave differently when run in isolation.
|
|
27
27
|
|
|
28
|
+
Test cases of a batch share one browser session (`webConfig.isolation: 'suite'`, the default): what
|
|
29
|
+
a case leaves in cookies, localStorage or sessionStorage (a table's search and page) is there for the
|
|
30
|
+
next one, and the run prints `[TESTSPECTRA_STATE_CARRIED]` naming it. Reset that state in the
|
|
31
|
+
suite's `beforeEach`, or set `isolation: 'testcase'` when no `before` hook needs to log in once.
|
|
32
|
+
|
|
28
33
|
---
|
|
29
34
|
|
|
30
35
|
## 2. Directory Layout
|
|
@@ -14,7 +14,7 @@ API, simulating an error, or asserting a call happened — rather than depending
|
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
interface InterceptRule {
|
|
17
|
-
url: string | RegExp; //
|
|
17
|
+
url: string | RegExp; // a glob matches the whole URL (a query may follow), e.g. '**/api/v1/payments/charge'
|
|
18
18
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'ALL';
|
|
19
19
|
response?: MockResponse | ((request: InterceptedRequest) => MockResponse | Promise<MockResponse>);
|
|
20
20
|
}
|
|
@@ -105,6 +105,7 @@ it('should handle offline mode gracefully when sync fails', async () => {
|
|
|
105
105
|
|
|
106
106
|
- Prefer glob URL patterns (`'**/api/v1/...'`) over exact origin strings so mocks survive
|
|
107
107
|
environment/base-URL changes between local, staging, and CI.
|
|
108
|
+
- A glob matches the whole URL: `'**/api/v1/brands'` does not also catch `/api/v1/brands/check-availability`; end it with `*` to cover every path under it.
|
|
108
109
|
- Only mock what the test is actually about — don't blanket-intercept every domain; the linter and
|
|
109
110
|
reviewers expect `monitoredDomains` in `spectra.config.ts` (see the `workspace-structure` skill)
|
|
110
111
|
to reflect real traffic, and over-mocking hides real integration regressions.
|
|
@@ -124,6 +124,7 @@ export default defineConfig({
|
|
|
124
124
|
headless: true,
|
|
125
125
|
implicitWait: '5000',
|
|
126
126
|
parallelizationMode: 'testcase', // "testcase" | "suite"
|
|
127
|
+
isolation: 'suite', // "suite": cases share the browser session (a before hook logs in once) | "testcase": empty cookies and storage per case
|
|
127
128
|
},
|
|
128
129
|
androidConfig: {
|
|
129
130
|
driverServer: 'tcp://127.0.0.1:8200',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/skills",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Installer & manager for modular AI agent skills that standardize TestSpectra script authoring (specs, page objects, steps, actions, hooks, fixtures, matchers)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debugging-runs
|
|
3
|
+
description: How to read a failing or slow `spectra run` — the failure context, the warnings, the step lines, the network and intercept records — and `spectra diagnose` for failures that pass with `--delay`. Use whenever a test fails, times out, or a run slows down, before changing the script.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Debugging a run
|
|
7
|
+
|
|
8
|
+
Read what the run already reports before you change a script or add a wait. Every signal below is
|
|
9
|
+
printed by `spectra run` (plain output, CI, or an agent's shell) and saved under `.testspectra/reports/`.
|
|
10
|
+
|
|
11
|
+
## 1. Signals and what they mean
|
|
12
|
+
|
|
13
|
+
| Signal | Meaning | Do |
|
|
14
|
+
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
15
|
+
| `── failure context ──` (`[TESTSPECTRA_FAILURE_CONTEXT]` as JSON) | The page when the test failed: last step, URL, focused element, open dialogs, input rates, CDP calls, a screenshot | Open the screenshot; check the focused element and the dialogs against what the step expected |
|
|
16
|
+
| `"resolved":"<button aria-label=…>"` on a click/type step | The element the action actually hit | If it is not the one you meant, the lookup is wrong (a position, a repeated name) |
|
|
17
|
+
| `⚠ the page received N keydown events/s` | Input is repeating (a stuck key, a script re-dispatching) | Find the step named in the warning; the page is unusable after it |
|
|
18
|
+
| `⚠ the page's main thread is busy` / `CDP command … timed out during step #N` | The page did not answer | Look for an input storm or long tasks first, not for a longer timeout |
|
|
19
|
+
| `[TESTSPECTRA_INTERCEPT] '<pattern>' (METHOD) answered METHOD <url>` | Which mock answered which request | A URL you did not mean: narrow the pattern (a glob matches the whole URL) |
|
|
20
|
+
| `⚠ intercept '<pattern>' … answered no request` | The mock never matched | Check its URL and method |
|
|
21
|
+
| `[TESTSPECTRA_STATE_CARRIED] … sessionStorage: <keys>` | Storage the previous test case left (`isolation: 'suite'`) | A test that passes alone but fails in the suite: clear those keys in `beforeEach`, or set `webConfig.isolation: 'testcase'` |
|
|
22
|
+
| `⚠ another spectra run (pid …) is testing <url>` | Two runs share one server and reset each other's data | Stop one; results of both runs are unreliable |
|
|
23
|
+
| `Typed text did not reach … (focus was on …; the field is …)` | The keystrokes went elsewhere, or the field was disabled/inert | Wait for the state that enables the field |
|
|
24
|
+
|
|
25
|
+
`network-resources.json` holds every request with its HTTP method, request body and, when a mock
|
|
26
|
+
answered it, `interceptedBy`. The terminal no longer prints one line per request; set
|
|
27
|
+
`TESTSPECTRA_STREAM_NETWORK=1` to stream them.
|
|
28
|
+
|
|
29
|
+
## 2. A test that passes with `--delay`
|
|
30
|
+
|
|
31
|
+
It waits for no state. Ask the runner which step:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
spectra diagnose --spec <id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It reruns the spec with a wait after one step at a time, closest to the failure first, and prints
|
|
38
|
+
the step the test must wait after (`before step #33: click <button aria-label="Close dialog">`).
|
|
39
|
+
Put a `should*` assertion there for the state the app reaches — never a sleep. A global
|
|
40
|
+
`--delay` hides transient states a spec checks on purpose ("Checking availability…").
|
|
41
|
+
|
|
42
|
+
## 3. Probes, when the signals are not enough
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
await Spectra.browser.addInitScript(source); // runs in every document from its first instant
|
|
46
|
+
const stop = Spectra.onConsole(({ type, text }) => { /* … */ });
|
|
47
|
+
await Spectra.browser.cdp('Performance.getMetrics');
|
|
48
|
+
await Spectra.sleep(500); // probes only
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Delete a probe spec when you are done.
|
|
@@ -25,6 +25,11 @@ screenshots) that shouldn't be duplicated inside every `it()` body.
|
|
|
25
25
|
test genuinely depends on (navigating to `/login`, clearing storage) in a **suite** hook instead,
|
|
26
26
|
not a global one, or the test will fail/behave differently when run in isolation.
|
|
27
27
|
|
|
28
|
+
Test cases of a batch share one browser session (`webConfig.isolation: 'suite'`, the default): what
|
|
29
|
+
a case leaves in cookies, localStorage or sessionStorage (a table's search and page) is there for the
|
|
30
|
+
next one, and the run prints `[TESTSPECTRA_STATE_CARRIED]` naming it. Reset that state in the
|
|
31
|
+
suite's `beforeEach`, or set `isolation: 'testcase'` when no `before` hook needs to log in once.
|
|
32
|
+
|
|
28
33
|
---
|
|
29
34
|
|
|
30
35
|
## 2. Directory Layout
|
|
@@ -14,7 +14,7 @@ API, simulating an error, or asserting a call happened — rather than depending
|
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
interface InterceptRule {
|
|
17
|
-
url: string | RegExp; //
|
|
17
|
+
url: string | RegExp; // a glob matches the whole URL (a query may follow), e.g. '**/api/v1/payments/charge'
|
|
18
18
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'ALL';
|
|
19
19
|
response?: MockResponse | ((request: InterceptedRequest) => MockResponse | Promise<MockResponse>);
|
|
20
20
|
}
|
|
@@ -105,6 +105,7 @@ it('should handle offline mode gracefully when sync fails', async () => {
|
|
|
105
105
|
|
|
106
106
|
- Prefer glob URL patterns (`'**/api/v1/...'`) over exact origin strings so mocks survive
|
|
107
107
|
environment/base-URL changes between local, staging, and CI.
|
|
108
|
+
- A glob matches the whole URL: `'**/api/v1/brands'` does not also catch `/api/v1/brands/check-availability`; end it with `*` to cover every path under it.
|
|
108
109
|
- Only mock what the test is actually about — don't blanket-intercept every domain; the linter and
|
|
109
110
|
reviewers expect `monitoredDomains` in `spectra.config.ts` (see the `workspace-structure` skill)
|
|
110
111
|
to reflect real traffic, and over-mocking hides real integration regressions.
|
|
@@ -124,6 +124,7 @@ export default defineConfig({
|
|
|
124
124
|
headless: true,
|
|
125
125
|
implicitWait: '5000',
|
|
126
126
|
parallelizationMode: 'testcase', // "testcase" | "suite"
|
|
127
|
+
isolation: 'suite', // "suite": cases share the browser session (a before hook logs in once) | "testcase": empty cookies and storage per case
|
|
127
128
|
},
|
|
128
129
|
androidConfig: {
|
|
129
130
|
driverServer: 'tcp://127.0.0.1:8200',
|