@matware/e2e-runner 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.claude-plugin/marketplace.json +21 -0
  2. package/.mcp.json +2 -2
  3. package/.opencode/commands/create-test.md +63 -0
  4. package/.opencode/commands/run.md +50 -0
  5. package/.opencode/commands/verify-issue.md +62 -0
  6. package/.opencode/skills/e2e-testing/SKILL.md +181 -0
  7. package/.opencode/skills/e2e-testing/references/action-types.md +143 -0
  8. package/.opencode/skills/e2e-testing/references/auth-strategies.md +91 -0
  9. package/.opencode/skills/e2e-testing/references/graphql.md +59 -0
  10. package/.opencode/skills/e2e-testing/references/issue-verification.md +59 -0
  11. package/.opencode/skills/e2e-testing/references/multi-pool.md +60 -0
  12. package/.opencode/skills/e2e-testing/references/network-debugging.md +62 -0
  13. package/.opencode/skills/e2e-testing/references/test-json-format.md +163 -0
  14. package/.opencode/skills/e2e-testing/references/troubleshooting.md +224 -0
  15. package/.opencode/skills/e2e-testing/references/variables.md +41 -0
  16. package/.opencode/skills/e2e-testing/references/visual-verification.md +89 -0
  17. package/OPENCODE.md +166 -0
  18. package/README.md +581 -55
  19. package/agents/test-creator.md +54 -1
  20. package/agents/test-improver.md +37 -0
  21. package/bin/cli.js +408 -16
  22. package/commands/create-test.md +16 -1
  23. package/opencode.json +11 -0
  24. package/package.json +7 -2
  25. package/scripts/setup-opencode.sh +113 -0
  26. package/skills/e2e-testing/SKILL.md +10 -3
  27. package/skills/e2e-testing/references/action-types.md +48 -5
  28. package/skills/e2e-testing/references/auth-strategies.md +91 -0
  29. package/skills/e2e-testing/references/graphql.md +59 -0
  30. package/skills/e2e-testing/references/issue-verification.md +59 -0
  31. package/skills/e2e-testing/references/multi-pool.md +60 -0
  32. package/skills/e2e-testing/references/network-debugging.md +62 -0
  33. package/skills/e2e-testing/references/test-json-format.md +4 -0
  34. package/skills/e2e-testing/references/troubleshooting.md +44 -2
  35. package/skills/e2e-testing/references/variables.md +41 -0
  36. package/skills/e2e-testing/references/visual-verification.md +89 -0
  37. package/src/actions.js +324 -2
  38. package/src/ai-generate.js +58 -8
  39. package/src/config.js +143 -0
  40. package/src/dashboard.js +145 -13
  41. package/src/db.js +130 -2
  42. package/src/index.js +7 -6
  43. package/src/learner-sqlite.js +304 -0
  44. package/src/learner.js +8 -3
  45. package/src/mcp-tools.js +1121 -43
  46. package/src/module-resolver.js +37 -0
  47. package/src/narrate.js +37 -0
  48. package/src/pool-manager.js +223 -0
  49. package/src/reporter.js +82 -1
  50. package/src/runner.js +157 -28
  51. package/src/sync/auth.js +354 -0
  52. package/src/sync/client.js +572 -0
  53. package/src/sync/hub-routes.js +816 -0
  54. package/src/sync/index.js +68 -0
  55. package/src/sync/middleware.js +347 -0
  56. package/src/sync/queue.js +209 -0
  57. package/src/sync/schema.js +540 -0
  58. package/src/verify.js +10 -7
  59. package/src/watch.js +384 -0
  60. package/templates/build-dashboard.js +47 -6
  61. package/templates/dashboard/js/api.js +60 -0
  62. package/templates/dashboard/js/init.js +13 -0
  63. package/templates/dashboard/js/keyboard.js +46 -0
  64. package/templates/dashboard/js/state.js +40 -0
  65. package/templates/dashboard/js/toast.js +41 -0
  66. package/templates/dashboard/js/utils.js +196 -0
  67. package/templates/dashboard/js/view-live.js +143 -0
  68. package/templates/dashboard/js/view-runs.js +572 -0
  69. package/templates/dashboard/js/view-tests.js +294 -0
  70. package/templates/dashboard/js/view-watch.js +242 -0
  71. package/templates/dashboard/js/websocket.js +110 -0
  72. package/templates/dashboard/styles/base.css +69 -0
  73. package/templates/dashboard/styles/components.css +110 -0
  74. package/templates/dashboard/styles/view-live.css +74 -0
  75. package/templates/dashboard/styles/view-runs.css +207 -0
  76. package/templates/dashboard/styles/view-tests.css +96 -0
  77. package/templates/dashboard/styles/view-watch.css +53 -0
  78. package/templates/dashboard/template.html +165 -99
  79. package/templates/dashboard.html +1596 -541
  80. package/templates/sample-test.json +0 -8
  81. package/templates/dashboard/app.js +0 -1152
  82. package/templates/dashboard/styles.css +0 -413
