@hasna/testers 0.0.1

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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -0
  3. package/dashboard/dist/assets/index-CDcHt94n.css +1 -0
  4. package/dashboard/dist/assets/index-DCNDCh61.js +49 -0
  5. package/dashboard/dist/index.html +13 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +4112 -0
  9. package/dist/db/agents.d.ts +10 -0
  10. package/dist/db/agents.d.ts.map +1 -0
  11. package/dist/db/database.d.ts +10 -0
  12. package/dist/db/database.d.ts.map +1 -0
  13. package/dist/db/projects.d.ts +11 -0
  14. package/dist/db/projects.d.ts.map +1 -0
  15. package/dist/db/results.d.ts +20 -0
  16. package/dist/db/results.d.ts.map +1 -0
  17. package/dist/db/runs.d.ts +9 -0
  18. package/dist/db/runs.d.ts.map +1 -0
  19. package/dist/db/scenarios.d.ts +8 -0
  20. package/dist/db/scenarios.d.ts.map +1 -0
  21. package/dist/db/screenshots.d.ts +13 -0
  22. package/dist/db/screenshots.d.ts.map +1 -0
  23. package/dist/index.d.ts +18 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +2515 -0
  26. package/dist/lib/ai-client.d.ts +66 -0
  27. package/dist/lib/ai-client.d.ts.map +1 -0
  28. package/dist/lib/browser.d.ts +64 -0
  29. package/dist/lib/browser.d.ts.map +1 -0
  30. package/dist/lib/config.d.ts +18 -0
  31. package/dist/lib/config.d.ts.map +1 -0
  32. package/dist/lib/reporter.d.ts +18 -0
  33. package/dist/lib/reporter.d.ts.map +1 -0
  34. package/dist/lib/runner.d.ts +36 -0
  35. package/dist/lib/runner.d.ts.map +1 -0
  36. package/dist/lib/screenshotter.d.ts +60 -0
  37. package/dist/lib/screenshotter.d.ts.map +1 -0
  38. package/dist/lib/todos-connector.d.ts +32 -0
  39. package/dist/lib/todos-connector.d.ts.map +1 -0
  40. package/dist/mcp/index.d.ts +3 -0
  41. package/dist/mcp/index.d.ts.map +1 -0
  42. package/dist/mcp/index.js +5903 -0
  43. package/dist/server/index.d.ts +3 -0
  44. package/dist/server/index.d.ts.map +1 -0
  45. package/dist/server/index.js +1654 -0
  46. package/dist/types/index.d.ts +276 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrei Hasna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # open-testers
