retestkit 1.4.1 → 1.5.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 +59 -40
- package/dist/config.js +8 -8
- package/dist/config.js.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +21 -21
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/templates/mcp/retest-crawl.md +7 -0
- package/{src/prompts/templates/mcp/webtest-discover-flows.md → dist/prompts/templates/mcp/retest-discover-flows.md} +1 -1
- package/{src/prompts/templates/mcp/webtest-discover.md → dist/prompts/templates/mcp/retest-discover.md} +2 -2
- package/dist/prompts/templates/mcp/retest-full-workflow.md +12 -0
- package/{src/prompts/templates/mcp/webtest-generate-tests.md → dist/prompts/templates/mcp/retest-generate-tests.md} +1 -1
- package/{src/prompts/templates/mcp/webtest-run-test.md → dist/prompts/templates/mcp/retest-run-test.md} +1 -1
- package/{src/prompts/templates/mcp/webtest-start.md → dist/prompts/templates/mcp/retest-start.md} +1 -1
- package/{src → dist}/prompts/templates/sampling/system-prefix.md +1 -1
- package/dist/resources/index.js +7 -7
- package/dist/resources/index.js.map +1 -1
- package/dist/schemas/config.js +2 -2
- package/dist/schemas/config.js.map +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server.js +3 -3
- package/dist/server.js.map +1 -1
- package/dist/test-utils/mock-context.js +22 -22
- package/dist/test-utils/mock-context.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/retest/crawl.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/crawl.js +7 -7
- package/dist/tools/retest/crawl.js.map +1 -0
- package/dist/tools/retest/discover-features.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/discover-features.js +6 -6
- package/dist/tools/retest/discover-features.js.map +1 -0
- package/dist/tools/retest/discover-flows.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/discover-flows.js +6 -6
- package/dist/tools/retest/discover-flows.js.map +1 -0
- package/dist/tools/retest/generate-tests.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/generate-tests.js +5 -5
- package/dist/tools/retest/generate-tests.js.map +1 -0
- package/dist/tools/retest/index.d.ts.map +1 -0
- package/dist/tools/retest/index.js.map +1 -0
- package/dist/tools/retest/run-test-case.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/run-test-case.js +3 -3
- package/dist/tools/retest/run-test-case.js.map +1 -0
- package/dist/tools/retest/schemas.d.ts.map +1 -0
- package/dist/tools/retest/schemas.js.map +1 -0
- package/dist/tools/retest/start-analysis.d.ts.map +1 -0
- package/dist/tools/{webtest → retest}/start-analysis.js +5 -5
- package/dist/tools/retest/start-analysis.js.map +1 -0
- package/dist/workspace/index.js +8 -8
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/types.d.ts +2 -2
- package/dist/workspace/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/.claude/commands/openspec/apply.md +0 -23
- package/.claude/commands/openspec/archive.md +0 -27
- package/.claude/commands/openspec/proposal.md +0 -28
- package/.gemini/commands/openspec/apply.toml +0 -21
- package/.gemini/commands/openspec/archive.toml +0 -25
- package/.gemini/commands/openspec/proposal.toml +0 -26
- package/.github/prompts/openspec-apply.prompt.md +0 -22
- package/.github/prompts/openspec-archive.prompt.md +0 -26
- package/.github/prompts/openspec-proposal.prompt.md +0 -27
- package/.github/workflows/release.yml +0 -33
- package/.kilocode/workflows/openspec-apply.md +0 -17
- package/.kilocode/workflows/openspec-archive.md +0 -21
- package/.kilocode/workflows/openspec-proposal.md +0 -22
- package/.mcp.json +0 -23
- package/.opencode/command/openspec-apply.md +0 -25
- package/.opencode/command/openspec-archive.md +0 -28
- package/.opencode/command/openspec-proposal.md +0 -30
- package/.roo/commands/openspec-apply.md +0 -20
- package/.roo/commands/openspec-archive.md +0 -24
- package/.roo/commands/openspec-proposal.md +0 -25
- package/.vscode/mcp.json +0 -23
- package/AGENTS.md +0 -18
- package/CLAUDE.md +0 -18
- package/dist/tools/webtest/crawl.d.ts.map +0 -1
- package/dist/tools/webtest/crawl.js.map +0 -1
- package/dist/tools/webtest/discover-features.d.ts.map +0 -1
- package/dist/tools/webtest/discover-features.js.map +0 -1
- package/dist/tools/webtest/discover-flows.d.ts.map +0 -1
- package/dist/tools/webtest/discover-flows.js.map +0 -1
- package/dist/tools/webtest/generate-tests.d.ts.map +0 -1
- package/dist/tools/webtest/generate-tests.js.map +0 -1
- package/dist/tools/webtest/index.d.ts.map +0 -1
- package/dist/tools/webtest/index.js.map +0 -1
- package/dist/tools/webtest/run-test-case.d.ts.map +0 -1
- package/dist/tools/webtest/run-test-case.js.map +0 -1
- package/dist/tools/webtest/schemas.d.ts.map +0 -1
- package/dist/tools/webtest/schemas.js.map +0 -1
- package/dist/tools/webtest/start-analysis.d.ts.map +0 -1
- package/dist/tools/webtest/start-analysis.js.map +0 -1
- package/openspec/AGENTS.md +0 -456
- package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/proposal.md +0 -33
- package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/specs/webtest-resources/spec.md +0 -27
- package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/specs/webtest-tools/spec.md +0 -304
- package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/tasks.md +0 -43
- package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/design.md +0 -209
- package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/proposal.md +0 -41
- package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/specs/mcp-server-core/spec.md +0 -183
- package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/tasks.md +0 -112
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/design.md +0 -333
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/proposal.md +0 -66
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/mcp-server-core/spec.md +0 -129
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-lifecycle/spec.md +0 -138
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-logging/spec.md +0 -211
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-prompts/spec.md +0 -157
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-resources/spec.md +0 -213
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-sampling/spec.md +0 -257
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-tools/spec.md +0 -501
- package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/tasks.md +0 -264
- package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/proposal.md +0 -24
- package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/specs/webtest-tools/spec.md +0 -80
- package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/tasks.md +0 -8
- package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/design.md +0 -90
- package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/proposal.md +0 -28
- package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/specs/webtest-sampling/spec.md +0 -90
- package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/tasks.md +0 -33
- package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/design.md +0 -558
- package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/proposal.md +0 -119
- package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/specs/webtest-resources/spec.md +0 -109
- package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/specs/webtest-tools/spec.md +0 -121
- package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/tasks.md +0 -133
- package/openspec/changes/extract-prompts-to-markdown/design.md +0 -86
- package/openspec/changes/extract-prompts-to-markdown/proposal.md +0 -50
- package/openspec/changes/extract-prompts-to-markdown/specs/webtest-prompts/spec.md +0 -74
- package/openspec/changes/extract-prompts-to-markdown/tasks.md +0 -40
- package/openspec/changes/refactor-webtest-naming/design.md +0 -95
- package/openspec/changes/refactor-webtest-naming/proposal.md +0 -66
- package/openspec/changes/refactor-webtest-naming/specs/webtest-prompts/spec.md +0 -79
- package/openspec/changes/refactor-webtest-naming/specs/webtest-resources/spec.md +0 -80
- package/openspec/changes/refactor-webtest-naming/specs/webtest-sampling/spec.md +0 -122
- package/openspec/changes/refactor-webtest-naming/specs/webtest-tools/spec.md +0 -113
- package/openspec/changes/refactor-webtest-naming/tasks.md +0 -119
- package/openspec/changes/rename-package-to-retest/proposal.md +0 -52
- package/openspec/changes/rename-package-to-retest/specs/mcp-server-core/spec.md +0 -53
- package/openspec/changes/rename-package-to-retest/specs/retest-lifecycle/spec.md +0 -68
- package/openspec/changes/rename-package-to-retest/specs/retest-logging/spec.md +0 -35
- package/openspec/changes/rename-package-to-retest/specs/retest-prompts/spec.md +0 -159
- package/openspec/changes/rename-package-to-retest/specs/retest-resources/spec.md +0 -251
- package/openspec/changes/rename-package-to-retest/specs/retest-sampling/spec.md +0 -99
- package/openspec/changes/rename-package-to-retest/specs/retest-tools/spec.md +0 -295
- package/openspec/changes/rename-package-to-retest/tasks.md +0 -71
- package/openspec/project.md +0 -31
- package/openspec/specs/mcp-server-core/spec.md +0 -178
- package/openspec/specs/webtest-lifecycle/spec.md +0 -136
- package/openspec/specs/webtest-logging/spec.md +0 -209
- package/openspec/specs/webtest-prompts/spec.md +0 -155
- package/openspec/specs/webtest-resources/spec.md +0 -248
- package/openspec/specs/webtest-sampling/spec.md +0 -344
- package/openspec/specs/webtest-tools/spec.md +0 -282
- package/release.config.js +0 -9
- package/src/config.test.ts +0 -96
- package/src/config.ts +0 -32
- package/src/elicitation/index.test.ts +0 -399
- package/src/elicitation/index.ts +0 -171
- package/src/elicitation/types.ts +0 -68
- package/src/index.ts +0 -83
- package/src/lifecycle/index.test.ts +0 -260
- package/src/lifecycle/index.ts +0 -101
- package/src/logger.redaction.test.ts +0 -322
- package/src/logger.test.ts +0 -123
- package/src/logger.ts +0 -229
- package/src/playwright-client/index.ts +0 -392
- package/src/playwright-client/types.ts +0 -99
- package/src/progress/index.test.ts +0 -327
- package/src/progress/index.ts +0 -170
- package/src/progress/types.ts +0 -25
- package/src/prompts/index.test.ts +0 -451
- package/src/prompts/index.ts +0 -246
- package/src/prompts/loader.test.ts +0 -100
- package/src/prompts/loader.ts +0 -59
- package/src/prompts/templates/mcp/webtest-crawl.md +0 -7
- package/src/prompts/templates/mcp/webtest-full-workflow.md +0 -12
- package/src/resources/index.ts +0 -250
- package/src/resources/subscriptions.ts +0 -37
- package/src/sampling/index.test.ts +0 -414
- package/src/sampling/index.ts +0 -286
- package/src/sampling/prompts.ts +0 -194
- package/src/sampling/types.ts +0 -60
- package/src/schemas/config.ts +0 -39
- package/src/security/index.test.ts +0 -441
- package/src/security/index.ts +0 -361
- package/src/security/security-scenarios.test.ts +0 -468
- package/src/server.ts +0 -211
- package/src/test-utils/index.ts +0 -6
- package/src/test-utils/mock-context.ts +0 -426
- package/src/test-utils/mock-playwright-client.ts +0 -422
- package/src/tools/index.ts +0 -11
- package/src/tools/webtest/crawl.test.ts +0 -834
- package/src/tools/webtest/crawl.ts +0 -901
- package/src/tools/webtest/discover-features.ts +0 -412
- package/src/tools/webtest/discover-flows.ts +0 -408
- package/src/tools/webtest/generate-tests.test.ts +0 -532
- package/src/tools/webtest/generate-tests.ts +0 -425
- package/src/tools/webtest/index.ts +0 -7
- package/src/tools/webtest/integration.test.ts +0 -536
- package/src/tools/webtest/run-test-case.test.ts +0 -659
- package/src/tools/webtest/run-test-case.ts +0 -508
- package/src/tools/webtest/schemas.ts +0 -201
- package/src/tools/webtest/start-analysis.test.ts +0 -151
- package/src/tools/webtest/start-analysis.ts +0 -158
- package/src/transports/http.ts +0 -19
- package/src/transports/index.ts +0 -30
- package/src/transports/stdio.ts +0 -7
- package/src/types/capabilities.test.ts +0 -193
- package/src/types/capabilities.ts +0 -50
- package/src/types/context.ts +0 -21
- package/src/types/tool.ts +0 -11
- package/src/workspace/index.ts +0 -945
- package/src/workspace/markdown.ts +0 -272
- package/src/workspace/types.ts +0 -186
- package/tests/integration/server.test.ts +0 -89
- package/tests/integration/tools.test.ts +0 -99
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -9
- package/vitest.integration.config.ts +0 -10
- /package/{src → dist}/prompts/templates/sampling/crawl-action.md +0 -0
- /package/{src → dist}/prompts/templates/sampling/feature-discovery.md +0 -0
- /package/{src → dist}/prompts/templates/sampling/flow-discovery.md +0 -0
- /package/{src → dist}/prompts/templates/sampling/page-content-wrapper.md +0 -0
- /package/{src → dist}/prompts/templates/sampling/test-evaluation.md +0 -0
- /package/{src → dist}/prompts/templates/sampling/test-generation.md +0 -0
- /package/dist/tools/{webtest → retest}/crawl.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/discover-features.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/discover-flows.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/generate-tests.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/index.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/index.js +0 -0
- /package/dist/tools/{webtest → retest}/run-test-case.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/schemas.d.ts +0 -0
- /package/dist/tools/{webtest → retest}/schemas.js +0 -0
- /package/dist/tools/{webtest → retest}/start-analysis.d.ts +0 -0
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
# webtest-tools Specification
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
TBD - created by archiving change add-webtest-orchestrator. Update Purpose after archive.
|
|
5
|
-
## Requirements
|
|
6
|
-
### Requirement: webtest_init Tool
|
|
7
|
-
|
|
8
|
-
The system SHALL provide a `webtest_init` tool that initializes an analysis workspace for a target URL and focus, storing metadata in markdown format.
|
|
9
|
-
|
|
10
|
-
#### Scenario: Start analysis with valid URL
|
|
11
|
-
|
|
12
|
-
- **GIVEN** the tool is called with a valid URL and focus
|
|
13
|
-
- **WHEN** execution completes
|
|
14
|
-
- **THEN** it SHALL generate a unique `analysisId`
|
|
15
|
-
- **AND** create workspace directories
|
|
16
|
-
- **AND** write initial `index.md` metadata with YAML frontmatter
|
|
17
|
-
- **AND** return `{ analysisId, workspaceRootPath, workspaceRootUri, statusUri }` where statusUri points to `index.md`
|
|
18
|
-
|
|
19
|
-
### Requirement: webtest_crawl_app Tool
|
|
20
|
-
|
|
21
|
-
The system SHALL provide a `webtest_crawl_app` tool that dynamically explores a web application, storing all crawl artifacts in markdown format.
|
|
22
|
-
|
|
23
|
-
#### Scenario: Crawl captures artifacts at each checkpoint
|
|
24
|
-
|
|
25
|
-
- **GIVEN** a crawl iteration completes an action
|
|
26
|
-
- **WHEN** state is captured
|
|
27
|
-
- **THEN** it SHALL call Playwright MCP `browser_snapshot` for accessibility tree
|
|
28
|
-
- **AND** call `browser_take_screenshot` for visual evidence
|
|
29
|
-
- **AND** optionally extract HTML DOM
|
|
30
|
-
- **AND** store snapshot as `snapshot.md` with formatted accessibility tree and YAML frontmatter
|
|
31
|
-
- **AND** store screenshot as PNG
|
|
32
|
-
- **AND** store DOM as HTML
|
|
33
|
-
|
|
34
|
-
#### Scenario: Crawl outputs complete results
|
|
35
|
-
|
|
36
|
-
- **GIVEN** crawl has finalized
|
|
37
|
-
- **WHEN** output is returned
|
|
38
|
-
- **THEN** it SHALL include `crawlId`, `crawlIndexFilePath`, `crawlIndexUri` (pointing to `index.md`), `pages[]`, `summaryUri`
|
|
39
|
-
|
|
40
|
-
### Requirement: webtest_analyze_app Tool
|
|
41
|
-
|
|
42
|
-
The system SHALL provide a `webtest_analyze_app` tool that reverse-engineers application structure from crawl data, outputting all results in markdown format.
|
|
43
|
-
|
|
44
|
-
#### Scenario: Analyze app writes markdown report
|
|
45
|
-
|
|
46
|
-
- **GIVEN** analysis is complete
|
|
47
|
-
- **WHEN** output is generated
|
|
48
|
-
- **THEN** it SHALL write `app-analysis.md` resource to workspace
|
|
49
|
-
|
|
50
|
-
#### Scenario: Analyze app writes flows
|
|
51
|
-
|
|
52
|
-
- **GIVEN** analysis is complete
|
|
53
|
-
- **WHEN** output is generated
|
|
54
|
-
- **THEN** it SHALL write `flows.md` resource to workspace as markdown with YAML frontmatter containing structured flow definitions
|
|
55
|
-
|
|
56
|
-
#### Scenario: Analyze app outputs URIs
|
|
57
|
-
|
|
58
|
-
- **GIVEN** analysis is complete
|
|
59
|
-
- **WHEN** tool returns
|
|
60
|
-
- **THEN** it SHALL include `appAnalysisFilePath`, `appAnalysisUri`, `flowsFilePath`, `flowsUri` all pointing to `.md` files
|
|
61
|
-
|
|
62
|
-
### Requirement: webtest_generate_tests Tool
|
|
63
|
-
|
|
64
|
-
The system SHALL provide a `webtest_generate_tests` tool that produces test cases from application analysis in a single markdown format.
|
|
65
|
-
|
|
66
|
-
#### Scenario: Generate tests outputs structured format
|
|
67
|
-
|
|
68
|
-
- **GIVEN** test generation completes
|
|
69
|
-
- **WHEN** results are written
|
|
70
|
-
- **THEN** it SHALL produce `tests.md` with human-readable format AND YAML frontmatter containing structured test definitions
|
|
71
|
-
- **AND** there SHALL NOT be a separate `tests.json` file
|
|
72
|
-
|
|
73
|
-
#### Scenario: Generate tests outputs URIs
|
|
74
|
-
|
|
75
|
-
- **GIVEN** generation is complete
|
|
76
|
-
- **WHEN** tool returns
|
|
77
|
-
- **THEN** it SHALL include `testsFilePath` and `testsUri` pointing to `tests.md`
|
|
78
|
-
|
|
79
|
-
### Requirement: webtest_run_tests Tool
|
|
80
|
-
|
|
81
|
-
The system SHALL provide a `webtest_run_tests` tool that executes a test case with evidence capture, storing all results in markdown format.
|
|
82
|
-
|
|
83
|
-
#### Scenario: Run test case captures evidence
|
|
84
|
-
|
|
85
|
-
- **GIVEN** a step is executed
|
|
86
|
-
- **WHEN** evidence is captured
|
|
87
|
-
- **THEN** it SHALL take screenshot after action (stored as PNG)
|
|
88
|
-
- **AND** capture accessibility snapshot (stored as `snapshot.md` with formatted tree and YAML frontmatter)
|
|
89
|
-
- **AND** store with step identifier
|
|
90
|
-
|
|
91
|
-
#### Scenario: Run test case outputs report
|
|
92
|
-
|
|
93
|
-
- **GIVEN** test execution completes
|
|
94
|
-
- **WHEN** output is generated
|
|
95
|
-
- **THEN** it SHALL write `report.md` with pass/fail summary, step details, evidence links, and YAML frontmatter containing structured run data
|
|
96
|
-
- **AND** there SHALL NOT be a separate `index.json` or `artifacts.json` file
|
|
97
|
-
|
|
98
|
-
#### Scenario: Run test case returns URIs
|
|
99
|
-
|
|
100
|
-
- **GIVEN** execution is complete
|
|
101
|
-
- **WHEN** tool returns
|
|
102
|
-
- **THEN** it SHALL include `testRunId`, `reportFilePath`, `reportUri` pointing to `report.md`
|
|
103
|
-
|
|
104
|
-
### Requirement: Playwright MCP Integration
|
|
105
|
-
|
|
106
|
-
The system SHALL orchestrate an external Playwright MCP server for browser automation with dynamic tool discovery.
|
|
107
|
-
|
|
108
|
-
#### Scenario: Playwright MCP is spawned on first use
|
|
109
|
-
|
|
110
|
-
- **GIVEN** a webtest tool needs browser access
|
|
111
|
-
- **WHEN** Playwright client is accessed
|
|
112
|
-
- **THEN** it SHALL spawn Playwright MCP server as subprocess if not running
|
|
113
|
-
- **AND** connect via stdio transport
|
|
114
|
-
|
|
115
|
-
#### Scenario: Playwright MCP tools are discovered dynamically
|
|
116
|
-
|
|
117
|
-
- **GIVEN** Playwright MCP is connected
|
|
118
|
-
- **WHEN** connection is established
|
|
119
|
-
- **THEN** it SHALL call `tools/list` to discover available tools
|
|
120
|
-
- **AND** build a capability adapter mapping canonical operations to actual tool names
|
|
121
|
-
- **AND** cache the mapping for the session lifetime
|
|
122
|
-
|
|
123
|
-
#### Scenario: Capability adapter maps canonical operations
|
|
124
|
-
|
|
125
|
-
- **GIVEN** Playwright MCP tools have been discovered
|
|
126
|
-
- **WHEN** the adapter is queried for operation "snapshot"
|
|
127
|
-
- **THEN** it SHALL return the matching tool (e.g., `browser_snapshot` or `playwright_snapshot`)
|
|
128
|
-
- **AND** if multiple matches exist, prefer the most specific
|
|
129
|
-
|
|
130
|
-
#### Scenario: Missing required capability logs warning
|
|
131
|
-
|
|
132
|
-
- **GIVEN** Playwright MCP tools have been discovered
|
|
133
|
-
- **WHEN** a required capability (snapshot, screenshot, click, type, navigate) is missing
|
|
134
|
-
- **THEN** it SHALL log a warning with the missing capability
|
|
135
|
-
- **AND** tools requiring that capability SHALL return an error when invoked
|
|
136
|
-
|
|
137
|
-
#### Scenario: Playwright actions are executed via adapter
|
|
138
|
-
|
|
139
|
-
- **GIVEN** a crawl action specifies `{ tool: "click", args: { selector: "button" } }`
|
|
140
|
-
- **WHEN** action is executed
|
|
141
|
-
- **THEN** it SHALL resolve "click" through the capability adapter
|
|
142
|
-
- **AND** call the resolved Playwright MCP tool with appropriate arguments
|
|
143
|
-
- **AND** return the result
|
|
144
|
-
|
|
145
|
-
#### Scenario: Playwright MCP version differences are handled
|
|
146
|
-
|
|
147
|
-
- **GIVEN** different Playwright MCP implementations may have different tool names
|
|
148
|
-
- **WHEN** the adapter maps tools
|
|
149
|
-
- **THEN** it SHALL check for common variants:
|
|
150
|
-
- `browser_*` prefix (Microsoft implementation)
|
|
151
|
-
- `playwright_*` prefix (alternative implementations)
|
|
152
|
-
- unprefixed names
|
|
153
|
-
- **AND** log the detected implementation variant
|
|
154
|
-
|
|
155
|
-
#### Scenario: Playwright MCP is terminated on shutdown
|
|
156
|
-
|
|
157
|
-
- **GIVEN** the server receives shutdown signal
|
|
158
|
-
- **WHEN** shutdown begins
|
|
159
|
-
- **THEN** it SHALL terminate Playwright MCP subprocess
|
|
160
|
-
- **AND** wait for clean exit
|
|
161
|
-
|
|
162
|
-
### Requirement: Crawl Checkpointing
|
|
163
|
-
|
|
164
|
-
The system SHALL implement checkpointing during crawl using markdown format to enable resumption and provide human-readable partial results on failure.
|
|
165
|
-
|
|
166
|
-
#### Scenario: Checkpoint is written periodically
|
|
167
|
-
|
|
168
|
-
- **GIVEN** a crawl is in progress
|
|
169
|
-
- **WHEN** N steps have completed (configurable, default 5)
|
|
170
|
-
- **THEN** it SHALL write a checkpoint to `webtest://{analysisId}/crawls/{crawlId}/checkpoint.md`
|
|
171
|
-
- **AND** the checkpoint SHALL be markdown with YAML frontmatter including: current step, visited pages, action history, goal progress
|
|
172
|
-
- **AND** the checkpoint body SHALL contain human-readable progress summary
|
|
173
|
-
|
|
174
|
-
#### Scenario: Crawl can resume from checkpoint
|
|
175
|
-
|
|
176
|
-
- **GIVEN** a crawl was interrupted (cancelled, error, timeout)
|
|
177
|
-
- **AND** a checkpoint exists as `checkpoint.md`
|
|
178
|
-
- **WHEN** `webtest_crawl_app` is called with `resume: true`
|
|
179
|
-
- **THEN** it SHALL parse the checkpoint YAML frontmatter
|
|
180
|
-
- **AND** continue from the last recorded state
|
|
181
|
-
|
|
182
|
-
### Requirement: Crawl Loop Detection and Prevention
|
|
183
|
-
|
|
184
|
-
The system SHALL detect and prevent infinite crawl loops.
|
|
185
|
-
|
|
186
|
-
#### Scenario: Same page state detected consecutively
|
|
187
|
-
|
|
188
|
-
- **GIVEN** crawl detects same DOM signature 3 times consecutively
|
|
189
|
-
- **WHEN** loop is detected
|
|
190
|
-
- **THEN** it SHALL log a warning with loop details
|
|
191
|
-
- **AND** inform sampling of the loop condition
|
|
192
|
-
- **AND** request alternative action with loop context
|
|
193
|
-
|
|
194
|
-
#### Scenario: URL cycle detected
|
|
195
|
-
|
|
196
|
-
- **GIVEN** crawl visits the same URL more than 3 times
|
|
197
|
-
- **WHEN** cycle is detected
|
|
198
|
-
- **THEN** it SHALL log a warning
|
|
199
|
-
- **AND** exclude that URL from future navigation suggestions
|
|
200
|
-
|
|
201
|
-
#### Scenario: Action repeat detected
|
|
202
|
-
|
|
203
|
-
- **GIVEN** the same action (tool + args) is attempted 3 times consecutively
|
|
204
|
-
- **WHEN** repeat is detected
|
|
205
|
-
- **THEN** it SHALL reject the repeated action
|
|
206
|
-
- **AND** request a different action from sampling with repeat context
|
|
207
|
-
|
|
208
|
-
#### Scenario: Loop detection state is included in sampling prompts
|
|
209
|
-
|
|
210
|
-
- **GIVEN** loop detection has flagged potential issues
|
|
211
|
-
- **WHEN** the next sampling prompt is built
|
|
212
|
-
- **THEN** it SHALL include:
|
|
213
|
-
- URLs visited more than once
|
|
214
|
-
- Recently repeated actions
|
|
215
|
-
- DOM signature history
|
|
216
|
-
- **AND** instruct the model to avoid these patterns
|
|
217
|
-
|
|
218
|
-
### Requirement: Crawl Budget Enforcement
|
|
219
|
-
|
|
220
|
-
The system SHALL enforce time, step, and page limits during crawl.
|
|
221
|
-
|
|
222
|
-
#### Scenario: Step limit is enforced
|
|
223
|
-
|
|
224
|
-
- **GIVEN** crawl has a `maxSteps` limit
|
|
225
|
-
- **WHEN** the step count reaches the limit
|
|
226
|
-
- **THEN** crawl SHALL finalize with status "limits_reached"
|
|
227
|
-
- **AND** include all artifacts collected up to that point
|
|
228
|
-
|
|
229
|
-
#### Scenario: Time limit is enforced
|
|
230
|
-
|
|
231
|
-
- **GIVEN** crawl has a `maxMinutes` limit
|
|
232
|
-
- **WHEN** elapsed time reaches the limit
|
|
233
|
-
- **THEN** crawl SHALL finalize with status "timeout"
|
|
234
|
-
- **AND** complete current action before stopping
|
|
235
|
-
- **AND** preserve all collected artifacts
|
|
236
|
-
|
|
237
|
-
#### Scenario: Page limit is enforced
|
|
238
|
-
|
|
239
|
-
- **GIVEN** crawl has a `maxPages` limit
|
|
240
|
-
- **WHEN** the unique page count reaches the limit
|
|
241
|
-
- **THEN** crawl SHALL stop discovering new pages
|
|
242
|
-
- **AND** continue actions on already-visited pages until goal or step limit
|
|
243
|
-
|
|
244
|
-
#### Scenario: Budget status is reported in progress
|
|
245
|
-
|
|
246
|
-
- **GIVEN** crawl is running with limits
|
|
247
|
-
- **WHEN** progress notification is emitted
|
|
248
|
-
- **THEN** it SHALL include budget status:
|
|
249
|
-
- `stepsUsed` / `maxSteps`
|
|
250
|
-
- `minutesElapsed` / `maxMinutes`
|
|
251
|
-
- `pagesDiscovered` / `maxPages`
|
|
252
|
-
|
|
253
|
-
### Requirement: Security Domain Enforcement
|
|
254
|
-
|
|
255
|
-
The system SHALL enforce domain allowlists for all navigation actions.
|
|
256
|
-
|
|
257
|
-
#### Scenario: Navigation to allowed domain succeeds
|
|
258
|
-
|
|
259
|
-
- **GIVEN** allowedDomains includes "example.com"
|
|
260
|
-
- **WHEN** Playwright action navigates to "https://example.com/page"
|
|
261
|
-
- **THEN** navigation SHALL be allowed
|
|
262
|
-
|
|
263
|
-
#### Scenario: Navigation to disallowed domain is blocked
|
|
264
|
-
|
|
265
|
-
- **GIVEN** allowedDomains includes only "example.com"
|
|
266
|
-
- **WHEN** sampling returns action to navigate to "https://malicious.com"
|
|
267
|
-
- **THEN** the action SHALL be rejected
|
|
268
|
-
- **AND** error logged with attempted URL
|
|
269
|
-
|
|
270
|
-
#### Scenario: Subdomain matching follows rules
|
|
271
|
-
|
|
272
|
-
- **GIVEN** allowedDomains includes "example.com"
|
|
273
|
-
- **WHEN** navigation to "sub.example.com" is attempted
|
|
274
|
-
- **THEN** it SHALL be allowed (subdomain of allowed domain)
|
|
275
|
-
|
|
276
|
-
#### Scenario: Link clicks are validated
|
|
277
|
-
|
|
278
|
-
- **GIVEN** a click action may navigate to external domain
|
|
279
|
-
- **WHEN** click is executed
|
|
280
|
-
- **THEN** resulting URL SHALL be checked post-navigation
|
|
281
|
-
- **AND** if disallowed, navigate back and report error
|
|
282
|
-
|
package/release.config.js
DELETED
package/src/config.test.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { loadConfig } from "./config.js";
|
|
3
|
-
|
|
4
|
-
describe("config", () => {
|
|
5
|
-
const originalEnv = process.env;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
// Reset environment before each test
|
|
9
|
-
process.env = { ...originalEnv };
|
|
10
|
-
delete process.env.TRANSPORT;
|
|
11
|
-
delete process.env.PORT;
|
|
12
|
-
delete process.env.LOG_LEVEL;
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
process.env = originalEnv;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe("defaults", () => {
|
|
20
|
-
it("uses stdio transport by default", () => {
|
|
21
|
-
const config = loadConfig();
|
|
22
|
-
expect(config.transport).toBe("stdio");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("uses port 3000 by default", () => {
|
|
26
|
-
const config = loadConfig();
|
|
27
|
-
expect(config.port).toBe(3000);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("uses info log level by default", () => {
|
|
31
|
-
const config = loadConfig();
|
|
32
|
-
expect(config.logLevel).toBe("info");
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe("transport", () => {
|
|
37
|
-
it("accepts stdio transport", () => {
|
|
38
|
-
process.env.TRANSPORT = "stdio";
|
|
39
|
-
const config = loadConfig();
|
|
40
|
-
expect(config.transport).toBe("stdio");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("accepts http transport", () => {
|
|
44
|
-
process.env.TRANSPORT = "http";
|
|
45
|
-
const config = loadConfig();
|
|
46
|
-
expect(config.transport).toBe("http");
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("rejects invalid transport", () => {
|
|
50
|
-
process.env.TRANSPORT = "invalid";
|
|
51
|
-
expect(() => loadConfig()).toThrow();
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe("port", () => {
|
|
56
|
-
it("accepts valid port number", () => {
|
|
57
|
-
process.env.PORT = "8080";
|
|
58
|
-
const config = loadConfig();
|
|
59
|
-
expect(config.port).toBe(8080);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("rejects invalid port", () => {
|
|
63
|
-
process.env.PORT = "invalid";
|
|
64
|
-
expect(() => loadConfig()).toThrow();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("rejects port below 1", () => {
|
|
68
|
-
process.env.PORT = "0";
|
|
69
|
-
expect(() => loadConfig()).toThrow();
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("rejects port above 65535", () => {
|
|
73
|
-
process.env.PORT = "70000";
|
|
74
|
-
expect(() => loadConfig()).toThrow();
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe("log level", () => {
|
|
79
|
-
it("accepts debug level", () => {
|
|
80
|
-
process.env.LOG_LEVEL = "debug";
|
|
81
|
-
const config = loadConfig();
|
|
82
|
-
expect(config.logLevel).toBe("debug");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("accepts error level", () => {
|
|
86
|
-
process.env.LOG_LEVEL = "error";
|
|
87
|
-
const config = loadConfig();
|
|
88
|
-
expect(config.logLevel).toBe("error");
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it("rejects invalid log level", () => {
|
|
92
|
-
process.env.LOG_LEVEL = "invalid";
|
|
93
|
-
expect(() => loadConfig()).toThrow();
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
});
|
package/src/config.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ConfigSchema, type Config } from "./schemas/config.js";
|
|
2
|
-
|
|
3
|
-
export function loadConfig(): Config {
|
|
4
|
-
const rawConfig = {
|
|
5
|
-
transport: process.env.TRANSPORT,
|
|
6
|
-
port: process.env.PORT,
|
|
7
|
-
logLevel: process.env.LOG_LEVEL,
|
|
8
|
-
// Webtest configuration
|
|
9
|
-
workspaceDir: process.env.WEBTEST_WORKSPACE_DIR,
|
|
10
|
-
playwrightMcpCommand: process.env.PLAYWRIGHT_MCP_COMMAND,
|
|
11
|
-
playwrightMcpArgs: process.env.PLAYWRIGHT_MCP_ARGS,
|
|
12
|
-
checkpointInterval: process.env.WEBTEST_CHECKPOINT_INTERVAL,
|
|
13
|
-
screenshotFormat: process.env.WEBTEST_SCREENSHOT_FORMAT,
|
|
14
|
-
screenshotQuality: process.env.WEBTEST_SCREENSHOT_QUALITY,
|
|
15
|
-
defaultMaxSteps: process.env.WEBTEST_DEFAULT_MAX_STEPS,
|
|
16
|
-
defaultMaxMinutes: process.env.WEBTEST_DEFAULT_MAX_MINUTES,
|
|
17
|
-
defaultMaxPages: process.env.WEBTEST_DEFAULT_MAX_PAGES,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const result = ConfigSchema.safeParse(rawConfig);
|
|
21
|
-
|
|
22
|
-
if (!result.success) {
|
|
23
|
-
const errors = result.error.issues
|
|
24
|
-
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
25
|
-
.join(", ");
|
|
26
|
-
throw new Error(`Invalid configuration: ${errors}`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return result.data;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type { Config };
|