@@ -28,20 +28,17 @@
28
28
  <div class="sidebar-section">
29
29
  <div class="sidebar-section-label">Navigation</div>
30
30
  </div>
31
- <div class="nav-item" data-view="live" id="navLive" style="display:none">
32
- <i class="icon"><span class="live-nav-dot"></span></i><span>Live</span><span class="badge" id="liveBadge" style="background:var(--purple-dim);color:var(--purple)">0</span>
31
+ <div class="nav-item active" data-view="watch">
32
+ <i class="icon">&#9202;</i><span>Watch</span>
33
33
  </div>
34
- <div class="nav-item active" data-view="suites">
35
- <i class="icon">&#9655;</i><span>Suites</span><span class="badge" id="badgeSuites">-</span>
34
+ <div class="nav-item" data-view="tests">
35
+ <i class="icon">&#9655;</i><span>Tests</span><span class="badge" id="badgeSuites">-</span>
36
36
  </div>
37
37
  <div class="nav-item" data-view="runs">
38
38
  <i class="icon">&#9776;</i><span>Runs</span><span class="badge" id="badgeRuns">-</span>
39
39
  </div>
40
- <div class="nav-item" data-view="screenshots">
41
- <i class="icon">&#9635;</i><span>Screenshots</span><span class="badge" id="badgeScreenshots">-</span>
42
- </div>
43
- <div class="nav-item" data-view="learnings">
44
- <i class="icon">&#9733;</i><span>Learnings</span><span class="badge" id="badgeLearnings">-</span>
40
+ <div class="nav-item" data-view="live" id="navLive" style="display:none">
41
+ <i class="icon"><span class="live-nav-dot"></span></i><span>Live</span><span class="badge" id="liveBadge" style="background:var(--purple-dim);color:var(--purple)">0</span>
45
42
  </div>
46
43
 
47
44
  <div class="pool-status" id="poolStatus">
@@ -50,6 +47,7 @@
50
47
  <strong>Pool</strong> <span id="poolLabel">--</span>
51
48
  </div>
52
49
  <div class="pool-info">Sessions: <strong id="poolSessions">-/-</strong></div>
50
+ <div class="pool-list" id="poolList" style="display:none"></div>
53
51
  <div class="pool-info" style="margin-top:6px">
54
52
  <span class="ws-dot" id="wsDot" style="background:var(--red)"></span>
55
53
  <span id="wsLabel" style="font-size:10px;color:var(--text3)">ws: connecting</span>
@@ -59,7 +57,145 @@
59
57
 
60
58
  <div class="main">
61
59
 