2
+
3
+ AI-powered QA testing CLI — spawns cheap AI agents to test web apps with headless browsers.
4
+
5
+ ## What is this?
6
+
7
+ `testers` is a CLI tool that creates AI testing agents (Claude Haiku 4.5 by default) to click through your website like a real human. Tests are stored in SQLite, screenshots are captured at every step, and results are queryable.
8
+
9
+ Part of the [@hasna](https://www.npmjs.com/org/hasnaxyz) open-source ecosystem.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install -g @hasna/testers
15
+
16
+ # Install browser (first time only)
17
+ testers install-browser
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Create a test scenario
24
+ testers add "Login flow" --description "Test login with valid creds" --tag auth --priority high
25
+
26
+ # Run all scenarios against your app
27
+ testers run http://localhost:3000
28
+
29
+ # Run with live browser (non-headless)
30
+ testers run http://localhost:3000 --headed
31
+
32
+ # Run a quick ad-hoc test
33
+ testers run http://localhost:3000 "verify the signup page loads and shows a form"
34
+
35
+ # Use a smarter model for complex scenarios
36
+ testers run http://localhost:3000 --model sonnet
37
+ ```
38
+
39
+ ## Features
40
+
41
+ - **SQLite-backed scenarios** — Define, tag, filter, and reuse test scenarios
42
+ - **AI-powered** — Agents navigate, click, fill forms, and verify results autonomously
43
+ - **Screenshot-first** — Every action captured and organized by run/scenario/step
44
+ - **Cheap by default** — Haiku 4.5 (~$0.001/test), configurable per scenario
45
+ - **Headless by default** — Opt-in `--headed` mode to watch AI test live
46
+ - **open-todos integration** — Pull QA tasks as test scenarios
47
+ - **MCP server** — Let Claude Code trigger tests inline
48
+ - **Dashboard** — Web UI for browsing results and screenshots
49
+
50
+ ## CLI Reference
51
+
52
+ ### Scenario Management
53
+
54
+ ```bash
55
+ testers add <name> [options] # Create a test scenario
56
+ --description <desc> # Scenario description
57
+ --steps <step> # Add a step (repeatable)
58
+ --tag <tag> # Add a tag (repeatable)
59
+ --priority <low|medium|high|critical>
60
+ --model <preset|model-id> # Override model
61
+ --path <path> # Target path (e.g., /login)
62
+ --auth # Requires authentication
63
+ --timeout <ms> # Custom timeout
64
+
65
+ testers list [options] # List scenarios
66
+ --tag <tag> # Filter by tag
67
+ --priority <priority> # Filter by priority
68
+
69
+ testers show <id> # Show scenario details
70
+ testers update <id> [options] # Update scenario
71
+ testers delete <id> # Delete scenario
72
+ ```
73
+
74
+ ### Running Tests
75
+
76
+ ```bash
77
+ testers run <url> [description] # Run tests
78
+ --tag <tag> # Run scenarios with tag
79
+ --scenario <id> # Run specific scenario
80
+ --priority <priority> # Run by priority
81
+ --headed # Watch browser live
82
+ --model <quick|thorough|deep> # Model preset
83
+ --parallel <n> # Concurrent agents (default: 1)
84
+ --json # JSON output
85
+ --output <file> # Write JSON to file
86
+ --from-todos # Pull from open-todos
87
+ --project <name> # Filter by project
88
+ ```
89
+
90
+ ### Results
91
+
92
+ ```bash
93
+ testers runs # List past runs
94
+ testers results <run-id> # Show run results
95
+ testers screenshots <id> # List screenshots
96
+ ```
97
+
98
+ ### Utilities
99
+
100
+ ```bash
101
+ testers config # Show config
102
+ testers status # Show auth & DB status
103
+ testers install-browser # Install Playwright chromium
104
+ testers import <dir> # Import markdown tests to DB
105
+ testers serve # Start dashboard
106
+ ```
107
+
108
+ ## Model Presets
109
+
110
+ | Preset | Model | Use Case |
111
+ |--------|-------|----------|
112
+ | `quick` (default) | Claude Haiku 4.5 | Fast, cheap tests |
113
+ | `thorough` | Claude Sonnet 4.6 | Complex flows |
114
+ | `deep` | Claude Opus 4.6 | Multi-step critical paths |
115
+
116
+ ## Configuration
117
+
118
+ Config file: `~/.testers/config.json`
119
+
120
+ ```json
121
+ {
122
+ "defaultModel": "claude-haiku-4-5-20251001",
123
+ "browser": {
124
+ "headless": true,
125
+ "viewport": { "width": 1280, "height": 720 }
126
+ },
127
+ "screenshots": {
128
+ "dir": "~/.testers/screenshots",
129
+ "format": "png"
130
+ }
131
+ }
132
+ ```
133
+
134
+ Environment variables:
135
+ - `ANTHROPIC_API_KEY` — Your Anthropic API key (required)
136
+ - `TESTERS_DB_PATH` — Custom database path
137
+ - `TESTERS_MODEL` — Override default model
138
+ - `TESTERS_SCREENSHOTS_DIR` — Custom screenshot directory
139
+ - `TESTERS_PORT` — Dashboard server port (default: 19450)
140
+
141
+ ## Screenshots
142
+
143
+ Screenshots are saved to `~/.testers/screenshots/` organized by:
144
+
145
+ ```
146
+ {run-id}/
147
+ {scenario-slug}/
148
+ 001-navigate-homepage.png
149
+ 002-click-login-button.png
150
+ 003-fill-email-field.png
151
+ 004-submit-form.png
152
+ 005-verify-dashboard.png
153
+ ```
154
+
155
+ ## MCP Server
156
+
157
+ Install for Claude Code:
158
+
159
+ ```bash
160
+ claude mcp add --transport stdio --scope user testers-mcp -- testers-mcp
161
+ ```
162
+
163
+ Available tools: `create_scenario`, `list_scenarios`, `run_scenarios`, `get_results`, `get_screenshots`, and more.
164
+
165
+ ## open-todos Integration
166
+
167
+ Pull QA tasks from [open-todos](https://github.com/hasna/open-todos) as test scenarios:
168
+
169
+ ```bash
170
+ testers run http://localhost:3000 --from-todos --project myapp
171
+ ```
172
+
173
+ Tasks tagged with `qa`, `test`, or `testing` are automatically imported.
174
+
175
+ ## Dashboard
176
+
177
+ ```bash
178
+ testers serve
179
+ # Open http://localhost:19450
180
+ ```
181
+
182
+ Browse scenarios, runs, results, and screenshots in a web UI.
183
+
184
+ ## Stack
185
+
186
+ - **Runtime**: Bun
187
+ - **Language**: TypeScript
188
+ - **Database**: SQLite (bun:sqlite)
189
+ - **Browser**: Playwright (Chromium)
190
+ - **AI**: Anthropic Claude API
191
+ - **CLI**: Commander.js
192
+ - **Dashboard**: React + Vite + Tailwind CSS
193
+
194
+ ## License
195
+
196
+ MIT
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.start{inset-inline-start:var(--spacing)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.border{border-style:var(--tw-border-style);border-width:1px}}:root{--bg:#0a0a0a;--bg-card:#141414;--bg-hover:#1a1a1a;--border:#262626;--text:#e5e5e5;--text-muted:#737373;--green:#22c55e;--red:#ef4444;--yellow:#eab308;--blue:#3b82f6;--cyan:#06b6d4}body{background:var(--bg);color:var(--text);margin:0;font-family:system-ui,-apple-system,sans-serif}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}