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.
Files changed (238) hide show
  1. package/README.md +59 -40
  2. package/dist/config.js +8 -8
  3. package/dist/config.js.map +1 -1
  4. package/dist/logger.js +1 -1
  5. package/dist/logger.js.map +1 -1
  6. package/dist/prompts/index.d.ts +1 -1
  7. package/dist/prompts/index.d.ts.map +1 -1
  8. package/dist/prompts/index.js +21 -21
  9. package/dist/prompts/index.js.map +1 -1
  10. package/dist/prompts/templates/mcp/retest-crawl.md +7 -0
  11. package/{src/prompts/templates/mcp/webtest-discover-flows.md → dist/prompts/templates/mcp/retest-discover-flows.md} +1 -1
  12. package/{src/prompts/templates/mcp/webtest-discover.md → dist/prompts/templates/mcp/retest-discover.md} +2 -2
  13. package/dist/prompts/templates/mcp/retest-full-workflow.md +12 -0
  14. package/{src/prompts/templates/mcp/webtest-generate-tests.md → dist/prompts/templates/mcp/retest-generate-tests.md} +1 -1
  15. package/{src/prompts/templates/mcp/webtest-run-test.md → dist/prompts/templates/mcp/retest-run-test.md} +1 -1
  16. package/{src/prompts/templates/mcp/webtest-start.md → dist/prompts/templates/mcp/retest-start.md} +1 -1
  17. package/{src → dist}/prompts/templates/sampling/system-prefix.md +1 -1
  18. package/dist/resources/index.js +7 -7
  19. package/dist/resources/index.js.map +1 -1
  20. package/dist/schemas/config.js +2 -2
  21. package/dist/schemas/config.js.map +1 -1
  22. package/dist/security/index.js +1 -1
  23. package/dist/security/index.js.map +1 -1
  24. package/dist/server.js +3 -3
  25. package/dist/server.js.map +1 -1
  26. package/dist/test-utils/mock-context.js +22 -22
  27. package/dist/test-utils/mock-context.js.map +1 -1
  28. package/dist/tools/index.d.ts +1 -1
  29. package/dist/tools/index.d.ts.map +1 -1
  30. package/dist/tools/index.js +5 -5
  31. package/dist/tools/index.js.map +1 -1
  32. package/dist/tools/retest/crawl.d.ts.map +1 -0
  33. package/dist/tools/{webtest → retest}/crawl.js +7 -7
  34. package/dist/tools/retest/crawl.js.map +1 -0
  35. package/dist/tools/retest/discover-features.d.ts.map +1 -0
  36. package/dist/tools/{webtest → retest}/discover-features.js +6 -6
  37. package/dist/tools/retest/discover-features.js.map +1 -0
  38. package/dist/tools/retest/discover-flows.d.ts.map +1 -0
  39. package/dist/tools/{webtest → retest}/discover-flows.js +6 -6
  40. package/dist/tools/retest/discover-flows.js.map +1 -0
  41. package/dist/tools/retest/generate-tests.d.ts.map +1 -0
  42. package/dist/tools/{webtest → retest}/generate-tests.js +5 -5
  43. package/dist/tools/retest/generate-tests.js.map +1 -0
  44. package/dist/tools/retest/index.d.ts.map +1 -0
  45. package/dist/tools/retest/index.js.map +1 -0
  46. package/dist/tools/retest/run-test-case.d.ts.map +1 -0
  47. package/dist/tools/{webtest → retest}/run-test-case.js +3 -3
  48. package/dist/tools/retest/run-test-case.js.map +1 -0
  49. package/dist/tools/retest/schemas.d.ts.map +1 -0
  50. package/dist/tools/retest/schemas.js.map +1 -0
  51. package/dist/tools/retest/start-analysis.d.ts.map +1 -0
  52. package/dist/tools/{webtest → retest}/start-analysis.js +5 -5
  53. package/dist/tools/retest/start-analysis.js.map +1 -0
  54. package/dist/workspace/index.js +8 -8
  55. package/dist/workspace/index.js.map +1 -1
  56. package/dist/workspace/types.d.ts +2 -2
  57. package/dist/workspace/types.d.ts.map +1 -1
  58. package/package.json +6 -2
  59. package/.claude/commands/openspec/apply.md +0 -23
  60. package/.claude/commands/openspec/archive.md +0 -27
  61. package/.claude/commands/openspec/proposal.md +0 -28
  62. package/.gemini/commands/openspec/apply.toml +0 -21
  63. package/.gemini/commands/openspec/archive.toml +0 -25
  64. package/.gemini/commands/openspec/proposal.toml +0 -26
  65. package/.github/prompts/openspec-apply.prompt.md +0 -22
  66. package/.github/prompts/openspec-archive.prompt.md +0 -26
  67. package/.github/prompts/openspec-proposal.prompt.md +0 -27
  68. package/.github/workflows/release.yml +0 -33
  69. package/.kilocode/workflows/openspec-apply.md +0 -17
  70. package/.kilocode/workflows/openspec-archive.md +0 -21
  71. package/.kilocode/workflows/openspec-proposal.md +0 -22
  72. package/.mcp.json +0 -23
  73. package/.opencode/command/openspec-apply.md +0 -25
  74. package/.opencode/command/openspec-archive.md +0 -28
  75. package/.opencode/command/openspec-proposal.md +0 -30
  76. package/.roo/commands/openspec-apply.md +0 -20
  77. package/.roo/commands/openspec-archive.md +0 -24
  78. package/.roo/commands/openspec-proposal.md +0 -25
  79. package/.vscode/mcp.json +0 -23
  80. package/AGENTS.md +0 -18
  81. package/CLAUDE.md +0 -18
  82. package/dist/tools/webtest/crawl.d.ts.map +0 -1
  83. package/dist/tools/webtest/crawl.js.map +0 -1
  84. package/dist/tools/webtest/discover-features.d.ts.map +0 -1
  85. package/dist/tools/webtest/discover-features.js.map +0 -1
  86. package/dist/tools/webtest/discover-flows.d.ts.map +0 -1
  87. package/dist/tools/webtest/discover-flows.js.map +0 -1
  88. package/dist/tools/webtest/generate-tests.d.ts.map +0 -1
  89. package/dist/tools/webtest/generate-tests.js.map +0 -1
  90. package/dist/tools/webtest/index.d.ts.map +0 -1
  91. package/dist/tools/webtest/index.js.map +0 -1
  92. package/dist/tools/webtest/run-test-case.d.ts.map +0 -1
  93. package/dist/tools/webtest/run-test-case.js.map +0 -1
  94. package/dist/tools/webtest/schemas.d.ts.map +0 -1
  95. package/dist/tools/webtest/schemas.js.map +0 -1
  96. package/dist/tools/webtest/start-analysis.d.ts.map +0 -1
  97. package/dist/tools/webtest/start-analysis.js.map +0 -1
  98. package/openspec/AGENTS.md +0 -456
  99. package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/proposal.md +0 -33
  100. package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/specs/webtest-resources/spec.md +0 -27
  101. package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/specs/webtest-tools/spec.md +0 -304
  102. package/openspec/changes/archive/2025-12-18-add-hybrid-artifact-paths/tasks.md +0 -43
  103. package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/design.md +0 -209
  104. package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/proposal.md +0 -41
  105. package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/specs/mcp-server-core/spec.md +0 -183
  106. package/openspec/changes/archive/2025-12-18-add-mcp-server-foundation/tasks.md +0 -112
  107. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/design.md +0 -333
  108. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/proposal.md +0 -66
  109. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/mcp-server-core/spec.md +0 -129
  110. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-lifecycle/spec.md +0 -138
  111. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-logging/spec.md +0 -211
  112. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-prompts/spec.md +0 -157
  113. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-resources/spec.md +0 -213
  114. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-sampling/spec.md +0 -257
  115. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/specs/webtest-tools/spec.md +0 -501
  116. package/openspec/changes/archive/2025-12-18-add-webtest-orchestrator/tasks.md +0 -264
  117. package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/proposal.md +0 -24
  118. package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/specs/webtest-tools/spec.md +0 -80
  119. package/openspec/changes/archive/2025-12-18-allow-analysis-of-incomplete-crawls/tasks.md +0 -8
  120. package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/design.md +0 -90
  121. package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/proposal.md +0 -28
  122. package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/specs/webtest-sampling/spec.md +0 -90
  123. package/openspec/changes/archive/2025-12-18-fix-crawl-loop-stability/tasks.md +0 -33
  124. package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/design.md +0 -558
  125. package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/proposal.md +0 -119
  126. package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/specs/webtest-resources/spec.md +0 -109
  127. package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/specs/webtest-tools/spec.md +0 -121
  128. package/openspec/changes/archive/2025-12-18-use-markdown-artifacts/tasks.md +0 -133
  129. package/openspec/changes/extract-prompts-to-markdown/design.md +0 -86
  130. package/openspec/changes/extract-prompts-to-markdown/proposal.md +0 -50
  131. package/openspec/changes/extract-prompts-to-markdown/specs/webtest-prompts/spec.md +0 -74
  132. package/openspec/changes/extract-prompts-to-markdown/tasks.md +0 -40
  133. package/openspec/changes/refactor-webtest-naming/design.md +0 -95
  134. package/openspec/changes/refactor-webtest-naming/proposal.md +0 -66
  135. package/openspec/changes/refactor-webtest-naming/specs/webtest-prompts/spec.md +0 -79
  136. package/openspec/changes/refactor-webtest-naming/specs/webtest-resources/spec.md +0 -80
  137. package/openspec/changes/refactor-webtest-naming/specs/webtest-sampling/spec.md +0 -122
  138. package/openspec/changes/refactor-webtest-naming/specs/webtest-tools/spec.md +0 -113
  139. package/openspec/changes/refactor-webtest-naming/tasks.md +0 -119
  140. package/openspec/changes/rename-package-to-retest/proposal.md +0 -52
  141. package/openspec/changes/rename-package-to-retest/specs/mcp-server-core/spec.md +0 -53
  142. package/openspec/changes/rename-package-to-retest/specs/retest-lifecycle/spec.md +0 -68
  143. package/openspec/changes/rename-package-to-retest/specs/retest-logging/spec.md +0 -35
  144. package/openspec/changes/rename-package-to-retest/specs/retest-prompts/spec.md +0 -159
  145. package/openspec/changes/rename-package-to-retest/specs/retest-resources/spec.md +0 -251
  146. package/openspec/changes/rename-package-to-retest/specs/retest-sampling/spec.md +0 -99
  147. package/openspec/changes/rename-package-to-retest/specs/retest-tools/spec.md +0 -295
  148. package/openspec/changes/rename-package-to-retest/tasks.md +0 -71
  149. package/openspec/project.md +0 -31
  150. package/openspec/specs/mcp-server-core/spec.md +0 -178
  151. package/openspec/specs/webtest-lifecycle/spec.md +0 -136
  152. package/openspec/specs/webtest-logging/spec.md +0 -209
  153. package/openspec/specs/webtest-prompts/spec.md +0 -155
  154. package/openspec/specs/webtest-resources/spec.md +0 -248
  155. package/openspec/specs/webtest-sampling/spec.md +0 -344
  156. package/openspec/specs/webtest-tools/spec.md +0 -282
  157. package/release.config.js +0 -9
  158. package/src/config.test.ts +0 -96
  159. package/src/config.ts +0 -32
  160. package/src/elicitation/index.test.ts +0 -399
  161. package/src/elicitation/index.ts +0 -171
  162. package/src/elicitation/types.ts +0 -68
  163. package/src/index.ts +0 -83
  164. package/src/lifecycle/index.test.ts +0 -260
  165. package/src/lifecycle/index.ts +0 -101
  166. package/src/logger.redaction.test.ts +0 -322
  167. package/src/logger.test.ts +0 -123
  168. package/src/logger.ts +0 -229
  169. package/src/playwright-client/index.ts +0 -392
  170. package/src/playwright-client/types.ts +0 -99
  171. package/src/progress/index.test.ts +0 -327
  172. package/src/progress/index.ts +0 -170
  173. package/src/progress/types.ts +0 -25
  174. package/src/prompts/index.test.ts +0 -451
  175. package/src/prompts/index.ts +0 -246
  176. package/src/prompts/loader.test.ts +0 -100
  177. package/src/prompts/loader.ts +0 -59
  178. package/src/prompts/templates/mcp/webtest-crawl.md +0 -7
  179. package/src/prompts/templates/mcp/webtest-full-workflow.md +0 -12
  180. package/src/resources/index.ts +0 -250
  181. package/src/resources/subscriptions.ts +0 -37
  182. package/src/sampling/index.test.ts +0 -414
  183. package/src/sampling/index.ts +0 -286
  184. package/src/sampling/prompts.ts +0 -194
  185. package/src/sampling/types.ts +0 -60
  186. package/src/schemas/config.ts +0 -39
  187. package/src/security/index.test.ts +0 -441
  188. package/src/security/index.ts +0 -361
  189. package/src/security/security-scenarios.test.ts +0 -468
  190. package/src/server.ts +0 -211
  191. package/src/test-utils/index.ts +0 -6
  192. package/src/test-utils/mock-context.ts +0 -426
  193. package/src/test-utils/mock-playwright-client.ts +0 -422
  194. package/src/tools/index.ts +0 -11
  195. package/src/tools/webtest/crawl.test.ts +0 -834
  196. package/src/tools/webtest/crawl.ts +0 -901
  197. package/src/tools/webtest/discover-features.ts +0 -412
  198. package/src/tools/webtest/discover-flows.ts +0 -408
  199. package/src/tools/webtest/generate-tests.test.ts +0 -532
  200. package/src/tools/webtest/generate-tests.ts +0 -425
  201. package/src/tools/webtest/index.ts +0 -7
  202. package/src/tools/webtest/integration.test.ts +0 -536
  203. package/src/tools/webtest/run-test-case.test.ts +0 -659
  204. package/src/tools/webtest/run-test-case.ts +0 -508
  205. package/src/tools/webtest/schemas.ts +0 -201
  206. package/src/tools/webtest/start-analysis.test.ts +0 -151
  207. package/src/tools/webtest/start-analysis.ts +0 -158
  208. package/src/transports/http.ts +0 -19
  209. package/src/transports/index.ts +0 -30
  210. package/src/transports/stdio.ts +0 -7
  211. package/src/types/capabilities.test.ts +0 -193
  212. package/src/types/capabilities.ts +0 -50
  213. package/src/types/context.ts +0 -21
  214. package/src/types/tool.ts +0 -11
  215. package/src/workspace/index.ts +0 -945
  216. package/src/workspace/markdown.ts +0 -272
  217. package/src/workspace/types.ts +0 -186
  218. package/tests/integration/server.test.ts +0 -89
  219. package/tests/integration/tools.test.ts +0 -99
  220. package/tsconfig.json +0 -20
  221. package/vitest.config.ts +0 -9
  222. package/vitest.integration.config.ts +0 -10
  223. /package/{src → dist}/prompts/templates/sampling/crawl-action.md +0 -0
  224. /package/{src → dist}/prompts/templates/sampling/feature-discovery.md +0 -0
  225. /package/{src → dist}/prompts/templates/sampling/flow-discovery.md +0 -0
  226. /package/{src → dist}/prompts/templates/sampling/page-content-wrapper.md +0 -0
  227. /package/{src → dist}/prompts/templates/sampling/test-evaluation.md +0 -0
  228. /package/{src → dist}/prompts/templates/sampling/test-generation.md +0 -0
  229. /package/dist/tools/{webtest → retest}/crawl.d.ts +0 -0
  230. /package/dist/tools/{webtest → retest}/discover-features.d.ts +0 -0
  231. /package/dist/tools/{webtest → retest}/discover-flows.d.ts +0 -0
  232. /package/dist/tools/{webtest → retest}/generate-tests.d.ts +0 -0
  233. /package/dist/tools/{webtest → retest}/index.d.ts +0 -0
  234. /package/dist/tools/{webtest → retest}/index.js +0 -0
  235. /package/dist/tools/{webtest → retest}/run-test-case.d.ts +0 -0
  236. /package/dist/tools/{webtest → retest}/schemas.d.ts +0 -0
  237. /package/dist/tools/{webtest → retest}/schemas.js +0 -0
  238. /package/dist/tools/{webtest → retest}/start-analysis.d.ts +0 -0