62
- <!-- Live View -->
60
+ <!-- ════════════════ Watch View (default) ════════════════ -->
61
+ <div class="view active" id="view-watch">
62
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px">
63
+ <div style="font-family:var(--sans);font-size:16px;font-weight:600">Watch</div>
64
+ </div>
65
+ <div class="watch-grid" id="watchCards"></div>
66
+ <div class="watch-event-log">
67
+ <div class="watch-event-log-header">
68
+ <span class="title">Recent Runs</span>
69
+ </div>
70
+ <div class="watch-event-log-body" id="watchEventLog"></div>
71
+ </div>
72
+ <div class="empty" id="watchEmpty" style="display:none">
73
+ <div class="empty-icon">&#9202;</div>
74
+ <p>No projects registered yet. Run some tests to see project cards here.</p>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- ════════════════ Tests View (inner tabs: Suites / Modules / Variables) ════════════════ -->
79
+ <div class="view" id="view-tests">
80
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
81
+ <div style="font-family:var(--sans);font-size:16px;font-weight:600">Tests</div>
82
+ <div style="display:flex;gap:8px">
83
+ <button class="btn sm primary" id="btnRunAll">&#9655; Run All</button>
84
+ </div>
85
+ </div>
86
+ <div class="tab-bar">
87
+ <button class="tab-btn active" data-tab="testsTabSuites">Suites</button>
88
+ <button class="tab-btn" data-tab="testsTabModules">Modules</button>
89
+ <button class="tab-btn" data-tab="testsTabVariables">Variables</button>
90
+ </div>
91
+ <!-- Suites tab -->
92
+ <div class="tab-pane active" id="testsTabSuites">
93
+ <div id="suiteAccordionContainer"></div>
94
+ <div class="suite-grid" id="suiteGrid"></div>
95
+ <div class="empty" id="suitesEmpty" style="display:none">
96
+ <div class="empty-icon">&#9655;</div>
97
+ <p>No test suites found.</p>
98
+ </div>
99
+ </div>
100
+ <!-- Modules tab -->
101
+ <div class="tab-pane" id="testsTabModules">
102
+ <div id="moduleSection"></div>
103
+ </div>
104
+ <!-- Variables tab -->
105
+ <div class="tab-pane" id="testsTabVariables">
106
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
107
+ <div style="font-family:var(--sans);font-size:14px;font-weight:600;color:var(--text2)">Variables</div>
108
+ <button class="btn sm primary" id="btnAddVar">+ Add Variable</button>
109
+ </div>
110
+ <div id="varAddForm" style="display:none"></div>
111
+ <div id="variablesContainer"></div>
112
+ <div class="empty" id="variablesEmpty" style="display:none">
113
+ <div class="empty-icon">&#9881;</div>
114
+ <p>No variables set. Add variables to use <code>{{var.KEY}}</code> in your tests.</p>
115
+ </div>
116
+ </div>
117
+ </div>
118
+
119
+ <!-- ════════════════ Runs View (inner tabs: History / Screenshots / Learnings) ════════════════ -->
120
+ <div class="view" id="view-runs">
121
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
122
+ <div style="font-family:var(--sans);font-size:16px;font-weight:600">Runs</div>
123
+ </div>
124
+ <div class="tab-bar">
125
+ <button class="tab-btn active" data-tab="runsTabHistory">History</button>
126
+ <button class="tab-btn" data-tab="runsTabScreenshots">Screenshots<span class="badge" id="badgeScreenshots" style="margin-left:6px">-</span></button>
127
+ <button class="tab-btn" data-tab="runsTabLearnings" id="runsTabLearnings">Learnings<span class="badge" id="badgeLearnings" style="margin-left:6px">-</span></button>
128
+ </div>
129
+ <!-- History tab -->
130
+ <div class="tab-pane active" id="runsTabHistory">
131
+ <div class="health-banner" id="runsHealthBanner"></div>
132
+ <div class="card">
133
+ <div class="card-label">Pass Rate Trend</div>
134
+ <div class="chart" id="trendChart"></div>
135
+ </div>
136
+ <div class="filter-bar" id="filterBar">
137
+ <button class="filter-btn active" data-filter="all">All</button>
138
+ <button class="filter-btn" data-filter="pass">Pass</button>
139
+ <button class="filter-btn" data-filter="fail">Fail</button>
140
+ <button class="filter-btn" data-filter="mixed">Mixed</button>
141
+ <input type="text" id="runSearchInput" placeholder="Search suite..." spellcheck="false">
142
+ </div>
143
+ <div class="card" style="padding:0">
144
+ <div class="tbl-wrap">
145
+ <table>
146
+ <thead id="runsHead"><tr></tr></thead>
147
+ <tbody id="runsBody"></tbody>
148
+ </table>
149
+ </div>
150
+ </div>
151
+ <div class="empty" id="runsEmpty" style="display:none">
152
+ <div class="empty-icon">&#9776;</div>
153
+ <p>No runs recorded yet.</p>
154
+ </div>
155
+ </div>
156
+ <!-- Screenshots tab -->
157
+ <div class="tab-pane" id="runsTabScreenshots">
158
+ <div class="ss-search">
159
+ <input type="text" id="ssHashInput" placeholder="Search by hash (e.g. ss:a3f2b1c9)" spellcheck="false">
160
+ <button id="ssHashBtn">Search</button>
161
+ </div>
162
+ <div id="ssSearchResult"></div>
163
+ <div class="gallery" id="screenshotGallery"></div>
164
+ <div class="empty" id="screenshotsEmpty" style="display:none">
165
+ <div class="empty-icon">&#9635;</div>
166
+ <p>Select a project to view screenshots.</p>
167
+ </div>
168
+ </div>
169
+ <!-- Learnings tab -->
170
+ <div class="tab-pane" id="runsTabLearnings">
171
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
172
+ <div style="font-family:var(--sans);font-size:14px;font-weight:600;color:var(--text2)">Learnings</div>
173
+ <div style="display:flex;gap:8px;align-items:center">
174
+ <select id="learningsDays" style="padding:5px 8px;border-radius:var(--r);border:1px solid var(--border);background:var(--surface2);color:var(--text);font-family:var(--mono);font-size:11px">
175
+ <option value="7">7 days</option>
176
+ <option value="14">14 days</option>
177
+ <option value="30" selected>30 days</option>
178
+ <option value="90">90 days</option>
179
+ </select>
180
+ <button class="btn sm" id="btnExportLearnings">Export MD</button>
181
+ <button class="btn sm" id="btnRefreshLearnings">Refresh</button>
182
+ </div>
183
+ </div>
184
+ <div id="learningsOverview"></div>
185
+ <div id="learningsTrend"></div>
186
+ <div id="learningsFlaky"></div>
187
+ <div id="learningsSelectors"></div>
188
+ <div id="learningsPages"></div>
189
+ <div id="learningsApis"></div>
190
+ <div id="learningsErrors"></div>
191
+ <div class="empty" id="learningsEmpty" style="display:none">
192
+ <div class="empty-icon">&#9733;</div>
193
+ <p>No learnings data yet. Run some tests to start building knowledge.</p>
194
+ </div>
195
+ </div>
196
+ </div>
197
+
198
+ <!-- ════════════════ Live View ════════════════ -->
63
199
  <div class="view" id="view-live">
