shiplightai 0.1.49 → 0.1.50
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 +44 -628
- package/dist/cjs/debugger-pw.cjs +45 -45
- package/dist/cjs/fixture.cjs +78 -76
- package/dist/cjs/index.cjs +55 -53
- package/dist/cli.js +2 -2
- package/dist/debugger-pw.js +46 -46
- package/dist/fixture.d.ts +25 -1
- package/dist/fixture.js +79 -77
- package/dist/index.js +56 -54
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,672 +1,88 @@
|
|
|
1
1
|
# shiplightai
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AI-powered end-to-end testing for Playwright. Write tests as YAML with natural-language steps, run them alongside your existing `.test.ts` files, get self-healing locators and a visual debugger. One package ships both the `shiplight` CLI and the library you wire into `playwright.config.ts`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Full documentation: [docs.shiplight.ai](https://docs.shiplight.ai)**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Quick start
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Scaffold a new test project in under a minute:
|
|
10
10
|
|
|
11
|
-
### 1. Install
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install -D shiplightai @playwright/test
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 2. Configure
|
|
18
|
-
|
|
19
|
-
In your `playwright.config.ts`:
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
import { defineConfig, shiplightConfig } from 'shiplightai';
|
|
23
|
-
|
|
24
|
-
export default defineConfig({
|
|
25
|
-
...shiplightConfig(),
|
|
26
|
-
|
|
27
|
-
testDir: './tests',
|
|
28
|
-
use: {
|
|
29
|
-
headless: true,
|
|
30
|
-
viewport: { width: 1280, height: 720 },
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### 3. Set up API keys
|
|
36
|
-
|
|
37
|
-
At least one AI API key is required. You can either export it directly or use a `.env` file.
|
|
38
|
-
|
|
39
|
-
**Option A: Environment variable**
|
|
40
|
-
```bash
|
|
41
|
-
export ANTHROPIC_API_KEY=sk-ant-...
|
|
42
|
-
# or export GOOGLE_API_KEY=...
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**Option B: `.env` file** (in your test directory or project root)
|
|
46
11
|
```bash
|
|
47
|
-
|
|
48
|
-
|
|
12
|
+
npx shiplightai@latest create ./my-tests
|
|
13
|
+
cd my-tests
|
|
14
|
+
cp .env.example .env # then set one of GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY
|
|
15
|
+
npm install
|
|
16
|
+
npx playwright install chromium
|
|
17
|
+
npx shiplight test # runs the scaffolded starter test
|
|
49
18
|
```
|
|
50
19
|
|
|
51
|
-
`
|
|
52
|
-
|
|
53
|
-
The AI model is auto-detected from your API key (`ANTHROPIC_API_KEY` → `claude-haiku-4-5`, `GOOGLE_API_KEY` → `gemini-3.1-flash-lite-preview`, `OPENAI_API_KEY` → `gpt-5.4-mini`). Set `WEB_AGENT_MODEL` to override.
|
|
54
|
-
|
|
55
|
-
### 4. Write a YAML test
|
|
56
|
-
|
|
57
|
-
Create `tests/login.test.yaml`:
|
|
58
|
-
|
|
59
|
-
```yaml
|
|
60
|
-
goal: Verify user can log in
|
|
61
|
-
url: https://example.com/login
|
|
62
|
-
|
|
63
|
-
statements:
|
|
64
|
-
- Click on the username field and type "testuser"
|
|
65
|
-
- Click on the password field and type "secret123"
|
|
66
|
-
- Click the Login button
|
|
67
|
-
- "VERIFY: Dashboard page is visible"
|
|
68
|
-
```
|
|
20
|
+
The scaffolder writes `package.json`, `playwright.config.ts`, `.env.example`, `.gitignore`, and a runnable `tests/example.test.yaml` that exercises a live site. Open `shiplight-report/index.html` after the run to see per-step screenshots, videos, and traces.
|
|
69
21
|
|
|
70
|
-
|
|
22
|
+
Or add Shiplight to an existing Playwright project:
|
|
71
23
|
|
|
72
24
|
```bash
|
|
73
|
-
|
|
25
|
+
npm install shiplightai @playwright/test
|
|
74
26
|
```
|
|
75
27
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### 6. Gitignore generated files
|
|
79
|
-
|
|
80
|
-
Add to your `.gitignore`:
|
|
28
|
+
## CLI
|
|
81
29
|
|
|
82
|
-
|
|
83
|
-
*.yaml.spec.ts
|
|
84
|
-
auth.setup.ts
|
|
85
|
-
.auth/
|
|
86
|
-
.env
|
|
87
|
-
```
|
|
30
|
+
Every command is invoked via `npx shiplight <command>` from inside a project that has `shiplightai` installed.
|
|
88
31
|
|
|
89
|
-
|
|
32
|
+
| Command | Purpose |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `shiplight create <path>` | Scaffold a new test project |
|
|
35
|
+
| `shiplight test [args]` | Run your YAML and Playwright test suite (forwards all Playwright flags) |
|
|
36
|
+
| `shiplight debug <file>` | Launch the interactive visual debugger for a YAML test |
|
|
37
|
+
| `shiplight report [folder]` | Regenerate or merge HTML reports |
|
|
38
|
+
| `shiplight transpile [glob]` | Transpile YAML tests to `.yaml.spec.ts` (usually automatic) |
|
|
90
39
|
|
|
91
|
-
|
|
40
|
+
Full reference with flags, options, and troubleshooting: **[docs.shiplight.ai/local/cli-reference](https://docs.shiplight.ai/local/cli-reference)**.
|
|
92
41
|
|
|
93
|
-
|
|
94
|
-
my-tests/
|
|
95
|
-
├── playwright.config.ts
|
|
96
|
-
├── package.json
|
|
97
|
-
├── .env # API keys — shared by ALL projects (gitignored)
|
|
98
|
-
├── .env.example # Checked in, documents required keys
|
|
99
|
-
├── .gitignore
|
|
100
|
-
│
|
|
101
|
-
├── airbnb/ # Project 1: public site, no login needed
|
|
102
|
-
│ ├── search.test.yaml
|
|
103
|
-
│ ├── filter.test.yaml
|
|
104
|
-
│ └── listing.test.yaml
|
|
105
|
-
│
|
|
106
|
-
├── my-saas-app/ # Project 2: requires login
|
|
107
|
-
│ ├── shiplight.config.json # {"url":"https://my-saas.com","username":"...","password":"..."}
|
|
108
|
-
│ ├── dashboard.test.yaml
|
|
109
|
-
│ ├── settings.test.yaml
|
|
110
|
-
│ └── billing.test.yaml
|
|
111
|
-
│
|
|
112
|
-
└── admin-portal/ # Project 3: different app, different login
|
|
113
|
-
├── shiplight.config.json # {"url":"https://admin.my-saas.com","username":"...","password":"..."}
|
|
114
|
-
├── users.test.yaml
|
|
115
|
-
└── audit-log.test.yaml
|
|
116
|
-
```
|
|
42
|
+
## Library
|
|
117
43
|
|
|
118
|
-
|
|
44
|
+
Wire up YAML support and the Shiplight reporter in `playwright.config.ts`:
|
|
119
45
|
|
|
120
|
-
**`playwright.config.ts`** — Playwright config with `shiplightConfig()`:
|
|
121
46
|
```ts
|
|
122
47
|
import { defineConfig, shiplightConfig } from 'shiplightai';
|
|
123
48
|
|
|
124
49
|
export default defineConfig({
|
|
125
50
|
...shiplightConfig(),
|
|
126
51
|
|
|
127
|
-
testDir: '
|
|
128
|
-
timeout: 120_000,
|
|
52
|
+
testDir: './tests',
|
|
129
53
|
use: {
|
|
130
|
-
headless:
|
|
54
|
+
headless: true,
|
|
131
55
|
viewport: { width: 1280, height: 720 },
|
|
132
56
|
},
|
|
133
57
|
});
|
|
134
58
|
```
|
|
135
59
|
|
|
136
|
-
`shiplightConfig()`
|
|
137
|
-
1. Walks up from `scanDir` to the project root looking for `.env` files and loads them (closer files take precedence)
|
|
138
|
-
2. Scans for `**/*.test.yaml` files
|
|
139
|
-
3. Transpiles each to a `*.yaml.spec.ts` file next to the source
|
|
140
|
-
|
|
141
|
-
Playwright then discovers the generated `.yaml.spec.ts` files through its default `testMatch` pattern. If you override `testMatch`, make sure it includes `*.spec.ts`.
|
|
142
|
-
|
|
143
|
-
**`.env`** — API keys, shared by all projects (gitignored):
|
|
144
|
-
```bash
|
|
145
|
-
# At least one required. Model is auto-detected from the key.
|
|
146
|
-
ANTHROPIC_API_KEY=sk-ant-...
|
|
147
|
-
# GOOGLE_API_KEY=...
|
|
148
|
-
|
|
149
|
-
# Optional: override auto-detected model
|
|
150
|
-
# WEB_AGENT_MODEL=claude-haiku-4-5
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
**`.gitignore`**:
|
|
154
|
-
```
|
|
155
|
-
node_modules/
|
|
156
|
-
test-results/
|
|
157
|
-
*.yaml.spec.ts
|
|
158
|
-
auth.setup.ts
|
|
159
|
-
.auth/
|
|
160
|
-
.env
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Subdirectories
|
|
164
|
-
|
|
165
|
-
Each subdirectory is a separate project that can test a different application. Subdirectories that require login include a `shiplight.config.json` with credentials. Subdirectories that don't need login (e.g., public sites) simply omit it.
|
|
166
|
-
|
|
167
|
-
**`my-saas-app/shiplight.config.json`** — login + variables for one app:
|
|
168
|
-
```json
|
|
169
|
-
{
|
|
170
|
-
"url": "https://my-saas.com",
|
|
171
|
-
"username": "qa@my-saas.com",
|
|
172
|
-
"password": "test-password",
|
|
173
|
-
"variables": {
|
|
174
|
-
"BASE_URL": "https://my-saas.com",
|
|
175
|
-
"API_TOKEN": { "value": "sk-test-...", "sensitive": true }
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**`admin-portal/shiplight.config.json`** — different app, different credentials:
|
|
181
|
-
```json
|
|
182
|
-
{
|
|
183
|
-
"url": "https://admin.my-saas.com",
|
|
184
|
-
"username": "admin@my-saas.com",
|
|
185
|
-
"password": "admin-password"
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Running tests
|
|
190
|
-
|
|
191
|
-
**Run all tests:**
|
|
192
|
-
```bash
|
|
193
|
-
npx playwright test
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Run one project:**
|
|
197
|
-
```bash
|
|
198
|
-
npx playwright test my-saas-app/
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**Debug a single test:**
|
|
202
|
-
```bash
|
|
203
|
-
shiplight debug my-saas-app/dashboard.test.yaml
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
The visual debugger uses the same config discovery — it finds `my-saas-app/shiplight.config.json` for login and `.env` at the root for API keys.
|
|
207
|
-
|
|
208
|
-
## Environment Variables
|
|
209
|
-
|
|
210
|
-
| Variable | Description | Default |
|
|
211
|
-
|---|---|---|
|
|
212
|
-
| `ANTHROPIC_API_KEY` | Anthropic API key (for Claude models) | — |
|
|
213
|
-
| `GOOGLE_API_KEY` | Google AI API key (for Gemini models) | — |
|
|
214
|
-
| `OPENAI_API_KEY` | OpenAI API key (for GPT/o-series models) | — |
|
|
215
|
-
| `WEB_AGENT_MODEL` | AI model override | Auto-detected from API key |
|
|
216
|
-
| `OPENAI_BASE_URL` | Custom base URL for OpenAI-compatible APIs | — |
|
|
217
|
-
| `SHIPLIGHT_LOGIN_EMAIL` | Login email (with `_PASSWORD`, overrides `shiplight.config.json`) | — |
|
|
218
|
-
| `SHIPLIGHT_LOGIN_PASSWORD` | Login password (with `_EMAIL`, overrides `shiplight.config.json`) | — |
|
|
219
|
-
| `SHIPLIGHT_LOGIN_URL` | Login page URL (overrides `shiplight.config.json` `url`) | — |
|
|
220
|
-
| `SHIPLIGHT_LOGIN_TOTP_SECRET` | TOTP secret for 2FA (overrides `shiplight.config.json` `totp_secret`) | — |
|
|
221
|
-
| `PLAYWRIGHT_STARTING_URL` | Override the starting URL for all tests | — |
|
|
222
|
-
|
|
223
|
-
At least one AI API key is required. The model is auto-detected: `ANTHROPIC_API_KEY` defaults to `claude-haiku-4-5`, `GOOGLE_API_KEY` defaults to `gemini-3.1-flash-lite-preview`, `OPENAI_API_KEY` defaults to `gpt-5.4-mini`. Set `WEB_AGENT_MODEL` to override.
|
|
224
|
-
|
|
225
|
-
## Configuration Options
|
|
226
|
-
|
|
227
|
-
```ts
|
|
228
|
-
shiplightConfig({
|
|
229
|
-
// Directory to scan for .test.yaml files (default: process.cwd())
|
|
230
|
-
scanDir: './tests',
|
|
231
|
-
|
|
232
|
-
// API key for cloud features (optional)
|
|
233
|
-
apiKey: process.env.SHIPLIGHT_API_KEY,
|
|
234
|
-
|
|
235
|
-
// Auto-discover .env files by walking up the directory tree (default: true)
|
|
236
|
-
// Set to false for CI pipelines where env vars are injected externally
|
|
237
|
-
dotenv: false,
|
|
238
|
-
})
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Agent Fixture
|
|
242
|
-
|
|
243
|
-
The package exports a custom `test` that extends Playwright's `test` with an additional `agent` fixture. It works exactly like Playwright's `test` in every other way — same API, same hooks, same assertions. `expect` is re-exported from Playwright unchanged. Generated YAML tests use this automatically:
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
import { test, expect } from 'shiplightai/fixture';
|
|
247
|
-
|
|
248
|
-
test('my test', async ({ page, agent }) => {
|
|
249
|
-
// `agent` is a pre-configured WebAgent instance
|
|
250
|
-
// `page` is the standard Playwright page
|
|
251
|
-
});
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
You can also use the fixture in your hand-written `.test.ts` files to get the same `agent` instance:
|
|
255
|
-
|
|
256
|
-
```ts
|
|
257
|
-
// tests/custom.test.ts
|
|
258
|
-
import { test, expect } from 'shiplightai/fixture';
|
|
259
|
-
|
|
260
|
-
test('custom test with agent', async ({ page, agent }) => {
|
|
261
|
-
await page.goto('https://example.com');
|
|
262
|
-
await agent.run(page, 'Click the login button', 'step-1');
|
|
263
|
-
await agent.assert(page, 'User is on the dashboard', 'step-2');
|
|
264
|
-
});
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Authentication (Optional)
|
|
268
|
-
|
|
269
|
-
If your app requires login, add credentials to `shiplight.config.json` and wire up a Playwright setup project. `shiplightConfig()` auto-generates an `auth.setup.ts` file in each directory that has credentials. Skip this section if you're testing public pages.
|
|
270
|
-
|
|
271
|
-
### 1. Create `shiplight.config.json`
|
|
272
|
-
|
|
273
|
-
Place this in your test subdirectory (see [Project Structure](#project-structure) above):
|
|
274
|
-
|
|
275
|
-
```json
|
|
276
|
-
{
|
|
277
|
-
"url": "https://your-app.com",
|
|
278
|
-
"username": "testuser@example.com",
|
|
279
|
-
"password": "your-password",
|
|
280
|
-
"totp_secret": "JBSWY3DPEHPK3PXP"
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
The `totp_secret` field is optional — only needed if your app uses 2FA.
|
|
285
|
-
|
|
286
|
-
### 2. Add setup project to `playwright.config.ts`
|
|
287
|
-
|
|
288
|
-
Use Playwright's standard project dependencies to run the auto-generated `auth.setup.ts` before authenticated tests:
|
|
289
|
-
|
|
290
|
-
```ts
|
|
291
|
-
export default defineConfig({
|
|
292
|
-
...shiplightConfig(),
|
|
293
|
-
|
|
294
|
-
projects: [
|
|
295
|
-
// Setup project — runs auto-generated auth.setup.ts
|
|
296
|
-
{ name: 'my-app-setup', testDir: './my-app', testMatch: 'auth.setup.ts' },
|
|
297
|
-
{
|
|
298
|
-
name: 'my-app',
|
|
299
|
-
testDir: './my-app',
|
|
300
|
-
dependencies: ['my-app-setup'],
|
|
301
|
-
use: { storageState: './my-app/.auth/storage-state.json' },
|
|
302
|
-
},
|
|
303
|
-
],
|
|
304
|
-
});
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
That's it. No `global-setup.ts` needed — `shiplightConfig()` generates `auth.setup.ts` automatically from your `shiplight.config.json`.
|
|
308
|
-
|
|
309
|
-
### Credential resolution order
|
|
310
|
-
|
|
311
|
-
Login credentials are resolved in this order (first match wins):
|
|
312
|
-
|
|
313
|
-
1. **Environment variables**: `SHIPLIGHT_LOGIN_EMAIL` + `SHIPLIGHT_LOGIN_PASSWORD` (+ optional `SHIPLIGHT_LOGIN_URL`)
|
|
314
|
-
2. **Config file**: `shiplight.config.json` or `login.config.json`, discovered by walking up from the test directory
|
|
315
|
-
|
|
316
|
-
This means you can use `shiplight.config.json` for local development and override with env vars in CI.
|
|
317
|
-
|
|
318
|
-
### How it works
|
|
319
|
-
|
|
320
|
-
1. `shiplightConfig()` scans for `shiplight.config.json` files with credentials and generates `auth.setup.ts` next to each
|
|
321
|
-
2. Playwright runs the setup project before dependent projects
|
|
322
|
-
3. The AI agent logs in using `shiplightai`'s `WebAgent.loginPage()` — no fragile selectors
|
|
323
|
-
4. The resulting cookies/localStorage are saved to `<dir>/.auth/storage-state.json`
|
|
324
|
-
5. All tests in the dependent project load this storage state — every test starts already authenticated
|
|
325
|
-
6. Each directory is self-contained: its own credentials, its own auth state, its own setup
|
|
326
|
-
|
|
327
|
-
### 2FA / TOTP support
|
|
328
|
-
|
|
329
|
-
Set `totp_secret` in `shiplight.config.json` or `SHIPLIGHT_LOGIN_TOTP_SECRET` as an env var, and the agent will generate and enter the 2FA code automatically.
|
|
330
|
-
|
|
331
|
-
## YAML Test Format
|
|
332
|
-
|
|
333
|
-
### Basic Structure
|
|
334
|
-
|
|
335
|
-
```yaml
|
|
336
|
-
goal: Description of what this test verifies
|
|
337
|
-
url: https://your-app.com/starting-page
|
|
338
|
-
|
|
339
|
-
statements:
|
|
340
|
-
- Step described in natural language
|
|
341
|
-
- Another step
|
|
342
|
-
- "VERIFY: Expected outcome"
|
|
343
|
-
|
|
344
|
-
teardown:
|
|
345
|
-
- Clean up step
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
| Field | Required | Description |
|
|
349
|
-
|---|---|---|
|
|
350
|
-
| `goal` | Yes | Test description (used as the Playwright test name) |
|
|
351
|
-
| `url` | Yes | Starting URL to navigate to |
|
|
352
|
-
| `statements` | Yes | List of test steps |
|
|
353
|
-
| `teardown` | No | Steps that always run after the test (like `finally`) |
|
|
354
|
-
|
|
355
|
-
### Statement Types
|
|
356
|
-
|
|
357
|
-
#### Draft (natural language)
|
|
358
|
-
|
|
359
|
-
Plain strings are AI-resolved steps. The agent figures out what to click, type, etc.
|
|
360
|
-
|
|
361
|
-
```yaml
|
|
362
|
-
statements:
|
|
363
|
-
- Navigate to the settings page
|
|
364
|
-
- Click the "Delete Account" button
|
|
365
|
-
- Type "confirm" in the confirmation dialog
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
#### VERIFY
|
|
369
|
-
|
|
370
|
-
Asserts a condition using AI. Must be a quoted string prefixed with `VERIFY:`.
|
|
371
|
-
|
|
372
|
-
```yaml
|
|
373
|
-
statements:
|
|
374
|
-
- "VERIFY: The success message is displayed"
|
|
375
|
-
- "VERIFY: User is redirected to the dashboard"
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
#### ACTION (with action entity)
|
|
379
|
-
|
|
380
|
-
Deterministic actions with explicit locators. These replay fast (~1s) without AI.
|
|
381
|
-
|
|
382
|
-
```yaml
|
|
383
|
-
statements:
|
|
384
|
-
- description: Click the Submit button
|
|
385
|
-
action_entity:
|
|
386
|
-
action_description: Click the Submit button
|
|
387
|
-
locator: "getByRole('button', { name: 'Submit' })"
|
|
388
|
-
action_data:
|
|
389
|
-
action_name: click
|
|
390
|
-
kwargs: {}
|
|
391
|
-
|
|
392
|
-
- description: Type email address
|
|
393
|
-
action_entity:
|
|
394
|
-
action_description: Type email address
|
|
395
|
-
locator: "getByLabel('Email')"
|
|
396
|
-
action_data:
|
|
397
|
-
action_name: input_text
|
|
398
|
-
kwargs:
|
|
399
|
-
text: "user@example.com"
|
|
400
|
-
|
|
401
|
-
- description: Press Enter
|
|
402
|
-
action_entity:
|
|
403
|
-
action_data:
|
|
404
|
-
action_name: press
|
|
405
|
-
kwargs:
|
|
406
|
-
keys: Enter
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
#### STEP (grouping)
|
|
410
|
-
|
|
411
|
-
Groups related statements under a label.
|
|
412
|
-
|
|
413
|
-
```yaml
|
|
414
|
-
statements:
|
|
415
|
-
- STEP: Fill in the registration form
|
|
416
|
-
statements:
|
|
417
|
-
- Type "John" in the first name field
|
|
418
|
-
- Type "Doe" in the last name field
|
|
419
|
-
- Type "john@example.com" in the email field
|
|
420
|
-
```
|
|
60
|
+
`shiplightConfig()` returns a partial Playwright config that wires in YAML transpilation, auto-discovered `.env` files, and the HTML reporter. Spread it into your own `defineConfig` and override whatever you need.
|
|
421
61
|
|
|
422
|
-
|
|
62
|
+
For the YAML statement language, authentication, variables, templates, and custom functions: **[docs.shiplight.ai/local](https://docs.shiplight.ai/local/yaml-tests)**.
|
|
423
63
|
|
|
424
|
-
|
|
64
|
+
## Environment variables
|
|
425
65
|
|
|
426
|
-
|
|
427
|
-
statements:
|
|
428
|
-
# AI condition
|
|
429
|
-
- IF: A cookie consent banner is visible
|
|
430
|
-
THEN:
|
|
431
|
-
- Click the Accept button
|
|
432
|
-
ELSE:
|
|
433
|
-
- "VERIFY: No banner is blocking the page"
|
|
66
|
+
Set at least one LLM provider API key in `.env` before running tests:
|
|
434
67
|
|
|
435
|
-
# JavaScript condition
|
|
436
|
-
- IF: "js: page.url().includes('/login')"
|
|
437
|
-
THEN:
|
|
438
|
-
- Enter credentials and log in
|
|
439
68
|
```
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
Repeating steps with a timeout.
|
|
444
|
-
|
|
445
|
-
```yaml
|
|
446
|
-
statements:
|
|
447
|
-
- WHILE: There are more items in the list
|
|
448
|
-
DO:
|
|
449
|
-
- Click the next item
|
|
450
|
-
- "VERIFY: Item details are shown"
|
|
451
|
-
timeout_ms: 30000
|
|
69
|
+
GOOGLE_API_KEY=...
|
|
70
|
+
# or ANTHROPIC_API_KEY=sk-ant-...
|
|
71
|
+
# or OPENAI_API_KEY=sk-...
|
|
452
72
|
```
|
|
453
73
|
|
|
454
|
-
|
|
74
|
+
The AI model is auto-selected from the first key set. Override with `WEB_AGENT_MODEL=<model>`.
|
|
455
75
|
|
|
456
|
-
|
|
76
|
+
Shiplight uses an **explicit env var allowlist**: only the vars it forwards into its internal SDK config are accessible to the agent. Any env var not on the list is invisible to the SDK by design. Full list (`OPENAI_BASE_URL`, Vertex AI routing, Mailgun keys, etc.): **[docs.shiplight.ai/local/cli-reference#environment-variables](https://docs.shiplight.ai/local/cli-reference)**.
|
|
457
77
|
|
|
458
|
-
|
|
459
|
-
|---|---|---|
|
|
460
|
-
| `click` | — | Click an element |
|
|
461
|
-
| `double_click` | — | Double-click an element |
|
|
462
|
-
| `right_click` | — | Right-click an element |
|
|
463
|
-
| `hover` | — | Hover over an element |
|
|
464
|
-
| `input_text` | `text` | Type text into an input |
|
|
465
|
-
| `clear_input` | — | Clear an input field |
|
|
466
|
-
| `press` | `keys` | Press a keyboard key (e.g., `Enter`, `Tab`) |
|
|
467
|
-
| `send_keys_on_element` | `keys` | Press a key on a specific element |
|
|
468
|
-
| `select_dropdown_option` | `text` | Select a dropdown option by text |
|
|
469
|
-
| `scroll` | `down`, `num_pages` | Scroll the page |
|
|
470
|
-
| `scroll_to_text` | `text` | Scroll to text on the page |
|
|
471
|
-
| `go_to_url` | `url`, `new_tab` | Navigate to a URL |
|
|
472
|
-
| `go_back` | — | Browser back |
|
|
473
|
-
| `reload_page` | — | Reload the page |
|
|
474
|
-
| `wait` | `seconds` | Wait for a duration |
|
|
475
|
-
| `wait_for_page_ready` | — | Wait for page load |
|
|
476
|
-
| `verify` | `statement` or `code` | Assert a condition (AI or JS) |
|
|
477
|
-
| `js_code` | `code` | Run inline JavaScript |
|
|
478
|
-
| `function` | `functionName`, `parameterNames`, `parameterValues` | Call a function |
|
|
479
|
-
| `switch_tab` | `tab_index` | Switch browser tab |
|
|
480
|
-
| `close_tab` | — | Close current tab |
|
|
481
|
-
| `upload_file` | `file_path` | Upload a file |
|
|
482
|
-
| `save_variable` | `name`, `value` | Save a variable for later use |
|
|
78
|
+
## Requirements
|
|
483
79
|
|
|
484
|
-
|
|
80
|
+
- **Node.js >= 22**
|
|
81
|
+
- **`@playwright/test` 1.58.2** — declared as a peer dependency and installed automatically by `npm install`
|
|
82
|
+
- **Chromium** — install on demand with `npx playwright install chromium`
|
|
485
83
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
```yaml
|
|
489
|
-
# Playwright locator (preferred)
|
|
490
|
-
locator: "getByRole('button', { name: 'Submit' })"
|
|
491
|
-
|
|
492
|
-
# XPath
|
|
493
|
-
xpath: "//button[@id='submit']"
|
|
494
|
-
```
|
|
84
|
+
## Links
|
|
495
85
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
For elements inside iframes:
|
|
501
|
-
|
|
502
|
-
```yaml
|
|
503
|
-
action_entity:
|
|
504
|
-
frame_path:
|
|
505
|
-
- "iframe#main"
|
|
506
|
-
locator: "getByText('Hello')"
|
|
507
|
-
action_data:
|
|
508
|
-
action_name: click
|
|
509
|
-
kwargs: {}
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
## Extensions
|
|
513
|
-
|
|
514
|
-
### Custom Test Name
|
|
515
|
-
|
|
516
|
-
Override the Playwright test name (defaults to `goal`):
|
|
517
|
-
|
|
518
|
-
```yaml
|
|
519
|
-
name: Login with valid credentials
|
|
520
|
-
goal: Verify login flow works
|
|
521
|
-
url: https://example.com
|
|
522
|
-
statements:
|
|
523
|
-
- ...
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### Tags
|
|
527
|
-
|
|
528
|
-
Add Playwright tags for filtering with `--grep`:
|
|
529
|
-
|
|
530
|
-
```yaml
|
|
531
|
-
tags:
|
|
532
|
-
- smoke
|
|
533
|
-
- auth
|
|
534
|
-
goal: Login test
|
|
535
|
-
url: https://example.com
|
|
536
|
-
statements:
|
|
537
|
-
- ...
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
Run: `npx playwright test --grep @smoke`
|
|
541
|
-
|
|
542
|
-
### Playwright Fixtures
|
|
543
|
-
|
|
544
|
-
Pass options to `test.use()`:
|
|
545
|
-
|
|
546
|
-
```yaml
|
|
547
|
-
use:
|
|
548
|
-
viewport:
|
|
549
|
-
width: 375
|
|
550
|
-
height: 812
|
|
551
|
-
locale: fr-FR
|
|
552
|
-
goal: Mobile French layout
|
|
553
|
-
url: https://example.com
|
|
554
|
-
statements:
|
|
555
|
-
- ...
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
## Variables
|
|
559
|
-
|
|
560
|
-
Use `{{VAR_NAME}}` syntax in YAML tests to reference variables. Variables are resolved at runtime.
|
|
561
|
-
|
|
562
|
-
```yaml
|
|
563
|
-
statements:
|
|
564
|
-
- description: Type username
|
|
565
|
-
action_entity:
|
|
566
|
-
locator: "getByLabel('Username')"
|
|
567
|
-
action_data:
|
|
568
|
-
action_name: input_text
|
|
569
|
-
kwargs:
|
|
570
|
-
text: "{{TEST_USER}}"
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### Defining variables in `shiplight.config.json`
|
|
574
|
-
|
|
575
|
-
Declare variable defaults in your project's `shiplight.config.json`. These are loaded before each test runs.
|
|
576
|
-
|
|
577
|
-
```json
|
|
578
|
-
{
|
|
579
|
-
"url": "https://my-app.com",
|
|
580
|
-
"username": "qa@my-app.com",
|
|
581
|
-
"password": "test-password",
|
|
582
|
-
"variables": {
|
|
583
|
-
"TEST_USER": "standard_user",
|
|
584
|
-
"TEST_PASS": { "value": "secret_sauce", "sensitive": true }
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
Variables can be either:
|
|
590
|
-
- **Plain string** — `"TEST_USER": "standard_user"`
|
|
591
|
-
- **Object with sensitive flag** — `"TEST_PASS": { "value": "secret_sauce", "sensitive": true }` (masked in logs)
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
## Templates
|
|
595
|
-
|
|
596
|
-
Extract reusable flows into template files and include them with `template:`.
|
|
597
|
-
|
|
598
|
-
### Template file (`templates/login.yaml`):
|
|
599
|
-
|
|
600
|
-
```yaml
|
|
601
|
-
params:
|
|
602
|
-
- username
|
|
603
|
-
- password
|
|
604
|
-
|
|
605
|
-
statements:
|
|
606
|
-
- description: Enter username
|
|
607
|
-
action_entity:
|
|
608
|
-
locator: "getByLabel('Username')"
|
|
609
|
-
action_data:
|
|
610
|
-
action_name: input_text
|
|
611
|
-
kwargs:
|
|
612
|
-
text: "{{username}}"
|
|
613
|
-
- description: Enter password
|
|
614
|
-
action_entity:
|
|
615
|
-
locator: "getByLabel('Password')"
|
|
616
|
-
action_data:
|
|
617
|
-
action_name: input_text
|
|
618
|
-
kwargs:
|
|
619
|
-
text: "{{password}}"
|
|
620
|
-
- description: Click login
|
|
621
|
-
action_entity:
|
|
622
|
-
locator: "getByRole('button', { name: 'Log in' })"
|
|
623
|
-
action_data:
|
|
624
|
-
action_name: click
|
|
625
|
-
kwargs: {}
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
### Using the template:
|
|
629
|
-
|
|
630
|
-
```yaml
|
|
631
|
-
goal: Purchase flow
|
|
632
|
-
url: https://example.com
|
|
633
|
-
|
|
634
|
-
statements:
|
|
635
|
-
- template: ../templates/login.yaml
|
|
636
|
-
params:
|
|
637
|
-
username: "{{TEST_USER}}"
|
|
638
|
-
password: "{{TEST_PASS}}"
|
|
639
|
-
- Navigate to the checkout page
|
|
640
|
-
- "VERIFY: Order summary is displayed"
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
Template params (`{{username}}`) are substituted at transpile time. Variables (`{{TEST_USER}}`) pass through and are resolved at runtime.
|
|
644
|
-
|
|
645
|
-
Templates can be nested (max depth: 5) and circular references are detected.
|
|
646
|
-
|
|
647
|
-
## Custom Functions
|
|
648
|
-
|
|
649
|
-
Call TypeScript functions from YAML using the `function` action with `file#export` syntax:
|
|
650
|
-
|
|
651
|
-
```yaml
|
|
652
|
-
statements:
|
|
653
|
-
- description: Seed test data
|
|
654
|
-
action_entity:
|
|
655
|
-
action_data:
|
|
656
|
-
action_name: function
|
|
657
|
-
kwargs:
|
|
658
|
-
functionName: "../helpers/seed.ts#createTestUser"
|
|
659
|
-
parameterNames:
|
|
660
|
-
- page
|
|
661
|
-
- email
|
|
662
|
-
parameterValues:
|
|
663
|
-
- page
|
|
664
|
-
- "test@example.com"
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
This generates:
|
|
668
|
-
```ts
|
|
669
|
-
import { createTestUser } from '../helpers/seed';
|
|
670
|
-
// ...
|
|
671
|
-
await createTestUser(page, "test@example.com");
|
|
672
|
-
```
|
|
86
|
+
- **Documentation:** [docs.shiplight.ai](https://docs.shiplight.ai)
|
|
87
|
+
- **VS Code extension:** [github.com/ShiplightAI/vscode-extension](https://github.com/ShiplightAI/vscode-extension)
|
|
88
|
+
- **Cloud platform:** [shiplight.ai](https://www.shiplight.ai)
|