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 CHANGED
@@ -1,672 +1,88 @@
1
1
  # shiplightai
2
2
 
3
- The best way to write UI tests YAML with natural language steps. Easy for AI agents to create and maintain, yet clear for humans to understand and control.
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
- AI-powered execution with self-healing locators means near-zero maintenance — no more broken tests every time the UI changes. Compatible with Playwright, running alongside your existing `.test.ts` files with `npx playwright test` — no separate tooling needed.
5
+ **Full documentation: [docs.shiplight.ai](https://docs.shiplight.ai)**
6
6
 
7
- **AI does the work. Humans have visibility and control.**
7
+ ## Quick start
8
8
 
9
- ## Quick Start
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
- ANTHROPIC_API_KEY=sk-ant-...
48
- # GOOGLE_API_KEY=...
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
- `shiplightConfig()` auto-discovers `.env` files by walking up the directory tree no manual `dotenv` setup needed.
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
- ### 5. Run
22
+ Or add Shiplight to an existing Playwright project:
71
23
 
72
24
  ```bash
73
- npx playwright test
25
+ npm install shiplightai @playwright/test
74
26
  ```
75
27
 
76
- Playwright discovers both `*.test.ts` and `*.test.yaml` files. YAML files are transparently transpiled to `.yaml.spec.ts` files next to the source.
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
- ## Project Structure
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
- A typical Shiplight test project follows standard Playwright conventions — a `playwright.config.ts` at the root, test files in subdirectories, and a `.gitignore`. On top of that, Shiplight adds two config files: `.env` for API keys (shared across all projects) and `shiplight.config.json` for per-project login credentials (only needed if the app requires authentication).
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
- ### Root files
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: false,
54
+ headless: true,
131
55
  viewport: { width: 1280, height: 720 },
132
56
  },
133
57
  });
134
58
  ```
135
59
 
136
- `shiplightConfig()` runs during Playwright config loading and:
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
- #### IF / ELSE (conditional)
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
- Conditional branching with AI or JavaScript conditions.
64
+ ## Environment variables
425
65
 
426
- ```yaml
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
- #### WHILE loop
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
- ### Supported Actions
74
+ The AI model is auto-selected from the first key set. Override with `WEB_AGENT_MODEL=<model>`.
455
75
 
456
- Actions used in `action_entity.action_data.action_name`:
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
- | Action | kwargs | Description |
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
- ### Locators
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
- Action entities can specify element locators in two ways:
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
- If both are present, `locator` takes priority. If neither is present, the AI agent resolves the element from the action description.
497
-
498
- ### Frames
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)