@timetotest/cli 0.1.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/README.md ADDED
@@ -0,0 +1,263 @@
1
+ ### Time to Test CLI (`@timetotest/cli`)
2
+
3
+ AI-powered web testing from your terminal. Start tests against your app, stream real-time progress, and download shareable reports.
4
+
5
+ ## Quick Start
6
+
7
+ 1. Log in
8
+
9
+ ```bash
10
+ ttt login
11
+ ```
12
+
13
+ 2. Start a test
14
+
15
+ - Easiest (no URL needed, uses your project’s saved URL):
16
+
17
+ ```bash
18
+ ttt start-test "Smoke test the main user journey" --execute --wait
19
+ ```
20
+
21
+ - With an explicit URL:
22
+
23
+ ```bash
24
+ ttt test --url https://your-app.com --type ui --execute --wait
25
+ ```
26
+
27
+ 3. Chat with the agent
28
+
29
+ ```bash
30
+ ttt ask
31
+ ```
32
+
33
+ Tips:
34
+
35
+ - Use `--report [path]` to download a PDF when the test completes
36
+ - Use `--share` to enable a public share link
37
+ - Use `ttt stream <test-id>` to reattach to progress later
38
+
39
+ - **Node requirement**: 18+
40
+ - **Website**: [Time to Test](https://timetotest.tech)
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ npm i -g @timetotest/cli
46
+ # or use npx without global install
47
+ npx @timetotest/cli --help
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ 1. Authenticate
53
+
54
+ ```bash
55
+ ttt login
56
+ # Opens a browser to authenticate. As a fallback, you may be prompted to paste a short-lived token.
57
+ ```
58
+
59
+ 2. Run a UI test against a local app
60
+
61
+ ```bash
62
+ ttt test \
63
+ --url http://localhost:3000 \
64
+ --type ui \
65
+ --execute \
66
+ --mode priority \
67
+ --project-id 123 \
68
+ --team-id 456 \
69
+ --report ./report.pdf \
70
+ --wait
71
+ ```
72
+
73
+ The CLI will automatically start an ngrok tunnel for local URLs and stream progress via Socket.IO.
74
+
75
+ ## Authentication
76
+
77
+ - **Interactive**: `ttt login` opens the browser and stores a Firebase ID token in `~/.timetotest/config.json`.
78
+ - **Headless/CI**: Use Firebase Email/Password (service user):
79
+
80
+ ```bash
81
+ ttt login --email "$TTT_EMAIL" --password "$TTT_PASSWORD" --api-key "$TTT_FIREBASE_API_KEY"
82
+ ```
83
+
84
+ - **Direct token**: `ttt login --token <FIREBASE_ID_TOKEN>`
85
+ - **Env override**: Set `TTT_TOKEN` to inject the token for one-off runs.
86
+
87
+ ## Commands
88
+
89
+ - **ttt login**
90
+
91
+ - Options:
92
+ - `--device` (reserved)
93
+ - `--email <email> --password <password> --api-key <firebase-web-api-key>`
94
+ - `--token <FIREBASE_ID_TOKEN>`
95
+
96
+ - **ttt test**
97
+
98
+ - Starts a test and subscribes to real-time events.
99
+ - Key options:
100
+ - `--url <ui-url>`: app URL under test (required for UI/mixed)
101
+ - `--type <ui|api|mixed>`: defaults to `ui`
102
+ - `--execute`: execute generated test cases
103
+ - `--mode <all|priority|failed_only>`: defaults to `priority`
104
+ - `--project-id <id>` / `--team-id <id>`
105
+ - `--docs-url <openapi-url>`: API docs (OpenAPI/Swagger)
106
+ - `--no-tunnel`: disable auto ngrok tunnel for local URLs
107
+ - `--report [path]`: download PDF on completion (default `./report-<id>.pdf`)
108
+ - `--share`: enable public sharing after completion
109
+ - `--wait`: block until completion and set exit code based on result
110
+
111
+ - **ttt start-test <prompt>**
112
+
113
+ - Start a test from a natural language prompt. The backend derives the URL from your selected/last project, so you don't need to pass `--url`.
114
+ - Examples:
115
+ ```bash
116
+ ttt start-test "Smoke test the main user journey and generate a PDF report" --execute --wait
117
+ ttt start-test "API regression for orders endpoints" --type api --docs-url https://api.example.com/openapi.json --execute
118
+ ```
119
+ - Options:
120
+ - `--type <ui|api|mixed>`: defaults to `ui`
121
+ - `--execute`: execute generated test cases
122
+ - `--mode <all|priority|failed_only>`: defaults to `priority`
123
+ - `--project-id <id>` / `--team-id <id>`
124
+ - `--docs-url <openapi-url>`: API docs (OpenAPI/Swagger)
125
+ - `--report [path]`: download PDF on completion (default `./report-<id>.pdf`)
126
+ - `--share`: enable public sharing after completion
127
+ - `--wait`: block until completion and set exit code based on result
128
+
129
+ - **ttt stream <test-id>**
130
+
131
+ - Attach to an existing test and print textual progress only.
132
+
133
+ - **ttt status <test-id>**
134
+
135
+ - Print the test status JSON.
136
+
137
+ - **ttt restart <test-id>**
138
+
139
+ - Re-run a completed or failed test.
140
+
141
+ - **ttt report <test-id> --out <file.pdf>**
142
+
143
+ - Create (if needed) and download a PDF report.
144
+
145
+ - **ttt share <test-id>**
146
+ - Enable public sharing and print the public URL.
147
+
148
+ ## Real-time Streaming
149
+
150
+ The CLI connects to Socket.IO at `/socket.io` and emits `subscribe_test` with the test ID. It prints minimal, time-stamped lines for events like `test_started`, `test_progress`, `test_completed`, `test_failed`.
151
+
152
+ If websockets are blocked, use `ttt status <id>` to poll.
153
+
154
+ ## Tunnels (Local URLs)
155
+
156
+ When `--url` (or `--docs-url`) points to `localhost`/`127.0.0.1`, the CLI auto-starts an ngrok tunnel and injects the public URL into the request. For reliability, provide an ngrok authtoken:
157
+
158
+ ```bash
159
+ export TTT_NGROK_AUTHTOKEN=... # optional but recommended
160
+ ```
161
+
162
+ ## Configuration
163
+
164
+ - **Precedence**: CLI flags > environment variables > config file.
165
+ - **Config file**: `~/.timetotest/config.json`
166
+
167
+ Example (values are examples; your file will reflect your environment):
168
+
169
+ ```json
170
+ {
171
+ "apiUrl": "https://api.timetotest.tech",
172
+ "socketUrl": "https://api.timetotest.tech",
173
+ "auth": {"firebaseIdToken": "...", "expiresAt": 0},
174
+ "defaultProjectId": null,
175
+ "defaultTeamId": null,
176
+ "ngrok": {"authtoken": null}
177
+ }
178
+ ```
179
+
180
+ ## Environment Variables
181
+
182
+ - `TTT_API_URL` – override API base URL
183
+ - `TTT_SOCKET_URL` – override Socket.IO base URL
184
+ - `TTT_TOKEN` – Firebase ID token (overrides stored token)
185
+ - `TTT_NGROK_AUTHTOKEN` – ngrok account token
186
+
187
+ ## GitHub Actions (Example)
188
+
189
+ ```yaml
190
+ name: Time to Test
191
+ on:
192
+ push:
193
+ branches: [main]
194
+
195
+ jobs:
196
+ ttt:
197
+ runs-on: ubuntu-latest
198
+ steps:
199
+ - uses: actions/checkout@v4
200
+ - uses: actions/setup-node@v4
201
+ with:
202
+ node-version: "20"
203
+
204
+ - name: Install CLI
205
+ run: npm i -g @timetotest/cli
206
+
207
+ - name: Start App Under Test
208
+ run: |
209
+ npm ci
210
+ npm run build --if-present
211
+ npm start &
212
+ echo $! > app.pid
213
+ npx wait-on http://localhost:3000
214
+
215
+ - name: CLI Login (headless)
216
+ env:
217
+ TTT_EMAIL: ${{ secrets.TTT_EMAIL }}
218
+ TTT_PASSWORD: ${{ secrets.TTT_PASSWORD }}
219
+ TTT_FIREBASE_API_KEY: ${{ secrets.TTT_FIREBASE_API_KEY }}
220
+ run: ttt login --email "$TTT_EMAIL" --password "$TTT_PASSWORD" --api-key "$TTT_FIREBASE_API_KEY"
221
+
222
+ - name: Run Test
223
+ env:
224
+ TTT_API_URL: https://dev.timetotest.kinra.ng
225
+ TTT_SOCKET_URL: https://dev.timetotest.kinra.ng
226
+ TTT_NGROK_AUTHTOKEN: ${{ secrets.NGROK_AUTHTOKEN }}
227
+ run: |
228
+ ttt test \
229
+ --url http://localhost:3000 \
230
+ --type ui \
231
+ --execute \
232
+ --mode priority \
233
+ --project-id 123 \
234
+ --team-id 456 \
235
+ --report ./report.pdf \
236
+ --wait
237
+
238
+ - name: Upload Report (PDF)
239
+ uses: actions/upload-artifact@v4
240
+ with:
241
+ name: timetotest-report
242
+ path: ./report.pdf
243
+
244
+ - name: Stop App
245
+ if: always()
246
+ run: kill $(cat app.pid) || true
247
+ ```
248
+
249
+ ## Troubleshooting
250
+
251
+ - **401 Unauthorized**: run `ttt login` again or set `TTT_TOKEN`.
252
+ - **Tunnel issues**: set `TTT_NGROK_AUTHTOKEN`, ensure your local app is running and reachable.
253
+ - **Socket blocked**: use `ttt status <id>` for polling.
254
+ - **PDF not saving**: ensure the output path is writable.
255
+
256
+ ## Privacy & Security
257
+
258
+ - Your token is stored in `~/.timetotest/config.json` with restricted permissions.
259
+ - The CLI avoids logging secrets; still, prefer not to paste sensitive URLs directly in shared logs.
260
+
261
+ ## Feedback
262
+
263
+ We’d love to hear from you. Visit [Time to Test](https://timetotest.tech) for updates and support.
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { login } from "../src/commands/login.js";
4
+ import { test } from "../src/commands/test.js";
5
+ import { status } from "../src/commands/status.js";
6
+ import { restart } from "../src/commands/restart.js";
7
+ import { stream } from "../src/commands/stream.js";
8
+ import { report } from "../src/commands/report.js";
9
+ import { share } from "../src/commands/share.js";
10
+ import { ask } from "../src/commands/ask.js";
11
+ import { startTest } from "../src/commands/start-test.js";
12
+ import { applyStyledHelpRecursively } from "../src/lib/help.js";
13
+ const program = new Command();
14
+ program.name("ttt").description("Time to Test CLI").version("0.1.0");
15
+ program.addCommand(login);
16
+ program.addCommand(test);
17
+ program.addCommand(status);
18
+ program.addCommand(restart);
19
+ program.addCommand(stream);
20
+ program.addCommand(report);
21
+ program.addCommand(share);
22
+ program.addCommand(ask);
23
+ program.addCommand(startTest);
24
+ applyStyledHelpRecursively(program, "ttt");
25
+ // Default to `ask` when no subcommand is provided
26
+ if (process.argv.length <= 2) {
27
+ process.argv.push("ask");
28
+ }
29
+ program.parseAsync(process.argv);
30
+ //# sourceMappingURL=ttt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ttt.js","sourceRoot":"","sources":["../../bin/ttt.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,KAAK,EAAC,MAAM,0BAA0B,CAAC;AAC/C,OAAO,EAAC,IAAI,EAAC,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAC,KAAK,EAAC,MAAM,0BAA0B,CAAC;AAC/C,OAAO,EAAC,GAAG,EAAC,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAC,SAAS,EAAC,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAC,0BAA0B,EAAC,MAAM,oBAAoB,CAAC;AAE9D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAErE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC1B,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACzB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAC3B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAC3B,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAC3B,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC1B,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACxB,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9B,0BAA0B,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC3C,kDAAkD;AAClD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AACD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}