@@ -1,272 +0,0 @@
1
- import matter from "gray-matter";
2
- import { readFile, writeFile } from "node:fs/promises";
3
-
4
- /**
5
- * Write a markdown file with YAML frontmatter
6
- */
7
- export async function writeMarkdownWithFrontmatter<T extends object>(
8
- filePath: string,
9
- frontmatter: T,
10
- content: string
11
- ): Promise<void> {
12
- const file = matter.stringify(content, frontmatter as object);
13
- await writeFile(filePath, file, "utf-8");
14
- }
15
-
16
- /**
17
- * Read YAML frontmatter from a markdown file
18
- */
19
- export async function readMarkdownFrontmatter<T>(filePath: string): Promise<T> {
20
- const fileContent = await readFile(filePath, "utf-8");
21
- const { data } = matter(fileContent);
22
- return data as T;
23
- }
24
-
25
- /**
26
- * Read both frontmatter and content from a markdown file
27
- */
28
- export async function readMarkdownFile<T>(
29
- filePath: string
30
- ): Promise<{ data: T; content: string }> {
31
- const fileContent = await readFile(filePath, "utf-8");
32
- const { data, content } = matter(fileContent);
33
- return { data: data as T, content };
34
- }
35
-
36
- /**
37
- * Format an accessibility tree snapshot as a human-readable tree
38
- */
39
- export function formatAccessibilityTree(
40
- snapshot: AccessibilityNode,
41
- indent: number = 0
42
- ): string {
43
- const lines: string[] = [];
44
- const prefix = indent === 0 ? "" : "│ ".repeat(indent - 1) + "├── ";
45
-
46
- // Format the node
47
- let nodeStr = snapshot.role || "unknown";
48
- if (snapshot.name) {
49
- nodeStr += ` "${snapshot.name}"`;
50
- }
51
- if (snapshot.ref) {
52
- nodeStr += ` [ref: ${snapshot.ref}]`;
53
- }
54
- if (snapshot.level) {
55
- nodeStr += ` (h${snapshot.level})`;
56
- }
57
- if (snapshot.checked !== undefined) {
58
- nodeStr += snapshot.checked ? " [checked]" : " [unchecked]";
59
- }
60
- if (snapshot.selected !== undefined) {
61
- nodeStr += snapshot.selected ? " [selected]" : "";
62
- }
63
- if (snapshot.disabled) {
64
- nodeStr += " [disabled]";
65
- }
66
- if (snapshot.value) {
67
- nodeStr += ` = "${truncate(snapshot.value, 30)}"`;
68
- }
69
-
70
- lines.push(prefix + nodeStr);
71
-
72
- // Format children
73
- if (snapshot.children && snapshot.children.length > 0) {
74
- for (let i = 0; i < snapshot.children.length; i++) {
75
- const child = snapshot.children[i];
76
- const isLast = i === snapshot.children.length - 1;
77
- const childPrefix = indent === 0 ? "" : "│ ".repeat(indent - 1) + (isLast ? "└── " : "├── ");
78
- lines.push(
79
- ...formatAccessibilityTreeInternal(child, indent + 1, isLast).split("\n")
80
- );
81
- }
82
- }
83
-
84
- return lines.join("\n");
85
- }
86
-
87
- function formatAccessibilityTreeInternal(
88
- snapshot: AccessibilityNode,
89
- indent: number,
90
- isLast: boolean
91
- ): string {
92
- const lines: string[] = [];
93
- const connector = isLast ? "└── " : "├── ";
94
- const childIndent = isLast ? " " : "│ ";
95
- const prefix = "│ ".repeat(Math.max(0, indent - 1)) + connector;
96
-
97
- // Format the node
98
- let nodeStr = snapshot.role || "unknown";
99
- if (snapshot.name) {
100
- nodeStr += ` "${snapshot.name}"`;
101
- }
102
- if (snapshot.ref) {
103
- nodeStr += ` [ref: ${snapshot.ref}]`;
104
- }
105
- if (snapshot.level) {
106
- nodeStr += ` (h${snapshot.level})`;
107
- }
108
- if (snapshot.checked !== undefined) {
109
- nodeStr += snapshot.checked ? " [checked]" : " [unchecked]";
110
- }
111
- if (snapshot.selected !== undefined) {
112
- nodeStr += snapshot.selected ? " [selected]" : "";
113
- }
114
- if (snapshot.disabled) {
115
- nodeStr += " [disabled]";
116
- }
117
- if (snapshot.value) {
118
- nodeStr += ` = "${truncate(snapshot.value, 30)}"`;
119
- }
120
-
121
- lines.push(prefix + nodeStr);
122
-
123
- // Format children
124
- if (snapshot.children && snapshot.children.length > 0) {
125
- for (let i = 0; i < snapshot.children.length; i++) {
126
- const child = snapshot.children[i];
127
- const childIsLast = i === snapshot.children.length - 1;
128
- const baseIndent = "│ ".repeat(Math.max(0, indent - 1)) + childIndent;
129
- lines.push(
130
- formatAccessibilityTreeWithBase(child, baseIndent, childIsLast)
131
- );
132
- }
133
- }
134
-
135
- return lines.join("\n");
136
- }
137
-
138
- function formatAccessibilityTreeWithBase(
139
- snapshot: AccessibilityNode,
140
- baseIndent: string,
141
- isLast: boolean
142
- ): string {
143
- const lines: string[] = [];
144
- const connector = isLast ? "└── " : "├── ";
145
- const childIndent = isLast ? " " : "│ ";
146
-
147
- // Format the node
148
- let nodeStr = snapshot.role || "unknown";
149
- if (snapshot.name) {
150
- nodeStr += ` "${snapshot.name}"`;
151
- }
152
- if (snapshot.ref) {
153
- nodeStr += ` [ref: ${snapshot.ref}]`;
154
- }
155
- if (snapshot.level) {
156
- nodeStr += ` (h${snapshot.level})`;
157
- }
158
- if (snapshot.checked !== undefined) {
159
- nodeStr += snapshot.checked ? " [checked]" : " [unchecked]";
160
- }
161
- if (snapshot.selected !== undefined) {
162
- nodeStr += snapshot.selected ? " [selected]" : "";
163
- }
164
- if (snapshot.disabled) {
165
- nodeStr += " [disabled]";
166
- }
167
- if (snapshot.value) {
168
- nodeStr += ` = "${truncate(snapshot.value, 30)}"`;
169
- }
170
-
171
- lines.push(baseIndent + connector + nodeStr);
172
-
173
- // Format children
174
- if (snapshot.children && snapshot.children.length > 0) {
175
- for (let i = 0; i < snapshot.children.length; i++) {
176
- const child = snapshot.children[i];
177
- const childIsLast = i === snapshot.children.length - 1;
178
- lines.push(
179
- formatAccessibilityTreeWithBase(child, baseIndent + childIndent, childIsLast)
180
- );
181
- }
182
- }
183
-
184
- return lines.join("\n");
185
- }
186
-
187
- /**
188
- * Extract interactive elements from an accessibility snapshot
189
- */
190
- export function extractInteractiveElements(
191
- snapshot: AccessibilityNode
192
- ): Array<{ element: string; type: string; ref?: string }> {
193
- const elements: Array<{ element: string; type: string; ref?: string }> = [];
194
- const interactiveRoles = [
195
- "link",
196
- "button",
197
- "textbox",
198
- "checkbox",
199
- "radio",
200
- "combobox",
201
- "menuitem",
202
- "tab",
203
- "slider",
204
- "spinbutton",
205
- "searchbox",
206
- ];
207
-
208
- function traverse(node: AccessibilityNode): void {
209
- if (node.role && interactiveRoles.includes(node.role)) {
210
- elements.push({
211
- element: node.name || node.role,
212
- type: node.role,
213
- ref: node.ref,
214
- });
215
- }
216
- if (node.children) {
217
- for (const child of node.children) {
218
- traverse(child);
219
- }
220
- }
221
- }
222
-
223
- traverse(snapshot);
224
- return elements;
225
- }
226
-
227
- function truncate(str: string, maxLength: number): string {
228
- if (str.length <= maxLength) return str;
229
- return str.slice(0, maxLength - 3) + "...";
230
- }
231
-
232
- /**
233
- * Format a date for human-readable display
234
- */
235
- export function formatDate(isoDate: string): string {
236
- const date = new Date(isoDate);
237
- return date.toLocaleString("en-US", {
238
- month: "long",
239
- day: "numeric",
240
- year: "numeric",
241
- hour: "numeric",
242
- minute: "2-digit",
243
- hour12: true,
244
- });
245
- }
246
-
247
- /**
248
- * Format a short time for display
249
- */
250
- export function formatTime(isoDate: string): string {
251
- const date = new Date(isoDate);
252
- return date.toLocaleTimeString("en-US", {
253
- hour: "numeric",
254
- minute: "2-digit",
255
- hour12: true,
256
- });
257
- }
258
-
259
- /**
260
- * Type definition for accessibility tree nodes
261
- */
262
- export interface AccessibilityNode {
263
- role?: string;
264
- name?: string;
265
- ref?: string;
266
- level?: number;
267
- checked?: boolean;
268
- selected?: boolean;
269
- disabled?: boolean;
270
- value?: string;
271
- children?: AccessibilityNode[];
272
- }
@@ -1,186 +0,0 @@
1
- export interface WorkspaceIndex {
2
- analysisId: string;
3
- url: string;
4
- domain: string;
5
- focus?: string;
6
- createdAt: string;
7
- updatedAt: string;
8
- status: "active" | "completed" | "failed";
9
- limits: {
10
- maxSteps: number;
11
- maxMinutes: number;
12
- maxPages: number;
13
- };
14
- crawls: CrawlReference[];
15
- /** Discovered features from webtest_discover_features */
16
- features?: FeaturesReference;
17
- /** Discovered flows per feature from webtest_discover_flows */
18
- featureFlows?: FlowsReference[];
19
- tests?: TestsReference;
20
- runs: TestRunReference[];
21
- }
22
-
23
- export interface CrawlReference {
24
- crawlId: string;
25
- goal: string;
26
- status: "in_progress" | "completed" | "failed" | "cancelled";
27
- startedAt: string;
28
- completedAt?: string;
29
- pagesVisited: number;
30
- stepsExecuted: number;
31
- }
32
-
33
- export interface Feature {
34
- slug: string;
35
- name: string;
36
- description: string;
37
- entities: string[];
38
- entryPoints: string[];
39
- }
40
-
41
- export interface FeaturesReference {
42
- createdAt: string;
43
- featuresFilePath: string;
44
- featuresUri: string;
45
- featureCount: number;
46
- features: Feature[];
47
- }
48
-
49
- export interface FlowsReference {
50
- featureSlug: string;
51
- createdAt: string;
52
- flowsFilePath: string;
53
- flowsUri: string;
54
- flowCount: number;
55
- }
56
-
57
- export interface TestsReference {
58
- createdAt: string;
59
- testsFilePath: string;
60
- testsUri: string;
61
- testCount: number;
62
- }
63
-
64
- export interface TestRunReference {
65
- runId: string;
66
- testCaseId: string;
67
- status: "in_progress" | "passed" | "failed" | "error";
68
- startedAt: string;
69
- completedAt?: string;
70
- }
71
-
72
- export interface CrawlIndex {
73
- crawlId: string;
74
- analysisId: string;
75
- goal: string;
76
- strategy: string;
77
- status: "in_progress" | "completed" | "failed" | "cancelled";
78
- startedAt: string;
79
- completedAt?: string;
80
- budget: {
81
- maxSteps: number;
82
- maxMinutes: number;
83
- maxPages: number;
84
- stepsUsed: number;
85
- pagesVisited: number;
86
- };
87
- pages: PageReference[];
88
- actionHistory: ActionRecord[];
89
- checkpoint?: CrawlCheckpoint;
90
- loopDetection: {
91
- domSignatures: Record<string, number>;
92
- urlVisits: Record<string, number>;
93
- recentActions: string[];
94
- };
95
- }
96
-
97
- export interface PageReference {
98
- pageId: string;
99
- url: string;
100
- title: string;
101
- capturedAt: string;
102
- snapshotFilePath: string;
103
- snapshotUri: string;
104
- screenshotFilePath: string;
105
- screenshotUri: string;
106
- domFilePath: string;
107
- domUri: string;
108
- }
109
-
110
- export interface ActionRecord {
111
- step: number;
112
- timestamp: string;
113
- tool: string;
114
- args: Record<string, unknown>;
115
- result: "success" | "error";
116
- reasoning?: string;
117
- error?: string;
118
- }
119
-
120
- export interface CrawlCheckpoint {
121
- step: number;
122
- timestamp: string;
123
- visitedUrls: string[];
124
- currentUrl: string;
125
- goalProgress: string;
126
- canResume: boolean;
127
- /** Start URL for navigation guard (blocks return to start after initial steps) */
128
- startUrl?: string;
129
- /** Preserved loop detection state for context continuity across resume */
130
- loopDetection?: {
131
- /** DOM signature visit counts as [signature, count] entries */
132
- domSignatures: Array<[string, number]>;
133
- /** URL visit counts as [url, count] entries */
134
- urlVisits: Array<[string, number]>;
135
- /** Recent action keys for repeat detection */
136
- recentActions: string[];
137
- };
138
- }
139
-
140
- export interface TestCase {
141
- id: string;
142
- name: string;
143
- purpose: string;
144
- category: "happy_path" | "edge_case" | "error_handling" | "boundary";
145
- preconditions: string[];
146
- steps: TestStep[];
147
- expectedOutcomes: string[];
148
- tags?: string[];
149
- }
150
-
151
- export interface TestStep {
152
- stepNumber: number;
153
- action: string;
154
- target?: string;
155
- value?: string;
156
- expected?: string;
157
- /** Playwright MCP element description */
158
- element?: string;
159
- /** Playwright MCP accessibility snapshot ref */
160
- ref?: string;
161
- }
162
-
163
- export interface TestRunIndex {
164
- runId: string;
165
- analysisId: string;
166
- testCaseId: string;
167
- testName: string;
168
- status: "in_progress" | "passed" | "failed" | "error";
169
- startedAt: string;
170
- completedAt?: string;
171
- steps: TestStepResult[];
172
- }
173
-
174
- export interface TestStepResult {
175
- stepNumber: number;
176
- status: "passed" | "failed" | "error" | "skipped";
177
- executedAt: string;
178
- evidence: {
179
- screenshotFilePath?: string;
180
- screenshotUri?: string;
181
- snapshotFilePath?: string;
182
- snapshotUri?: string;
183
- };
184
- actualResult?: string;
185
- errorMessage?: string;
186
- }
@@ -1,89 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
- import { spawn, type ChildProcess } from "node:child_process";
3
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5
- import { fileURLToPath } from "node:url";
6
- import { dirname, join } from "node:path";
7
-
8
- const __dirname = dirname(fileURLToPath(import.meta.url));
9
- const serverPath = join(__dirname, "../../src/index.ts");
10
-
11
- describe("MCP Server Integration", () => {
12
- let client: Client;
13
- let transport: StdioClientTransport;
14
- let serverProcess: ChildProcess;
15
-
16
- beforeAll(async () => {
17
- // Spawn the server using tsx
18
- serverProcess = spawn("npx", ["tsx", serverPath], {
19
- env: {
20
- ...process.env,
21
- TRANSPORT: "stdio",
22
- LOG_LEVEL: "error", // Minimize log noise during tests
23
- },
24
- stdio: ["pipe", "pipe", "pipe"],
25
- });
26
-
27
- // Create transport connected to server's stdin/stdout
28
- transport = new StdioClientTransport({
29
- command: "npx",
30
- args: ["tsx", serverPath],
31
- env: {
32
- ...process.env,
33
- TRANSPORT: "stdio",
34
- LOG_LEVEL: "error",
35
- },
36
- });
37
-
38
- // Create and connect client
39
- client = new Client({
40
- name: "test-client",
41
- version: "1.0.0",
42
- });
43
-
44
- await client.connect(transport);
45
- }, 15000);
46
-
47
- afterAll(async () => {
48
- await client.close();
49
- serverProcess?.kill();
50
- });
51
-
52
- describe("server identification", () => {
53
- it("reports correct server name", async () => {
54
- const info = client.getServerVersion();
55
- expect(info?.name).toBe("testing-mcp");
56
- });
57
-
58
- it("reports server version", async () => {
59
- const info = client.getServerVersion();
60
- expect(info?.version).toBeDefined();
61
- });
62
- });
63
-
64
- describe("tool discovery", () => {
65
- it("lists available tools", async () => {
66
- const result = await client.listTools();
67
- expect(result.tools).toBeDefined();
68
- expect(result.tools.length).toBeGreaterThan(0);
69
- });
70
-
71
- it("includes hello tool", async () => {
72
- const result = await client.listTools();
73
- const helloTool = result.tools.find((t) => t.name === "hello");
74
- expect(helloTool).toBeDefined();
75
- });
76
-
77
- it("hello tool has description", async () => {
78
- const result = await client.listTools();
79
- const helloTool = result.tools.find((t) => t.name === "hello");
80
- expect(helloTool?.description).toBeTruthy();
81
- });
82
-
83
- it("hello tool has input schema", async () => {
84
- const result = await client.listTools();
85
- const helloTool = result.tools.find((t) => t.name === "hello");
86
- expect(helloTool?.inputSchema).toBeDefined();
87
- });
88
- });
89
- });
@@ -1,99 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
- import { fileURLToPath } from "node:url";
5
- import { dirname, join } from "node:path";
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const serverPath = join(__dirname, "../../src/index.ts");
9
-
10
- describe("Tool Execution Integration", () => {
11
- let client: Client;
12
- let transport: StdioClientTransport;
13
-
14
- beforeAll(async () => {
15
- transport = new StdioClientTransport({
16
- command: "npx",
17
- args: ["tsx", serverPath],
18
- env: {
19
- ...process.env,
20
- TRANSPORT: "stdio",
21
- LOG_LEVEL: "error",
22
- },
23
- });
24
-
25
- client = new Client({
26
- name: "test-client",
27
- version: "1.0.0",
28
- });
29
-
30
- await client.connect(transport);
31
- }, 15000);
32
-
33
- afterAll(async () => {
34
- await client.close();
35
- });
36
-
37
- describe("hello tool", () => {
38
- it("returns greeting with provided name", async () => {
39
- const result = await client.callTool({
40
- name: "hello",
41
- arguments: { name: "World" },
42
- });
43
-
44
- expect(result.content).toBeDefined();
45
- expect(result.content.length).toBeGreaterThan(0);
46
-
47
- const textContent = result.content.find(
48
- (c): c is { type: "text"; text: string } => c.type === "text"
49
- );
50
- expect(textContent?.text).toBe("Hello, World!");
51
- });
52
-
53
- it("works with different names", async () => {
54
- const result = await client.callTool({
55
- name: "hello",
56
- arguments: { name: "Alice" },
57
- });
58
-
59
- const textContent = result.content.find(
60
- (c): c is { type: "text"; text: string } => c.type === "text"
61
- );
62
- expect(textContent?.text).toBe("Hello, Alice!");
63
- });
64
-
65
- it("handles special characters in name", async () => {
66
- const result = await client.callTool({
67
- name: "hello",
68
- arguments: { name: "Bob & Jane" },
69
- });
70
-
71
- const textContent = result.content.find(
72
- (c): c is { type: "text"; text: string } => c.type === "text"
73
- );
74
- expect(textContent?.text).toBe("Hello, Bob & Jane!");
75
- });
76
- });
77
-
78
- describe("error handling", () => {
79
- it("returns error for missing required argument", async () => {
80
- const result = await client.callTool({
81
- name: "hello",
82
- arguments: {},
83
- });
84
-
85
- // SDK validation should reject this
86
- expect(result.isError).toBe(true);
87
- });
88
-
89
- it("returns error for invalid argument type", async () => {
90
- const result = await client.callTool({
91
- name: "hello",
92
- // @ts-expect-error - intentionally passing wrong type
93
- arguments: { name: 123 },
94
- });
95
-
96
- expect(result.isError).toBe(true);
97
- });
98
- });
99
- });
package/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": ["ES2022"],
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true,
12
- "forceConsistentCasingInFileNames": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- "sourceMap": true,
16
- "resolveJsonModule": true
17
- },
18
- "include": ["src/**/*"],
19
- "exclude": ["node_modules", "dist", "**/*.test.ts"]
20
- }
package/vitest.config.ts DELETED
@@ -1,9 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- include: ["src/**/*.test.ts"],
6
- environment: "node",
7
- globals: false,
8
- },
9
- });
@@ -1,10 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- include: ["tests/integration/**/*.test.ts"],
6
- environment: "node",
7
- globals: false,
8
- testTimeout: 10000,
9
- },
10
- });
File without changes