@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.
- package/LICENSE +21 -0
- package/README.md +196 -0
- package/dashboard/dist/assets/index-CDcHt94n.css +1 -0
- package/dashboard/dist/assets/index-DCNDCh61.js +49 -0
- package/dashboard/dist/index.html +13 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4112 -0
- package/dist/db/agents.d.ts +10 -0
- package/dist/db/agents.d.ts.map +1 -0
- package/dist/db/database.d.ts +10 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/projects.d.ts +11 -0
- package/dist/db/projects.d.ts.map +1 -0
- package/dist/db/results.d.ts +20 -0
- package/dist/db/results.d.ts.map +1 -0
- package/dist/db/runs.d.ts +9 -0
- package/dist/db/runs.d.ts.map +1 -0
- package/dist/db/scenarios.d.ts +8 -0
- package/dist/db/scenarios.d.ts.map +1 -0
- package/dist/db/screenshots.d.ts +13 -0
- package/dist/db/screenshots.d.ts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2515 -0
- package/dist/lib/ai-client.d.ts +66 -0
- package/dist/lib/ai-client.d.ts.map +1 -0
- package/dist/lib/browser.d.ts +64 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/config.d.ts +18 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/reporter.d.ts +18 -0
- package/dist/lib/reporter.d.ts.map +1 -0
- package/dist/lib/runner.d.ts +36 -0
- package/dist/lib/runner.d.ts.map +1 -0
- package/dist/lib/screenshotter.d.ts +60 -0
- package/dist/lib/screenshotter.d.ts.map +1 -0
- package/dist/lib/todos-connector.d.ts +32 -0
- package/dist/lib/todos-connector.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5903 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1654 -0
- package/dist/types/index.d.ts +276 -0
- package/dist/types/index.d.ts.map +1 -0
- 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}
|