64
200
  <div class="live-panel active" id="livePanel">
65
201
  <div class="live-header">
@@ -82,110 +218,40 @@
82
218
  </div>
83
219
  <div class="empty" id="liveEmpty">
84
220
  <div class="empty-icon" style="font-size:48px;opacity:.3">&#9679;</div>
85
- <p>No tests running. Start a test from the Suites view or another console.</p>
221
+ <p>No tests running. Start a test from the Tests view or another console.</p>
86
222
  <p style="margin-top:8px;font-size:11px;color:var(--text3)">This view activates automatically when tests are detected.</p>
87
223
  </div>
88
224
  </div>
89
225
 
90
- <!-- Suites View -->
91
- <div class="view active" id="view-suites">
92
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px">
93
- <div style="font-family:var(--sans);font-size:16px;font-weight:600">Test Suites</div>
94
- <button class="btn primary" id="btnRunAll">Run All Tests</button>
95
- </div>
96
- <div class="suite-grid" id="suiteGrid"></div>
97
- <div id="moduleSection"></div>
98
- <div class="empty" id="suitesEmpty" style="display:none">
99
- <div class="empty-icon">&#9655;</div>
100
- <p>No test suites found.</p>
101
- </div>
102
- </div>
226
+ </div>
103
227
 
104
- <!-- Runs View -->
105
- <div class="view" id="view-runs">
106
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px">
107
- <div style="font-family:var(--sans);font-size:16px;font-weight:600">Run History</div>
108
- </div>
109
- <div class="card">
110
- <div class="card-label">Pass Rate Trend</div>
111
- <div class="chart" id="trendChart"></div>
112
- </div>
113
- <div class="filter-bar" id="filterBar">
114
- <button class="filter-btn active" data-filter="all">All</button>
115
- <button class="filter-btn" data-filter="pass">Pass</button>
116
- <button class="filter-btn" data-filter="fail">Fail</button>
117
- <button class="filter-btn" data-filter="mixed">Mixed</button>
118
- <input type="text" id="runSearchInput" placeholder="Search suite..." spellcheck="false">
119
- </div>
120
- <div class="card" style="padding:0">
121
- <div class="tbl-wrap">
122
- <table>
123
- <thead id="runsHead"><tr></tr></thead>
124
- <tbody id="runsBody"></tbody>
125
- </table>
228
+ <div class="suite-modal-overlay" id="suiteModalOverlay">
229
+ <div class="suite-modal" id="suiteModal">
230
+ <div class="suite-modal-header">
231
+ <div class="suite-card-icon">&#9655;</div>
232
+ <div class="suite-modal-title">
233
+ <h2 id="suiteModalName"></h2>
234
+ <span id="suiteModalFile"></span>
235
+ </div>
236
+ <div class="suite-modal-actions">
237
+ <button class="btn sm primary" id="suiteModalRun">&#9655; Run</button>
238
+ <button class="suite-modal-close" id="suiteModalClose">&times;</button>
126
239
  </div>
