opengstack 0.13.10 → 0.14.2

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 (189) hide show
  1. package/AGENTS.md +4 -4
  2. package/CLAUDE.md +127 -110
  3. package/README.md +10 -5
  4. package/SKILL.md +500 -70
  5. package/bin/opengstack.js +69 -69
  6. package/{skills/land-and-deploy/SKILL.md → commands/autoplan.md} +7 -25
  7. package/{skills/benchmark/SKILL.md → commands/benchmark.md} +84 -108
  8. package/{skills/browse/SKILL.md → commands/browse.md} +60 -81
  9. package/{skills/ship/SKILL.md → commands/canary.md} +7 -27
  10. package/{skills/careful/SKILL.md → commands/careful.md} +2 -22
  11. package/{skills/canary/SKILL.md → commands/codex.md} +7 -26
  12. package/{skills/connect-chrome/SKILL.md → commands/connect-chrome.md} +7 -24
  13. package/commands/cso.md +70 -0
  14. package/commands/design-consultation.md +70 -0
  15. package/commands/design-review.md +70 -0
  16. package/commands/design-shotgun.md +70 -0
  17. package/commands/document-release.md +70 -0
  18. package/{skills/freeze/SKILL.md → commands/freeze.md} +3 -29
  19. package/{skills/guard/SKILL.md → commands/guard.md} +4 -35
  20. package/commands/investigate.md +70 -0
  21. package/commands/land-and-deploy.md +70 -0
  22. package/commands/office-hours.md +70 -0
  23. package/{skills/gstack-upgrade/SKILL.md → commands/opengstack-upgrade.md} +64 -79
  24. package/commands/plan-ceo-review.md +70 -0
  25. package/commands/plan-design-review.md +70 -0
  26. package/commands/plan-eng-review.md +70 -0
  27. package/commands/qa-only.md +70 -0
  28. package/commands/qa.md +70 -0
  29. package/commands/retro.md +70 -0
  30. package/commands/review.md +70 -0
  31. package/{skills/setup-browser-cookies/SKILL.md → commands/setup-browser-cookies.md} +22 -40
  32. package/commands/setup-deploy.md +70 -0
  33. package/commands/ship.md +70 -0
  34. package/commands/unfreeze.md +25 -0
  35. package/docs/designs/CHROME_VS_CHROMIUM_EXPLORATION.md +9 -9
  36. package/docs/designs/CONDUCTOR_CHROME_SIDEBAR_INTEGRATION.md +2 -2
  37. package/docs/designs/CONDUCTOR_SESSION_API.md +16 -16
  38. package/docs/designs/DESIGN_SHOTGUN.md +74 -74
  39. package/docs/designs/DESIGN_TOOLS_V1.md +111 -111
  40. package/docs/skills.md +483 -202
  41. package/package.json +42 -43
  42. package/scripts/analytics.ts +188 -0
  43. package/scripts/dev-skill.ts +83 -0
  44. package/scripts/discover-skills.ts +39 -0
  45. package/scripts/eval-compare.ts +97 -0
  46. package/scripts/eval-list.ts +117 -0
  47. package/scripts/eval-select.ts +86 -0
  48. package/scripts/eval-summary.ts +188 -0
  49. package/scripts/eval-watch.ts +172 -0
  50. package/scripts/gen-skill-docs.ts +473 -0
  51. package/scripts/resolvers/browse.ts +129 -0
  52. package/scripts/resolvers/codex-helpers.ts +133 -0
  53. package/scripts/resolvers/composition.ts +48 -0
  54. package/scripts/resolvers/confidence.ts +37 -0
  55. package/scripts/resolvers/constants.ts +50 -0
  56. package/scripts/resolvers/design.ts +950 -0
  57. package/scripts/resolvers/index.ts +59 -0
  58. package/scripts/resolvers/learnings.ts +96 -0
  59. package/scripts/resolvers/preamble.ts +505 -0
  60. package/scripts/resolvers/review.ts +884 -0
  61. package/scripts/resolvers/testing.ts +573 -0
  62. package/scripts/resolvers/types.ts +45 -0
  63. package/scripts/resolvers/utility.ts +421 -0
  64. package/scripts/skill-check.ts +190 -0
  65. package/scripts/cleanup.py +0 -100
  66. package/scripts/filter-skills.sh +0 -114
  67. package/scripts/filter_skills.py +0 -164
  68. package/scripts/install-skills.js +0 -60
  69. package/skills/autoplan/SKILL.md +0 -96
  70. package/skills/autoplan/SKILL.md.tmpl +0 -694
  71. package/skills/benchmark/SKILL.md.tmpl +0 -222
  72. package/skills/browse/SKILL.md.tmpl +0 -131
  73. package/skills/browse/bin/find-browse +0 -21
  74. package/skills/browse/bin/remote-slug +0 -14
  75. package/skills/browse/scripts/build-node-server.sh +0 -48
  76. package/skills/browse/src/activity.ts +0 -208
  77. package/skills/browse/src/browser-manager.ts +0 -959
  78. package/skills/browse/src/buffers.ts +0 -137
  79. package/skills/browse/src/bun-polyfill.cjs +0 -109
  80. package/skills/browse/src/cli.ts +0 -678
  81. package/skills/browse/src/commands.ts +0 -128
  82. package/skills/browse/src/config.ts +0 -150
  83. package/skills/browse/src/cookie-import-browser.ts +0 -625
  84. package/skills/browse/src/cookie-picker-routes.ts +0 -230
  85. package/skills/browse/src/cookie-picker-ui.ts +0 -688
  86. package/skills/browse/src/find-browse.ts +0 -61
  87. package/skills/browse/src/meta-commands.ts +0 -550
  88. package/skills/browse/src/platform.ts +0 -17
  89. package/skills/browse/src/read-commands.ts +0 -358
  90. package/skills/browse/src/server.ts +0 -1192
  91. package/skills/browse/src/sidebar-agent.ts +0 -280
  92. package/skills/browse/src/sidebar-utils.ts +0 -21
  93. package/skills/browse/src/snapshot.ts +0 -407
  94. package/skills/browse/src/url-validation.ts +0 -95
  95. package/skills/browse/src/write-commands.ts +0 -364
  96. package/skills/browse/test/activity.test.ts +0 -120
  97. package/skills/browse/test/adversarial-security.test.ts +0 -32
  98. package/skills/browse/test/browser-manager-unit.test.ts +0 -17
  99. package/skills/browse/test/bun-polyfill.test.ts +0 -72
  100. package/skills/browse/test/commands.test.ts +0 -2075
  101. package/skills/browse/test/compare-board.test.ts +0 -342
  102. package/skills/browse/test/config.test.ts +0 -316
  103. package/skills/browse/test/cookie-import-browser.test.ts +0 -519
  104. package/skills/browse/test/cookie-picker-routes.test.ts +0 -260
  105. package/skills/browse/test/file-drop.test.ts +0 -271
  106. package/skills/browse/test/find-browse.test.ts +0 -50
  107. package/skills/browse/test/findport.test.ts +0 -191
  108. package/skills/browse/test/fixtures/basic.html +0 -33
  109. package/skills/browse/test/fixtures/cursor-interactive.html +0 -22
  110. package/skills/browse/test/fixtures/dialog.html +0 -15
  111. package/skills/browse/test/fixtures/empty.html +0 -2
  112. package/skills/browse/test/fixtures/forms.html +0 -55
  113. package/skills/browse/test/fixtures/iframe.html +0 -30
  114. package/skills/browse/test/fixtures/network-idle.html +0 -30
  115. package/skills/browse/test/fixtures/qa-eval-checkout.html +0 -108
  116. package/skills/browse/test/fixtures/qa-eval-spa.html +0 -98
  117. package/skills/browse/test/fixtures/qa-eval.html +0 -51
  118. package/skills/browse/test/fixtures/responsive.html +0 -49
  119. package/skills/browse/test/fixtures/snapshot.html +0 -55
  120. package/skills/browse/test/fixtures/spa.html +0 -24
  121. package/skills/browse/test/fixtures/states.html +0 -17
  122. package/skills/browse/test/fixtures/upload.html +0 -25
  123. package/skills/browse/test/gstack-config.test.ts +0 -138
  124. package/skills/browse/test/gstack-update-check.test.ts +0 -514
  125. package/skills/browse/test/handoff.test.ts +0 -235
  126. package/skills/browse/test/path-validation.test.ts +0 -91
  127. package/skills/browse/test/platform.test.ts +0 -37
  128. package/skills/browse/test/server-auth.test.ts +0 -65
  129. package/skills/browse/test/sidebar-agent-roundtrip.test.ts +0 -226
  130. package/skills/browse/test/sidebar-agent.test.ts +0 -199
  131. package/skills/browse/test/sidebar-integration.test.ts +0 -320
  132. package/skills/browse/test/sidebar-unit.test.ts +0 -96
  133. package/skills/browse/test/snapshot.test.ts +0 -467
  134. package/skills/browse/test/state-ttl.test.ts +0 -35
  135. package/skills/browse/test/test-server.ts +0 -57
  136. package/skills/browse/test/url-validation.test.ts +0 -72
  137. package/skills/browse/test/watch.test.ts +0 -129
  138. package/skills/canary/SKILL.md.tmpl +0 -212
  139. package/skills/careful/SKILL.md.tmpl +0 -56
  140. package/skills/careful/bin/check-careful.sh +0 -112
  141. package/skills/codex/SKILL.md +0 -90
  142. package/skills/codex/SKILL.md.tmpl +0 -417
  143. package/skills/connect-chrome/SKILL.md.tmpl +0 -195
  144. package/skills/cso/ACKNOWLEDGEMENTS.md +0 -14
  145. package/skills/cso/SKILL.md +0 -93
  146. package/skills/cso/SKILL.md.tmpl +0 -606
  147. package/skills/design-consultation/SKILL.md +0 -94
  148. package/skills/design-consultation/SKILL.md.tmpl +0 -415
  149. package/skills/design-review/SKILL.md +0 -94
  150. package/skills/design-review/SKILL.md.tmpl +0 -290
  151. package/skills/design-shotgun/SKILL.md +0 -91
  152. package/skills/design-shotgun/SKILL.md.tmpl +0 -285
  153. package/skills/document-release/SKILL.md +0 -91
  154. package/skills/document-release/SKILL.md.tmpl +0 -359
  155. package/skills/freeze/SKILL.md.tmpl +0 -77
  156. package/skills/freeze/bin/check-freeze.sh +0 -79
  157. package/skills/gstack-upgrade/SKILL.md.tmpl +0 -222
  158. package/skills/guard/SKILL.md.tmpl +0 -77
  159. package/skills/investigate/SKILL.md +0 -105
  160. package/skills/investigate/SKILL.md.tmpl +0 -194
  161. package/skills/land-and-deploy/SKILL.md.tmpl +0 -881
  162. package/skills/office-hours/SKILL.md +0 -96
  163. package/skills/office-hours/SKILL.md.tmpl +0 -645
  164. package/skills/plan-ceo-review/SKILL.md +0 -94
  165. package/skills/plan-ceo-review/SKILL.md.tmpl +0 -811
  166. package/skills/plan-design-review/SKILL.md +0 -92
  167. package/skills/plan-design-review/SKILL.md.tmpl +0 -446
  168. package/skills/plan-eng-review/SKILL.md +0 -93
  169. package/skills/plan-eng-review/SKILL.md.tmpl +0 -303
  170. package/skills/qa/SKILL.md +0 -95
  171. package/skills/qa/SKILL.md.tmpl +0 -316
  172. package/skills/qa/references/issue-taxonomy.md +0 -85
  173. package/skills/qa/templates/qa-report-template.md +0 -126
  174. package/skills/qa-only/SKILL.md +0 -89
  175. package/skills/qa-only/SKILL.md.tmpl +0 -101
  176. package/skills/retro/SKILL.md +0 -89
  177. package/skills/retro/SKILL.md.tmpl +0 -820
  178. package/skills/review/SKILL.md +0 -92
  179. package/skills/review/SKILL.md.tmpl +0 -281
  180. package/skills/review/TODOS-format.md +0 -62
  181. package/skills/review/checklist.md +0 -220
  182. package/skills/review/design-checklist.md +0 -132
  183. package/skills/review/greptile-triage.md +0 -220
  184. package/skills/setup-browser-cookies/SKILL.md.tmpl +0 -81
  185. package/skills/setup-deploy/SKILL.md +0 -92
  186. package/skills/setup-deploy/SKILL.md.tmpl +0 -215
  187. package/skills/ship/SKILL.md.tmpl +0 -636
  188. package/skills/unfreeze/SKILL.md +0 -37
  189. package/skills/unfreeze/SKILL.md.tmpl +0 -36