127
240
  </div>
128
- <div class="empty" id="runsEmpty" style="display:none">
129
- <div class="empty-icon">&#9776;</div>
130
- <p>No runs recorded yet.</p>
131
- </div>
132
- </div>
133
-
134
- <!-- Learnings View -->
135
- <div class="view" id="view-learnings">
136
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px">
137
- <div style="font-family:var(--sans);font-size:16px;font-weight:600">Learnings</div>
138
- <div style="display:flex;gap:8px;align-items:center">
139
- <select id="learningsDays" style="padding:5px 8px;border-radius:var(--r);border:1px solid var(--border);background:var(--surface2);color:var(--text);font-family:var(--mono);font-size:11px">
140
- <option value="7">7 days</option>
141
- <option value="14">14 days</option>
142
- <option value="30" selected>30 days</option>
143
- <option value="90">90 days</option>
144
- </select>
145
- <button class="btn sm" id="btnExportLearnings">Export MD</button>
146
- <button class="btn sm" id="btnRefreshLearnings">Refresh</button>
147
- </div>
148
- </div>
149
- <div id="learningsOverview"></div>
150
- <div id="learningsTrend"></div>
151
- <div id="learningsFlaky"></div>
152
- <div id="learningsSelectors"></div>
153
- <div id="learningsPages"></div>
154
- <div id="learningsApis"></div>
155
- <div id="learningsErrors"></div>
156
- <div class="empty" id="learningsEmpty" style="display:none">
157
- <div class="empty-icon">&#9733;</div>
158
- <p>No learnings data yet. Run some tests to start building knowledge.</p>
159
- </div>
160
- </div>
161
-
162
- <!-- Screenshots View -->
163
- <div class="view" id="view-screenshots">
164
- <div style="font-family:var(--sans);font-size:16px;font-weight:600;margin-bottom:20px">Screenshots</div>
165
- <div class="ss-search">
166
- <input type="text" id="ssHashInput" placeholder="Search by hash (e.g. ss:a3f2b1c9)" spellcheck="false">
167
- <button id="ssHashBtn">Search</button>
168
- </div>
169
- <div id="ssSearchResult"></div>
170
- <div class="gallery" id="screenshotGallery"></div>
171
- <div class="empty" id="screenshotsEmpty" style="display:none">
172
- <div class="empty-icon">&#9635;</div>
173
- <p>Select a project to view screenshots.</p>
241
+ <div class="suite-modal-body" id="suiteModalBody">
242
+ <div class="suite-modal-loading">Loading...</div>
174
243
  </div>
175
244
  </div>
176
-
177
245
  </div>
178
-
179
246
  <div class="modal" id="modal"><img id="modalImg" src="" alt=""></div>
180
247
  <div class="toast-container" id="toastContainer"></div>
181
248
  <div class="kb-modal" id="kbModal">
182
249
  <div class="kb-modal-content">
183
250
  <h2>Keyboard Shortcuts</h2>
184
- <div class="kb-row"><span class="kb-key">1</span><span class="kb-desc">Suites view</span></div>
185
- <div class="kb-row"><span class="kb-key">2</span><span class="kb-desc">Runs view</span></div>
186
- <div class="kb-row"><span class="kb-key">3</span><span class="kb-desc">Screenshots view</span></div>
187
- <div class="kb-row"><span class="kb-key">4</span><span class="kb-desc">Learnings view</span></div>
188
- <div class="kb-row"><span class="kb-key">5</span><span class="kb-desc">Live view</span></div>
251
+ <div class="kb-row"><span class="kb-key">1</span><span class="kb-desc">Watch view</span></div>
252
+ <div class="kb-row"><span class="kb-key">2</span><span class="kb-desc">Tests view</span></div>
253
+ <div class="kb-row"><span class="kb-key">3</span><span class="kb-desc">Runs view</span></div>
254
+ <div class="kb-row"><span class="kb-key">4</span><span class="kb-desc">Live view</span></div>
189
255
  <div class="kb-row"><span class="kb-key">j / k</span><span class="kb-desc">Navigate runs (next / previous)</span></div>
190
256
  <div class="kb-row"><span class="kb-key">Enter</span><span class="kb-desc">Expand / collapse selected run</span></div>
191
257
  <div class="kb-row"><span class="kb-key">Esc</span><span class="kb-desc">Close modal / collapse run</span></div>