@@ -1,191 +0,0 @@
1
- import { describe, test, expect } from 'bun:test';
2
- import * as net from 'net';
3
- import * as path from 'path';
4
-
5
- const polyfillPath = path.resolve(import.meta.dir, '../src/bun-polyfill.cjs');
6
-
7
- // Helper: bind a port and hold it open, returning a cleanup function
8
- function occupyPort(port: number): Promise<() => Promise<void>> {
9
- return new Promise((resolve, reject) => {
10
- const srv = net.createServer();
11
- srv.once('error', reject);
12
- srv.listen(port, '127.0.0.1', () => {
13
- resolve(() => new Promise<void>((r) => srv.close(() => r())));
14
- });
15
- });
16
- }
17
-
18
- // Helper: find a known-free port by binding to 0
19
- function getFreePort(): Promise<number> {
20
- return new Promise((resolve, reject) => {
21
- const srv = net.createServer();
22
- srv.once('error', reject);
23
- srv.listen(0, '127.0.0.1', () => {
24
- const port = (srv.address() as net.AddressInfo).port;
25
- srv.close(() => resolve(port));
26
- });
27
- });
28
- }
29
-
30
- describe('findPort / isPortAvailable', () => {
31
-
32
- test('isPortAvailable returns true for a free port', async () => {
33
- // Use the same isPortAvailable logic from server.ts
34
- const port = await getFreePort();
35
-
36
- const available = await new Promise<boolean>((resolve) => {
37
- const srv = net.createServer();
38
- srv.once('error', () => resolve(false));
39
- srv.listen(port, '127.0.0.1', () => {
40
- srv.close(() => resolve(true));
41
- });
42
- });
43
-
44
- expect(available).toBe(true);
45
- });
46
-
47
- test('isPortAvailable returns false for an occupied port', async () => {
48
- const port = await getFreePort();
49
- const release = await occupyPort(port);
50
-
51
- try {
52
- const available = await new Promise<boolean>((resolve) => {
53
- const srv = net.createServer();
54
- srv.once('error', () => resolve(false));
55
- srv.listen(port, '127.0.0.1', () => {
56
- srv.close(() => resolve(true));
57
- });
58
- });
59
-
60
- expect(available).toBe(false);
61
- } finally {
62
- await release();
63
- }
64
- });
65
-
66
- test('port is actually free after isPortAvailable returns true', async () => {
67
- // This is the core race condition test: after isPortAvailable says
68
- // a port is free, can we IMMEDIATELY bind to it?
69
- const port = await getFreePort();
70
-
71
- // Simulate isPortAvailable
72
- const isFree = await new Promise<boolean>((resolve) => {
73
- const srv = net.createServer();
74
- srv.once('error', () => resolve(false));
75
- srv.listen(port, '127.0.0.1', () => {
76
- srv.close(() => resolve(true));
77
- });
78
- });
79
-
80
- expect(isFree).toBe(true);
81
-
82
- // Now immediately try to bind — this would fail with the old
83
- // Bun.serve() polyfill approach because the test server's
84
- // listen() would still be pending
85
- const canBind = await new Promise<boolean>((resolve) => {
86
- const srv = net.createServer();
87
- srv.once('error', () => resolve(false));
88
- srv.listen(port, '127.0.0.1', () => {
89
- srv.close(() => resolve(true));
90
- });
91
- });
92
-
93
- expect(canBind).toBe(true);
94
- });
95
-
96
- test('polyfill Bun.serve stop() is fire-and-forget (async)', async () => {
97
- // Verify that the polyfill's stop() does NOT wait for the socket
98
- // to actually close — this is the root cause of the race condition.
99
- // On macOS/Linux the OS reclaims the port fast enough that the race
100
- // rarely manifests, but on Windows TIME_WAIT makes it 100% repro.
101
- const result = Bun.spawnSync(['node', '-e', `
102
- require('${polyfillPath}');
103
- const net = require('net');
104
-
105
- async function test() {
106
- const port = 10000 + Math.floor(Math.random() * 50000);
107
-
108
- const testServer = Bun.serve({
109
- port,
110
- hostname: '127.0.0.1',
111
- fetch: () => new Response('ok'),
112
- });
113
-
114
- // stop() returns undefined — it does NOT return a Promise,
115
- // so callers cannot await socket teardown
116
- const retval = testServer.stop();
117
- console.log(typeof retval === 'undefined' ? 'FIRE_AND_FORGET' : 'AWAITABLE');
118
- }
119
-
120
- test();
121
- `], { stdout: 'pipe', stderr: 'pipe' });
122
-
123
- const output = result.stdout.toString().trim();
124
- // Confirms the polyfill's stop() is fire-and-forget — callers
125
- // cannot wait for the port to be released, hence the race
126
- expect(output).toBe('FIRE_AND_FORGET');
127
- });
128
-
129
- test('net.createServer approach does not have the race condition', async () => {
130
- // Prove the fix: net.createServer with proper async bind/close
131
- // releases the port cleanly
132
- const result = Bun.spawnSync(['node', '-e', `
133
- const net = require('net');
134
-
135
- async function testFix() {
136
- const port = 10000 + Math.floor(Math.random() * 50000);
137
-
138
- // Simulate the NEW isPortAvailable: proper async bind/close
139
- const isFree = await new Promise((resolve) => {
140
- const srv = net.createServer();
141
- srv.once('error', () => resolve(false));
142
- srv.listen(port, '127.0.0.1', () => {
143
- srv.close(() => resolve(true));
144
- });
145
- });
146
-
147
- if (!isFree) {
148
- console.log('PORT_BUSY');
149
- return;
150
- }
151
-
152
- // Immediately try to bind — should succeed because close()
153
- // completed before the Promise resolved
154
- const canBind = await new Promise((resolve) => {
155
- const srv = net.createServer();
156
- srv.once('error', () => resolve(false));
157
- srv.listen(port, '127.0.0.1', () => {
158
- srv.close(() => resolve(true));
159
- });
160
- });
161
-
162
- console.log(canBind ? 'FIX_WORKS' : 'FIX_BROKEN');
163
- }
164
-
165
- testFix();
166
- `], { stdout: 'pipe', stderr: 'pipe' });
167
-
168
- const output = result.stdout.toString().trim();
169
- expect(output).toBe('FIX_WORKS');
170
- });
171
-
172
- test('isPortAvailable handles rapid sequential checks', async () => {
173
- // Stress test: check the same port multiple times in sequence
174
- const port = await getFreePort();
175
- const results: boolean[] = [];
176
-
177
- for (let i = 0; i < 5; i++) {
178
- const available = await new Promise<boolean>((resolve) => {
179
- const srv = net.createServer();
180
- srv.once('error', () => resolve(false));
181
- srv.listen(port, '127.0.0.1', () => {
182
- srv.close(() => resolve(true));
183
- });
184
- });
185
- results.push(available);
186
- }
187
-
188
- // All 5 checks should succeed — no leaked sockets
189
- expect(results).toEqual([true, true, true, true, true]);
190
- });
191
- });
@@ -1,33 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Basic</title>
6
- <style>
7
- body { font-family: "Helvetica Neue", sans-serif; color: #333; margin: 20px; }
8
- h1 { color: navy; font-size: 24px; }
9
- .highlight { background: yellow; padding: 4px; }
10
- .hidden { display: none; }
11
- nav a { margin-right: 10px; color: blue; }
12
- </style>
13
- </head>
14
- <body>
15
- <nav>
16
- <a href="/page1">Page 1</a>
17
- <a href="/page2">Page 2</a>
18
- <a href="https://external.com/link">External</a>
19
- </nav>
20
- <h1 id="title">Hello World</h1>
21
- <p class="highlight">This is a highlighted paragraph.</p>
22
- <p class="hidden">This should be hidden.</p>
23
- <div id="content" data-testid="main-content" data-version="1.0">
24
- <p>Some body text here.</p>
25
- <ul>
26
- <li>Item one</li>
27
- <li>Item two</li>
28
- <li>Item three</li>
29
- </ul>
30
- </div>
31
- <footer>Footer text</footer>
32
- </body>
33
- </html>
@@ -1,22 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Cursor Interactive</title>
6
- <style>
7
- .clickable-div { cursor: pointer; padding: 10px; border: 1px solid #ccc; }
8
- .hover-card { cursor: pointer; padding: 20px; background: #f0f0f0; }
9
- </style>
10
- </head>
11
- <body>
12
- <h1>Cursor Interactive Test</h1>
13
- <!-- These are NOT standard interactive elements but have cursor:pointer -->
14
- <div class="clickable-div" id="click-div" onclick="this.textContent = 'clicked!'">Click me (div)</div>
15
- <span class="hover-card" id="hover-span">Hover card (span)</span>
16
- <div tabindex="0" id="focusable-div">Focusable div</div>
17
- <div onclick="alert('hi')" id="onclick-div">Onclick div</div>
18
- <!-- Standard interactive element (should NOT appear in -C output) -->
19
- <button id="normal-btn">Normal Button</button>
20
- <a href="/test">Normal Link</a>
21
- </body>
22
- </html>
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Dialog</title>
6
- </head>
7
- <body>
8
- <h1>Dialog Test</h1>
9
- <button id="alert-btn" onclick="alert('Hello from alert')">Alert</button>
10
- <button id="confirm-btn" onclick="document.getElementById('confirm-result').textContent = confirm('Are you sure?') ? 'confirmed' : 'cancelled'">Confirm</button>
11
- <button id="prompt-btn" onclick="document.getElementById('prompt-result').textContent = prompt('Enter name:', 'default') || 'null'">Prompt</button>
12
- <p id="confirm-result"></p>
13
- <p id="prompt-result"></p>
14
- </body>
15
- </html>
@@ -1,2 +0,0 @@
1
- <!DOCTYPE html>
2
- <html><body></body></html>
@@ -1,55 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Forms</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; }
8
- form { margin-bottom: 20px; padding: 10px; border: 1px solid #ccc; }
9
- label { display: block; margin: 5px 0; }
10
- input, select, textarea { margin-bottom: 10px; padding: 5px; }
11
- #result { color: green; display: none; }
12
- </style>
13
- </head>
14
- <body>
15
- <h1>Form Test Page</h1>
16
-
17
- <form id="login-form" action="/login" method="post">
18
- <label for="email">Email:</label>
19
- <input type="email" id="email" name="email" placeholder="your@email.com" required>
20
- <label for="password">Password:</label>
21
- <input type="password" id="password" name="password" required>
22
- <button type="submit" id="login-btn">Log In</button>
23
- </form>
24
-
25
- <form id="profile-form" action="/profile" method="post">
26
- <label for="name">Name:</label>
27
- <input type="text" id="name" name="name" placeholder="Your name">
28
- <label for="bio">Bio:</label>
29
- <textarea id="bio" name="bio" placeholder="Tell us about yourself"></textarea>
30
- <label for="role">Role:</label>
31
- <select id="role" name="role">
32
- <option value="">Choose...</option>
33
- <option value="admin">Admin</option>
34
- <option value="user">User</option>
35
- <option value="guest">Guest</option>
36
- </select>
37
- <label>
38
- <input type="checkbox" id="newsletter" name="newsletter"> Subscribe to newsletter
39
- </label>
40
- <button type="submit" id="profile-btn">Save Profile</button>
41
- </form>
42
-
43
- <div id="result">Form submitted!</div>
44
-
45
- <script>
46
- document.querySelectorAll('form').forEach(form => {
47
- form.addEventListener('submit', (e) => {
48
- e.preventDefault();
49
- document.getElementById('result').style.display = 'block';
50
- console.log('[Form] Submitted:', form.id);
51
- });
52
- });
53
- </script>
54
- </body>
55
- </html>
@@ -1,30 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Iframe</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; }
8
- iframe { border: 1px solid #ccc; width: 400px; height: 200px; }
9
- </style>
10
- </head>
11
- <body>
12
- <h1 id="main-title">Main Page</h1>
13
- <iframe id="test-frame" name="testframe" srcdoc='
14
- <!DOCTYPE html>
15
- <html>
16
- <body>
17
- <h1 id="frame-title">Inside Frame</h1>
18
- <button id="frame-btn">Frame Button</button>
19
- <input id="frame-input" type="text" placeholder="Type here">
20
- <div id="frame-result"></div>
21
- <script>
22
- document.getElementById("frame-btn").addEventListener("click", () => {
23
- document.getElementById("frame-result").textContent = "Frame button clicked";
24
- });
25
- </script>
26
- </body>
27
- </html>
28
- '></iframe>
29
- </body>
30
- </html>
@@ -1,30 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Test Page - Network Idle</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; }
8
- #result { margin-top: 10px; color: green; }
9
- </style>
10
- </head>
11
- <body>
12
- <button id="fetch-btn">Load Data</button>
13
- <div id="result"></div>
14
- <button id="static-btn">Static Action</button>
15
- <div id="static-result"></div>
16
- <script>
17
- document.getElementById('fetch-btn').addEventListener('click', async () => {
18
- // Simulate an XHR that takes 200ms
19
- const res = await fetch('/echo');
20
- const data = await res.json();
21
- document.getElementById('result').textContent = 'Data loaded: ' + Object.keys(data).length + ' headers';
22
- });
23
-
24
- document.getElementById('static-btn').addEventListener('click', () => {
25
- // No network activity — purely client-side
26
- document.getElementById('static-result').textContent = 'Static action done';
27
- });
28
- </script>
29
- </body>
30
- </html>
@@ -1,108 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>QA Eval — Checkout</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; }
8
- .checkout-form { max-width: 500px; }
9
- .form-group { margin-bottom: 15px; }
10
- .form-group label { display: block; margin-bottom: 4px; font-weight: bold; }
11
- .form-group input { width: 100%; padding: 8px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; }
12
- .form-group input.invalid { border-color: red; }
13
- .form-group .error-msg { color: red; font-size: 12px; display: none; }
14
- .total { font-size: 24px; font-weight: bold; margin: 20px 0; }
15
- button[type="submit"] { padding: 12px 24px; background: #0066cc; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
16
- .order-summary { background: #f5f5f5; padding: 15px; border-radius: 4px; margin-bottom: 20px; }
17
- </style>
18
- </head>
19
- <body>
20
- <h1>Checkout</h1>
21
-
22
- <div class="order-summary">
23
- <h2>Order Summary</h2>
24
- <p>Widget Pro — $99.99 x <input type="number" id="quantity" value="1" min="1" style="width: 50px;"></p>
25
- <p class="total" id="total">Total: $99.99</p> <!-- BUG 2: shows $NaN when quantity is cleared -->
26
- </div>
27
-
28
- <form class="checkout-form" id="checkout-form">
29
- <h2>Shipping Information</h2>
30
-
31
- <div class="form-group">
32
- <label for="email">Email</label>
33
- <input type="text" id="email" name="email" placeholder="you@example.com" required
34
- pattern="[^@]+@[^@]"> <!-- BUG 1: broken regex — accepts "user@" as valid -->
35
- <span class="error-msg" id="email-error">Please enter a valid email</span>
36
- </div>
37
-
38
- <div class="form-group">
39
- <label for="address">Address</label>
40
- <input type="text" id="address" name="address" placeholder="123 Main St" required>
41
- </div>
42
-
43
- <div class="form-group">
44
- <label for="city">City</label>
45
- <input type="text" id="city" name="city" placeholder="San Francisco" required>
46
- </div>
47
-
48
- <div class="form-group">
49
- <label for="zip">Zip Code</label>
50
- <input type="text" id="zip" name="zip" placeholder="94105"> <!-- BUG 4: missing required attribute -->
51
- </div>
52
-
53
- <h2>Payment</h2>
54
-
55
- <div class="form-group">
56
- <label for="cc">Credit Card Number</label>
57
- <input type="text" id="cc" name="cc" placeholder="4111 1111 1111 1111" required>
58
- <!-- BUG 3: no maxlength — overflows container at >20 chars -->
59
- </div>
60
-
61
- <div class="form-group">
62
- <label for="exp">Expiration</label>
63
- <input type="text" id="exp" name="exp" placeholder="MM/YY" required maxlength="5">
64
- </div>
65
-
66
- <div class="form-group">
67
- <label for="cvv">CVV</label>
68
- <input type="text" id="cvv" name="cvv" placeholder="123" required maxlength="4">
69
- </div>
70
-
71
- <button type="submit">Place Order — $<span id="submit-total">99.99</span></button>
72
- </form>
73
-
74
- <script>
75
- // Update total when quantity changes
76
- const quantityInput = document.getElementById('quantity');
77
- const totalEl = document.getElementById('total');
78
- const submitTotalEl = document.getElementById('submit-total');
79
-
80
- quantityInput.addEventListener('input', () => {
81
- // BUG 2: parseInt on empty string returns NaN, no fallback
82
- const qty = parseInt(quantityInput.value);
83
- const total = (qty * 99.99).toFixed(2);
84
- totalEl.textContent = 'Total: $' + total;
85
- submitTotalEl.textContent = total;
86
- });
87
-
88
- // Email validation (broken)
89
- const emailInput = document.getElementById('email');
90
- emailInput.addEventListener('blur', () => {
91
- // BUG 1: this regex accepts "user@" — missing domain part check
92
- const valid = /[^@]+@/.test(emailInput.value);
93
- emailInput.classList.toggle('invalid', !valid && emailInput.value.length > 0);
94
- document.getElementById('email-error').style.display = (!valid && emailInput.value.length > 0) ? 'block' : 'none';
95
- });
96
-
97
- // Form submit
98
- document.getElementById('checkout-form').addEventListener('submit', (e) => {
99
- e.preventDefault();
100
- // BUG 5: stripe is not defined — console error on submit
101
- stripe.createPaymentMethod({
102
- type: 'card',
103
- card: { number: document.getElementById('cc').value }
104
- });
105
- });
106
- </script>
107
- </body>
108
- </html>
@@ -1,98 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>QA Eval — SPA Store</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; margin: 0; }
8
- nav { background: #333; padding: 10px 20px; }
9
- nav a { color: white; margin-right: 15px; text-decoration: none; cursor: pointer; }
10
- nav a:hover { text-decoration: underline; }
11
- #app { padding: 20px; }
12
- .product { border: 1px solid #ddd; padding: 10px; margin: 10px 0; border-radius: 4px; }
13
- .product button { padding: 6px 12px; background: #0066cc; color: white; border: none; cursor: pointer; }
14
- .cart-count { background: #cc0000; color: white; padding: 2px 8px; border-radius: 10px; font-size: 12px; }
15
- .error { color: red; padding: 10px; }
16
- .loading { color: #666; padding: 10px; }
17
- </style>
18
- </head>
19
- <body>
20
- <nav>
21
- <a href="#/home">Home</a>
22
- <a href="#/prodcts">Products</a> <!-- BUG 1: broken route — typo "prodcts" instead of "products" -->
23
- <a href="#/contact">Contact</a>
24
- <span class="cart-count" id="cart-count">0</span>
25
- </nav>
26
-
27
- <div id="app">
28
- <p>Welcome to SPA Store. Use the navigation above.</p>
29
- </div>
30
-
31
- <script>
32
- let cartCount = 0;
33
-
34
- // BUG 2: cart count never resets on route change — stale state
35
- function addToCart() {
36
- cartCount++;
37
- document.getElementById('cart-count').textContent = cartCount;
38
- }
39
-
40
- function renderHome() {
41
- document.getElementById('app').innerHTML = `
42
- <h1>Welcome to SPA Store</h1>
43
- <p>Browse our products using the navigation above.</p>
44
- `;
45
- }
46
-
47
- function renderProducts() {
48
- document.getElementById('app').innerHTML = '<p class="loading">Loading products...</p>';
49
-
50
- // BUG 3: async race — shows data briefly, then shows error
51
- setTimeout(() => {
52
- document.getElementById('app').innerHTML = `
53
- <h1>Products</h1>
54
- <div class="product">
55
- <h3>Widget A</h3>
56
- <p>$29.99</p>
57
- <button onclick="addToCart()">Add to Cart</button>
58
- </div>
59
- <div class="product">
60
- <h3>Widget B</h3>
61
- <p>$49.99</p>
62
- <button onclick="addToCart()">Add to Cart</button>
63
- </div>
64
- `;
65
- }, 300);
66
-
67
- setTimeout(() => {
68
- document.getElementById('app').innerHTML = '<p class="error">Error: Failed to fetch products from API</p>';
69
- }, 1000);
70
- }
71
-
72
- function renderContact() {
73
- document.getElementById('app').innerHTML = `
74
- <h1>Contact Us</h1>
75
- <p>Email: support@spastore.example.com</p>
76
- `;
77
- }
78
-
79
- // BUG 4: nav links have no aria-current attribute on active route
80
- function router() {
81
- const hash = window.location.hash || '#/home';
82
- switch (hash) {
83
- case '#/home': renderHome(); break;
84
- case '#/products': renderProducts(); break;
85
- case '#/contact': renderContact(); break;
86
- default:
87
- document.getElementById('app').innerHTML = '<p>Page not found</p>';
88
- }
89
-
90
- // BUG 5: console.warn on every route change — simulates listener leak
91
- console.warn('Possible memory leak detected: 11 event listeners added to window');
92
- }
93
-
94
- window.addEventListener('hashchange', router);
95
- router();
96
- </script>
97
- </body>
98
- </html>
@@ -1,51 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>QA Eval — Widget Dashboard</title>
6
- <style>
7
- body { font-family: sans-serif; padding: 20px; }
8
- nav { margin-bottom: 20px; }
9
- nav a { margin-right: 15px; color: #0066cc; }
10
- form { margin: 20px 0; padding: 15px; border: 1px solid #ccc; border-radius: 4px; }
11
- input { display: block; margin: 8px 0; padding: 6px; }
12
- button { padding: 8px 16px; margin-top: 8px; }
13
- .stats { margin: 20px 0; }
14
- img { display: block; margin: 20px 0; }
15
- </style>
16
- </head>
17
- <body>
18
- <nav>
19
- <a href="/">Home</a>
20
- <a href="/about">About</a>
21
- <a href="/nonexistent-404-page">Resources</a> <!-- BUG 1: broken link (404) -->
22
- </nav>
23
-
24
- <h1>Widget Dashboard</h1>
25
-
26
- <form id="contact">
27
- <h2>Contact Us</h2>
28
- <input type="text" name="name" placeholder="Name" required>
29
- <input type="email" name="email" placeholder="Email" required>
30
- <button type="submit" disabled>Submit</button> <!-- BUG 2: submit button permanently disabled -->
31
- </form>
32
-
33
- <div class="stats" style="width: 400px; overflow: hidden;">
34
- <h2>Statistics</h2>
35
- <p style="white-space: nowrap; width: 600px;">
36
- Revenue: $1,234,567.89 | Users: 45,678 | Conversion: 3.2% | Growth: +12.5% MoM | Retention: 87.3%
37
- </p> <!-- BUG 3: content overflow/clipping — text wider than container with overflow:hidden -->
38
- </div>
39
-
40
- <img src="/logo.png"> <!-- BUG 4: missing alt text on image -->
41
-
42
- <footer>
43
- <p>&copy; 2026 Widget Co. All rights reserved.</p>
44
- </footer>
45
-
46
- <script>
47
- console.error("TypeError: Cannot read properties of undefined (reading 'map')");
48
- // BUG 5: console error on page load
49
- </script>
50
- </body>
51
- </html>