@appliqation/automation-sdk 2.5.1 → 2.8.0

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,169 +1,94 @@
1
1
  # Appliqation Automation SDK
2
2
 
3
- A powerful SDK for integrating Playwright test results with the Appliqation test management portal.
3
+ Playwright reporter and CLI for Appliqation: authenticate against a gated
4
+ application, run your suite, and report results back to Appliqation with
5
+ zero manual login scripts and no separate test-runner integration.
4
6
 
5
- **What it does:**
6
- - ✅ Automatically creates test runs in Appliqation
7
- - ✅ Handles browser authentication with JWT tokens
8
- - ✅ Reports test results (passed/failed/skipped) to your portal
9
- - ✅ Tracks browser, OS, and device information
10
- - ✅ Manages test case mappings via UUIDs
7
+ ## What it does
11
8
 
12
- **Perfect for:**
13
- - QA teams running automated regression tests
14
- - CI/CD pipelines needing test result tracking
15
- - Teams using Appliqation for test management
9
+ - Creates and reports to Appliqation test runs directly from `playwright test`
10
+ - Authenticates against your application under test — either via a portable,
11
+ customer-defined login flow (`defineLogin`/`setupAuth`) or JWT-based
12
+ browser authentication, both usable in CI and locally
13
+ - Maps Playwright tests to Appliqation test cases via UUID, and reports
14
+ pass/fail/skip results, browser/OS/device metadata, and orphan tests
15
+ - Scopes a run to a single Scenario or an entire Test Set (smoke, sanity,
16
+ regression), with pre-execution validation that a tag-based test selection
17
+ hasn't accidentally drifted outside that scope
18
+ - Auto-tags test cases as automation-covered the first time a result for
19
+ them is accepted
16
20
 
17
- ---
21
+ Reporting to Appliqation is **opt-in** per run (`--appq` flag or
22
+ `APPQ_ENABLED=1`) — without it, tests run and results appear in Playwright's
23
+ own reporters as normal, nothing is sent to Appliqation.
18
24
 
19
- ## Prerequisites
25
+ ## Requirements
20
26
 
21
- Before you begin, ensure you have:
27
+ - Node.js 18
28
+ - `@playwright/test` ≥ 1.30 (peer dependency — install it yourself if you
29
+ haven't already)
30
+ - An Appliqation API key and project key (Project Settings → API Keys)
22
31
 
23
- 1. **Node.js 16+** installed
24
- ```bash
25
- node --version # Should be v16.0.0 or higher
26
- ```
27
-
28
- 2. **Playwright** installed in your project
29
- ```bash
30
- npm install @playwright/test
31
- ```
32
-
33
- 3. **Appliqation Account** with:
34
- - Access to Appliqation portal
35
- - API key (get from your project settings or ask your project admin)
36
- - Project key (get from your project settings or ask your project admin)
37
-
38
- ---
39
-
40
- ## Quick Start
41
-
42
- Follow these steps in order to integrate the SDK with your Playwright tests.
43
-
44
- **📌 Important:** Appliqation reporting is **opt-in**. You must either set `APPQ_ENABLE=1` environment variable or add `-- --appq` flag to your test command to send results to Appliqation. Without enabling reporting, tests run normally but results are not reported.
45
-
46
- ### Step 1: Install the SDK
47
-
48
- Navigate to your Playwright project and install the SDK:
32
+ ## Install
49
33
 
50
34
  ```bash
51
- npm install @appliqation/automation-sdk dotenv
35
+ npm install @appliqation/automation-sdk --save-dev
52
36
  ```
53
37
 
54
- **Why dotenv?** The SDK uses environment variables for configuration, and dotenv loads them from your `.env` file.
38
+ No other runtime dependency is required. The SDK does not use `dotenv`
39
+ in CI, inject configuration as environment variables/secrets the normal way
40
+ for your platform; locally, export them in your shell or use whatever
41
+ `.env` loader you already prefer (nothing the SDK does depends on it).
55
42
 
56
- ---
43
+ ## Quick start
57
44
 
58
- ### Step 2: Create .env File
45
+ ### 1. Configure credentials
59
46
 
60
- Create a `.env` file in your project root with your Appliqation credentials:
47
+ Set these as environment variables (CI secrets, shell exports, or your own
48
+ `.env` tooling):
61
49
 
62
- **File:** `.env`
63
50
  ```bash
64
- # IMPORTANT: No spaces around = signs, no trailing slashes on URLs
65
-
66
51
  APPLIQATION_API_KEY=appq_live_xxxxxxxxxxxxxxxxxxxx
67
- APPLIQATION_PROJECT_KEY=your-project-key-here
68
- TEST_APP_URL=https://www.example.com # App under test (Playwright baseURL)
69
- ```
70
-
71
- **How to get these values:**
72
- - `APPLIQATION_API_KEY` - Found in your project settings
73
- - `APPLIQATION_PROJECT_KEY` - Found in your project settings
74
- - `TEST_APP_URL` - The site you’re testing (e.g., https://www.amazon.in). Used as Playwright `baseURL`.
75
- -
76
-
77
- **⚠️ Add .env to .gitignore** to keep credentials secret:
78
- ```bash
79
- echo ".env" >> .gitignore
52
+ APPLIQATION_PROJECT_KEY=your-project-key
53
+ TEST_APP_URL=https://staging.your-app.com # used as Playwright's baseURL
80
54
  ```
81
55
 
82
- ---
83
-
84
- ### Step 3: Update playwright.config.js
85
-
86
- Update your Playwright configuration to use the SDK's built-in features:
87
-
88
- **File:** `playwright.config.js`
56
+ ### 2. Wire up `playwright.config.js`
89
57
 
90
58
  ```javascript
91
59
  const { defineConfig } = require('@playwright/test');
92
- require('dotenv').config(); // Load .env variables
93
60
 
94
- // SDK configuration
95
61
  const appliqationConfig = {
96
62
  apiKey: process.env.APPLIQATION_API_KEY,
97
63
  projectKey: process.env.APPLIQATION_PROJECT_KEY,
98
-
99
- // Optional settings
100
- autoCreateRun: true, // Automatically create run on test start
101
- batchSubmit: true, // Batch results for efficiency
102
- batchSize: 50, // Results per batch
103
- logOrphans: true, // Log tests without UUID mappings
104
- logLevel: 'INFO', // INFO, DEBUG, ERROR
105
- rejectUnauthorized: false // Set to false for self-signed certificates in dev
64
+ environment: process.env.APPLIQATION_ENVIRONMENT, // e.g. 'Staging'
106
65
  };
107
66
 
108
67
  module.exports = defineConfig({
109
68
  testDir: './tests',
110
69
 
111
- // SDK's built-in global setup (handles auth + run creation)
112
- globalSetup: require.resolve('@appliqation/automation-sdk/playwright/global-setup'),
113
- globalTeardown: require.resolve('@appliqation/automation-sdk/playwright/global-teardown'),
114
-
115
70
  use: {
116
71
  baseURL: process.env.TEST_APP_URL,
117
-
118
- // Use SDK-managed authentication state
119
- storageState: '.auth/jwt.json',
120
-
121
- // Ignore HTTPS errors for local development
122
- ignoreHTTPSErrors: true,
123
72
  },
124
73
 
125
74
  reporter: [
126
- ['list'], // Console output
127
- ['html'], // HTML report
128
-
129
- // Appliqation reporter for result submission
130
- ['@appliqation/automation-sdk/playwright/reporter', appliqationConfig]
75
+ ['list'],
76
+ ['@appliqation/automation-sdk/playwright/reporter', appliqationConfig],
131
77
  ],
132
-
133
- projects: [
134
- {
135
- name: 'chromium',
136
- use: {
137
- browserName: 'chromium',
138
- storageState: '.auth/jwt.json' // Authenticated browser state
139
- }
140
- }
141
- ]
142
78
  });
143
79
  ```
144
80
 
145
- **What this does:**
146
- - Loads environment variables from `.env`
147
- - Configures SDK with your credentials
148
- - ✅ Uses SDK's built-in `global-setup.js` to handle authentication automatically
149
- - ✅ Saves authenticated browser state to `.auth/jwt.json`
150
- - ✅ All tests use authenticated sessions (no login required!)
151
- - ✅ Reports results to Appliqation portal
152
-
153
- ---
154
-
155
- ### Step 4: Add UUIDs to Your Tests
81
+ This is enough to report results for an **ungated** application. If your
82
+ app requires login, see [Authenticated apps](#authenticated-apps-gated-suts)
83
+ below it adds a `globalSetup`/`storageState` wiring on top of this.
156
84
 
157
- Map your automated tests to Appliqation test cases using `mapAppqUuid()`:
158
-
159
- **File:** `tests/example.spec.js`
85
+ ### 3. Map tests to Appliqation test cases
160
86
 
161
87
  ```javascript
162
88
  const { test, expect } = require('@playwright/test');
163
89
  const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
164
90
 
165
- test('should login successfully', async ({ page }, testInfo) => {
166
- // Map this test to Appliqation test case UUID
91
+ test('should log in successfully', async ({ page }, testInfo) => {
167
92
  mapAppqUuid(testInfo, '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5');
168
93
 
169
94
  await page.goto('/login');
@@ -173,1172 +98,408 @@ test('should login successfully', async ({ page }, testInfo) => {
173
98
 
174
99
  await expect(page).toHaveURL('/dashboard');
175
100
  });
176
-
177
- test('should display user profile', async ({ page }, testInfo) => {
178
- // Different test case, different UUID
179
- mapAppqUuid(testInfo, '1154-8b28c910-1aa0-5cc2-a433-5fc6a4d82dc6');
180
-
181
- await page.goto('/profile');
182
- await expect(page.locator('h1')).toContainText('My Profile');
183
- });
184
101
  ```
185
102
 
186
- **How to get UUIDs:**
187
- 1. Login to your Appliqation portal
188
- 2. Navigate to your test cases
189
- 3. Copy the UUID for each test case (format: `nid-uuid`)
190
- 4. You can get UUID from downloading the CSV from the test scenario
191
-
192
- **Important:**
193
- - ⚠️ Always include `testInfo` as second parameter: `async ({ page }, testInfo) =>`
194
- - ⚠️ Call `mapAppqUuid()` at the start of each test
195
- - ⚠️ UUID format must be: `nid-uuid` (e.g., `1154-7a17b809-...`)
103
+ - `testInfo` must be the test function's second parameter.
104
+ - The UUID is `{test_case_nid}-{uuid}`; copy it from the test case in the
105
+ Appliqation portal, or export the scenario's CSV.
106
+ - Tests without a mapped UUID still run normally they're reported as
107
+ **orphan tests** rather than failing the run. See
108
+ [Orphan tests](#orphan-test-handling).
196
109
 
197
- ---
110
+ ### 4. Run with reporting enabled
198
111
 
199
- ### Step 5: Run Your Tests
200
-
201
- **IMPORTANT:** To enable Appliqation reporting, you must either set `APPQ_ENABLE=1` environment variable or use the `-- --appq` flag.
202
-
203
- **Reporting DISABLED (Default):**
204
112
  ```bash
205
- # Tests run normally, but results are NOT sent to Appliqation
113
+ # Reporting disabled by default results stay local
206
114
  npx playwright test
207
- ```
208
-
209
- **Reporting ENABLED (Method 1 - Environment Variable - Recommended):**
210
- ```bash
211
- # Set APPQ_ENABLE to enable reporting (simpler approach)
212
- APPQ_ENABLE=1 APPLIQATION_RUN_TITLE=yourruntitle APPLIQATION_ENVIRONMENT=test_env_name npx playwright test
213
- ```
214
-
215
- **Reporting ENABLED (Method 2 - CLI Flag):**
216
- ```bash
217
- # Use -- --appq flag to enable reporting (requires separator)
218
- APPLIQATION_RUN_TITLE=yourruntitle APPLIQATION_ENVIRONMENT=test_env_name npx playwright test -- --appq
219
- ```
220
-
221
- **Examples:**
222
- ```bash
223
- # Method 1: Using environment variable (recommended)
224
- APPQ_ENABLE=1 npx playwright test
225
- APPQ_ENABLE=1 npx playwright test tests/login.spec.js
226
- APPQ_ENABLE=1 npx playwright test --project=chromium
227
- APPQ_ENABLE=1 npx playwright test --headed
228
-
229
- # Method 2: Using CLI flag (requires -- separator)
230
- npx playwright test -- --appq
231
- npx playwright test tests/login.spec.js -- --appq
232
- npx playwright test --project=chromium -- --appq
233
- npx playwright test --headed -- --appq
234
-
235
- # Bonus: Set run title via CLI flag
236
- npx playwright test -- --appq --appq_run_title="My Custom Run"
237
- npx playwright test tests/login.spec.js -- --appq --appq_run_title="Login Tests Sprint 23"
238
- ```
239
-
240
- **What happens when `--appq` flag is present:**
241
-
242
- 1. **Global Setup Runs** (once before all tests):
243
- - Reads `.env` configuration
244
- - Creates automation run in Appliqation portal
245
- - Requests browser JWT token from portal
246
- - Sets up authenticated browser session
247
- - Saves authentication to `.auth/jwt.json`
248
-
249
- 2. **Tests Execute**:
250
- - Each test loads authenticated browser state
251
- - No login required - JWT cookie already set!
252
- - Tests run normally
253
- - Results collected by SDK reporter
254
-
255
- 3. **Results Submitted**:
256
- - SDK batches results (50 per batch by default)
257
- - Submits to Appliqation portal
258
- - Logs any orphan tests (tests without UUIDs)
259
-
260
- 4. **Global Teardown Runs** (once after all tests):
261
- - Cleanup temporary files
262
- - Log final summary
263
-
264
- **Check your results:**
265
- - Visit your Appliqation portal
266
- - Navigate to the scenario you configured
267
- - See test results in the run matrix!
268
-
269
- **Remember:** Results only appear in Appliqation when you enable reporting with `APPQ_ENABLE=1` or `-- --appq` flag!
270
-
271
- ---
272
-
273
- ✅ **That's it!** Your tests are now integrated with Appliqation. Remember to enable reporting with `APPQ_ENABLE=1` or `-- --appq`!
274
-
275
- ---
276
-
277
- ## Enabling Appliqation Reporting (--appq Flag)
278
-
279
- By default, Appliqation reporting is **DISABLED**. You must explicitly enable it by adding the `--appq` flag to your test command.
280
-
281
- ### Why Opt-In?
282
-
283
- This design allows you to:
284
- - ✅ Run tests locally without creating runs in Appliqation
285
- - ✅ Debug and develop tests without affecting production data
286
- - ✅ Control when results are sent to Appliqation portal
287
- - ✅ Avoid accidental test runs in your dashboard
288
-
289
- ### How to Enable
290
-
291
- You can enable Appliqation reporting in two ways:
292
-
293
- #### Method 1: Environment Variable (Recommended - Simpler)
294
115
 
295
- Set the `APPQ_ENABLE` environment variable to `1` or `true`:
116
+ # Enabled via env var (recommended)
117
+ APPQ_ENABLED=1 npx playwright test
296
118
 
297
- ```bash
298
- # Enable reporting with environment variable
299
- APPQ_ENABLE=1 npx playwright test
300
-
301
- # Works with any other flags
302
- APPQ_ENABLE=1 npx playwright test tests/login.spec.js --headed --project=chromium
303
-
304
- # Also works with APPLIQATION_ENABLE
305
- APPLIQATION_ENABLE=true npx playwright test
306
- ```
307
-
308
- #### Method 2: CLI Flag (Requires `--` Separator)
309
-
310
- Add `--appq` flag after the `--` separator:
311
-
312
- ```bash
313
- # Enable reporting with CLI flag (note the -- separator)
119
+ # Enabled via CLI flag (note the -- separator, required by Playwright)
314
120
  npx playwright test -- --appq
315
-
316
- # Works with any other flags
317
- npx playwright test tests/login.spec.js --headed --project=chromium -- --appq
318
121
  ```
319
122
 
320
- **Note:** The `--` separator is required because Playwright doesn't recognize custom flags directly. The environment variable method is simpler and doesn't require the separator.
321
-
322
- ### Setting Run Title via CLI
323
-
324
- You can also specify the run title directly in the command line using the `--appq_run_title` flag:
123
+ Both forms accept the usual Playwright flags (`--project`, `--headed`,
124
+ `-g`, a file path, etc.).
325
125
 
326
- ```bash
327
- # Set run title via CLI flag
328
- npx playwright test -- --appq --appq_run_title="My Custom Run Title"
329
-
330
- # Works with other flags
331
- npx playwright test tests/login.spec.js --headed --project=chromium -- --appq --appq_run_title="Login Tests"
332
-
333
- # With quotes for titles containing spaces
334
- npx playwright test -- --appq --appq_run_title="Regression Suite - Sprint 23"
335
- ```
336
-
337
- **Priority Order for Run Title:**
338
- 1. Config file `title` option (if specified)
339
- 2. CLI flag `--appq_run_title` (new!)
340
- 3. Environment variable `APPLIQATION_RUN_TITLE`
341
- 4. Auto-generated timestamp (default)
342
-
343
- **Examples:**
344
- ```bash
345
- # Method 1: Environment variable
346
- APPLIQATION_RUN_TITLE="My Run" npx playwright test -- --appq
347
-
348
- # Method 2: CLI flag (overrides environment variable)
349
- APPLIQATION_RUN_TITLE="Old Title" npx playwright test -- --appq --appq_run_title="New Title"
350
- # Result: Run title will be "New Title"
351
-
352
- # Method 3: Combined usage
353
- npx playwright test -- --appq --appq_run_title="Sprint 23 Regression"
354
- ```
126
+ ## Scoping runs: Scenario or Test Set
355
127
 
356
- ### What Happens When Reporting is Disabled
357
-
358
- When you run tests **without** enabling reporting (no flag, no env var):
359
- - Tests execute normally
360
- - ✅ Execution summary file is still created
361
- - ❌ No run is created in Appliqation
362
- - ❌ No results are sent to Appliqation portal
363
- - ℹ️ Console shows: "Appliqation reporting disabled: Add --appq flag to send results"
364
-
365
- **Example:**
366
- ```bash
367
- # Reporting disabled - no results sent to Appliqation
368
- npx playwright test
369
- ```
370
-
371
- ### What Happens When Reporting is Enabled
372
-
373
- When you run tests **with** reporting enabled (using flag or env var):
374
- - ✅ Tests execute normally
375
- - ✅ Run matrix created in Appliqation
376
- - ✅ Results sent to Appliqation portal
377
- - ✅ Execution summary file created
378
- - ✅ Console shows: "Appliqation reporting enabled: Results will be sent to Appliqation portal"
379
-
380
- **Examples:**
381
- ```bash
382
- # Reporting enabled with environment variable
383
- APPQ_ENABLE=1 npx playwright test
384
-
385
- # Reporting enabled with CLI flag
386
- npx playwright test -- --appq
387
- ```
388
-
389
- ---
390
-
391
- ## Execution Summary Files
392
-
393
- After each test run, the SDK automatically creates a timestamped summary file with comprehensive results.
394
-
395
- **Location:** `test-results/AppQ_Execution_Summary/`
396
-
397
- **Filename Format:** `{run_title}_2025-01-21_14-30-45.txt`
398
-
399
- **What's Included:**
400
- - ✅ Execution time (start, end, duration)
401
- - ✅ Test counts (submitted, accepted, rejected, passed, failed, skipped)
402
- - ✅ Run IDs for all created matrices
403
- - ✅ Detailed error information (duplicates, orphans, backend rejections)
404
- - ✅ Complete ASCII table (same as terminal output)
405
-
406
- **Example:**
407
- ```
408
- test-results/
409
- └── AppQ_Execution_Summary/
410
- ├── My_Test_Run_2025-01-21_09-30-15.txt
411
- ├── My_Test_Run_2025-01-21_14-45-30.txt
412
- └── Regression_Suite_2025-01-22_08-00-00.txt
413
- ```
414
-
415
- **Features:**
416
- - Always enabled automatically (no configuration needed)
417
- - Each run creates a NEW file (never overwrites)
418
- - If file writing fails, tests continue normally (non-blocking)
419
-
420
- **Sample File Content:**
421
- ```
422
- ═══════════════════════════════════════════════════════════
423
- APPLIQATION TEST EXECUTION SUMMARY
424
- ═══════════════════════════════════════════════════════════
425
-
426
- EXECUTION METADATA:
427
- ─────────────────────────────────────────────────────────
428
- Start Time: 2025-01-21T14:30:15.123Z
429
- End Time: 2025-01-21T14:35:45.456Z
430
- Duration: 5m 30s
431
- Run Title: My_Test_Run
432
-
433
- ╔═══════════════════════════════════════════════════════════╗
434
- ║ Appliqation Test Results Summary ║
435
- ╠═══════════════════════════════════════════════════════════╣
436
- ║ Submitted to Backend: ║
437
- ║ Total Submitted: 10 ║
438
- ║ ✅ Accepted: 8 ║
439
- ║ ❌ Rejected: 2 ║
440
- ║ ║
441
- ║ Test Execution Results (Playwright): ║
442
- ║ Passed: 8 ║
443
- ║ Failed: 0 ║
444
- ║ Skipped: 0 ║
445
- ║ ║
446
- ║ Not Submitted: ║
447
- ║ Orphan (No UUID): 3 ║
448
- ║ Duplicates: 2 ║
449
- ╠═══════════════════════════════════════════════════════════╣
450
- ║ Run Matrices Created: 2 ║
451
- ║ Desktop-Windows : run_abc123_1234567890 ║
452
- ║ Desktop-Linux : run_xyz789_0987654321 ║
453
- ╚═══════════════════════════════════════════════════════════╝
454
-
455
- DETAILED ERRORS & WARNINGS:
456
- ═══════════════════════════════════════════════════════════
457
- [Duplicate UUIDs, Orphan Tests, and Backend Rejections details...]
458
- ```
459
-
460
- ---
461
-
462
- ## Auto-Tagging Test Cases
463
-
464
- The SDK automatically tags test cases with "Appq_automated" (configurable) after their **first successful run**. This helps you track which test cases have been automated and are actively running in your test suite.
465
-
466
- ### How It Works
467
-
468
- 1. **Test runs and passes** → SDK submits result to Appliqation
469
- 2. **Backend accepts result** → SDK triggers auto-tagging (fire-and-forget)
470
- 3. **Check if already tagged** → Skip if test case already has the tag
471
- 4. **Add tag** → Test case gets tagged in Appliqation UI
472
-
473
- **Key Features:**
474
- - ✅ **Enabled by default** when Appliqation reporting is enabled
475
- - ✅ **Fire-and-forget** - tagging failures never block your test runs
476
- - ✅ **Smart deduplication** - checks before tagging, won't create duplicate tags
477
- - ✅ **Only accepted results** - backend-rejected results are NOT tagged
478
- - ✅ **Works for both** single and batch result submissions
479
- - ✅ **Async execution** - zero impact on test execution performance
480
-
481
- ### Configuration
482
-
483
- #### Environment Variables
484
-
485
- Add to your `.env` file:
486
-
487
- ```bash
488
- # Auto-Tagging Configuration (optional - all have sensible defaults)
489
- APPLIQATION_AUTO_TAG_ENABLED=true # Enable/disable (default: true)
490
- APPLIQATION_AUTO_TAG_NAME=Appq_automated # Custom tag name (default: Appq_automated)
491
- ```
492
-
493
- #### Playwright Reporter Config
494
-
495
- Configure in `playwright.config.js`:
128
+ Add `scenarioId` to link a run to one scenario, or `testSetId` to link it
129
+ to a Test Set — the grouping you'd use for a smoke, sanity, or regression
130
+ suite that spans multiple scenarios. They're mutually exclusive;
131
+ `scenarioId` wins if both are set.
496
132
 
497
133
  ```javascript
498
- reporter: [
499
- ['@appliqation/automation-sdk/playwright/reporter', {
500
- apiKey: process.env.APPLIQATION_API_KEY,
501
- projectKey: process.env.APPLIQATION_PROJECT_KEY,
502
-
503
- // Auto-tagging options (optional)
504
- autoTag: true, // Enable auto-tagging (default: true)
505
- autoTagName: 'My_Custom_Tag' // Custom tag name (default: 'Appq_automated')
506
- }]
507
- ]
508
- ```
509
-
510
- #### Programmatic Configuration
511
-
512
- When using the SDK directly:
513
-
514
- ```javascript
515
- const { AppliqationClient } = require('@appliqation/automation-sdk');
516
-
517
- const client = new AppliqationClient({
518
- apiKey: 'your_api_key',
519
- projectKey: 'your_project_key',
520
-
521
- // Auto-tagging options
522
- options: {
523
- autoTag: true, // Enable auto-tagging (default: true)
524
- autoTagName: 'Automated_Test' // Custom tag name (default: 'Appq_automated')
525
- }
526
- });
527
- ```
528
-
529
- ### Disabling Auto-Tagging
530
-
531
- If you want to disable auto-tagging:
532
-
533
- **Option 1: Environment Variable**
534
- ```bash
535
- APPLIQATION_AUTO_TAG_ENABLED=false
536
- ```
537
-
538
- **Option 2: Config**
539
- ```javascript
540
- {
541
- options: {
542
- autoTag: false
543
- }
544
- }
545
- ```
546
-
547
- ### What You'll See
548
-
549
- When auto-tagging is working:
550
-
551
- ```
552
- ✅ Auto-tagged 3 test case(s) with "Appq_automated"
553
- ```
554
-
555
- When test cases are already tagged (second run):
556
-
557
- ```
558
- DEBUG: Skipped 3 already-tagged test case(s)
559
- ```
560
-
561
- If tagging fails (non-blocking):
562
-
563
- ```
564
- ⚠️ Auto-tagging failed (non-blocking): Connection timeout
565
- ```
566
-
567
- ### Troubleshooting
568
-
569
- **Q: I don't see the tag in Appliqation UI**
570
-
571
- Check:
572
- 1. Is `APPQ_ENABLE=1` set? (Auto-tagging only works when reporting is enabled)
573
- 2. Did the test result get accepted by backend? (Check for backend validation errors)
574
- 3. Check SDK logs for "Auto-tagged X test case(s)" message
575
-
576
- **Q: Can I use a custom tag name?**
577
-
578
- Yes! Set `APPLIQATION_AUTO_TAG_NAME=Your_Tag_Name` in your `.env` file or use the config options shown above.
579
-
580
- **Q: Does tagging failure affect my test results?**
581
-
582
- No! Auto-tagging is fire-and-forget. If tagging fails, it's logged as a warning but your test run continues normally and results are still submitted successfully.
583
-
584
- ---
585
-
586
- ## Handling Orphan Tests
587
-
588
- ### What are Orphan Tests?
589
-
590
- **Orphan tests** are tests that execute successfully but **cannot be mapped to Appliqation test cases** because they're missing UUID annotations. When a test runs without a UUID, the SDK cannot link it to a specific test case in your Appliqation project, making the result "orphaned."
591
-
592
- ```javascript
593
- // ❌ This test will be orphaned (no UUID annotation)
594
- test('Login with valid credentials', async ({ page }) => {
595
- await page.goto('/login');
596
- await page.fill('#username', 'user@example.com');
597
- // ... test code
598
- });
599
-
600
- // ✅ This test will be properly mapped (has UUID annotation)
601
- test('Login with valid credentials', { tag: '@uuid:1154-abc-def' }, async ({ page }) => {
602
- await page.goto('/login');
603
- await page.fill('#username', 'user@example.com');
604
- // ... test code
605
- });
606
- ```
607
-
608
- ### Automatic Orphan Run Cleanup
609
-
610
- By default, the SDK **automatically prevents corrupted runs** from being created when ALL tests in a run are orphaned:
611
-
612
- **Default Behavior:**
613
- - ✅ If ALL tests lack UUIDs → Run is **deleted** and a clear error message is shown
614
- - ✅ If SOME tests have UUIDs → Run is **kept**, valid results are submitted, orphans are logged as warnings
615
- - ✅ CI/CD pipeline **fails with exit code 1** when orphan-only runs are detected
616
- - ✅ Clear, actionable error message guides users on how to fix the issue
617
-
618
- **Why?** Orphan-only runs create empty entries in Appliqation with "N/A" pass rates, which corrupts your analytics and dashboards.
619
-
620
- ### Error Message Example
621
-
622
- When all tests are orphaned, you'll see:
623
-
624
- ```
625
- ╔════════════════════════════════════════════════════════════════════╗
626
- ║ ❌ RUN CREATION FAILED - ALL TESTS MISSING UUID ANNOTATIONS ║
627
- ╠════════════════════════════════════════════════════════════════════╣
628
- ║ Project: 1162-MyProject ║
629
- ║ Orphan Tests: 6 ║
630
- ║ ║
631
- ║ ⚠️ NO RESULTS WERE SUBMITTED TO APPLIQATION ║
632
- ║ The test run was automatically deleted to prevent analytics ║
633
- ║ corruption. All tests are missing UUID annotations. ║
634
- ╠════════════════════════════════════════════════════════════════════╣
635
- ║ ✅ ACTION REQUIRED: Add UUID Annotations ║
636
- ╠════════════════════════════════════════════════════════════════════╣
637
- ║ Option 1: Using test tags (Recommended) ║
638
- ║ test('My Test', { tag: '@uuid:123-xxx' }, async ({ page }) => { ║
639
- ║ // your test code ║
640
- ║ }); ║
641
- ╚════════════════════════════════════════════════════════════════════╝
642
- ```
643
-
644
- ### Configuration Options
645
-
646
- You can customize orphan handling behavior via environment variables:
647
-
648
- ```env
649
- # .env file
650
-
651
- # Delete runs with only orphan tests (default: true)
652
- APPLIQATION_DELETE_ORPHAN_RUNS=true
653
-
654
- # Exit with error code 1 for orphan-only runs (default: true)
655
- APPLIQATION_FAIL_ON_ORPHAN_RUNS=true
656
- ```
657
-
658
- **Configuration via playwright.config.js:**
659
-
660
- ```javascript
661
- reporter: [
662
- [
663
- '@appliqation/automation-sdk-js/playwright',
664
- {
665
- deleteOrphanOnlyRuns: true, // Delete orphan-only runs (default: true)
666
- failOnOrphanOnlyRuns: true, // Fail CI/CD for orphan-only runs (default: true)
667
- }
668
- ]
669
- ]
670
- ```
671
-
672
- ### Mixed Scenarios (Some Tests Have UUIDs)
673
-
674
- When your test suite has **both valid and orphan tests**, the SDK handles it gracefully:
675
-
676
- ```javascript
677
- // Project 1162: 3 tests total
678
- test('Valid Test 1', { tag: '@uuid:1154-abc' }, async ({ page }) => {
679
- // ✅ Will be submitted to Appliqation
680
- });
681
-
682
- test('Orphan Test 1', async ({ page }) => {
683
- // ⚠️ Logged as warning, not submitted
684
- });
685
-
686
- test('Valid Test 2', { tag: '@uuid:1155-def' }, async ({ page }) => {
687
- // ✅ Will be submitted to Appliqation
688
- });
689
- ```
690
-
691
- **Result:**
692
- - ✅ Run is kept (because 2 tests have UUIDs)
693
- - ✅ 2 valid results submitted to Appliqation
694
- - ⚠️ 1 orphan logged in console and summary file
695
- - ✅ CI/CD passes (because at least some tests were valid)
696
- - ✅ Analytics remain accurate (only valid tests counted)
697
-
698
- ### Troubleshooting FAQ
699
-
700
- **Q: Why does my run get deleted?**
701
-
702
- Your run is deleted only when **100% of your tests lack UUID annotations**. This prevents corrupted analytics. Add UUIDs to at least one test to keep the run.
703
-
704
- **Q: How do I disable automatic deletion?**
705
-
706
- Set `APPLIQATION_DELETE_ORPHAN_RUNS=false` in your `.env` file. However, this is not recommended as it will corrupt your analytics with N/A pass rates.
707
-
708
- **Q: Can I keep orphan-only runs but still fail CI/CD?**
709
-
710
- Yes! Set:
711
- ```env
712
- APPLIQATION_DELETE_ORPHAN_RUNS=false
713
- APPLIQATION_FAIL_ON_ORPHAN_RUNS=true
714
- ```
715
-
716
- This will create the run in Appliqation but still fail your pipeline, forcing developers to fix UUIDs.
717
-
718
- **Q: Where do I find UUIDs for my tests?**
719
-
720
- 1. Log into Appliqation portal
721
- 2. Navigate to your project
722
- 3. Go to "Test Cases" tab
723
- 4. Find your test case
724
- 5. The UUID is in the format: `{test_nid}-{uuid}` (e.g., `1154-c1f9559c-b978-43cc-9c76-fd539c717cb4`)
725
-
726
- **Q: Does orphan cleanup affect test execution?**
727
-
728
- No! Cleanup happens **after** all tests complete in the `onEnd()` hook. Test execution is never blocked or interrupted.
729
-
730
- **Q: What if deletion fails?**
731
-
732
- Deletion is fire-and-forget with error handling. If deletion fails (network issue, permission, etc.), it's logged as an error but doesn't crash your test run. The corrupted run may remain in Appliqation in this rare case.
733
-
734
- ---
735
-
736
- ## How It Works
737
-
738
- Understanding the SDK's authentication and result submission flow helps troubleshoot issues.
739
-
740
- ### Authentication & Test Execution Flow
741
-
742
- ```
743
- ┌─────────────────────────────────────────────────────────────────┐
744
- │ GLOBAL SETUP (Runs Once) │
745
- ├─────────────────────────────────────────────────────────────────┤
746
- │ │
747
- │ 1. Read .env configuration │
748
- │ ├─ APPLIQATION_API_KEY │
749
- │ ├─ APPLIQATION_PROJECT_KEY │
750
- │ ├─ TEST_APP_URL │
751
-
752
- │ │ │
753
- │ ▼ │
754
- │ 2. Create automation run via API │
755
- │ POST /api/automation/run/create │
756
- │ ├─ Returns: run_id, api_token │
757
- │ └─ Saves to: process.env.APPLIQATION_RUN_ID │
758
- │ │ │
759
- │ ▼ │
760
- │ 3. Request browser JWT token │
761
- │ POST /api/auth/jwt/browser │
762
- │ ├─ Send: api_key │
763
- │ └─ Returns: jwt_token, expires_in │
764
- │ │ │
765
- │ ▼ │
766
- │ 4. Setup browser authentication │
767
- │ ├─ Launch headless browser │
768
- │ ├─ Navigate to baseURL │
769
- │ ├─ Set cookie: appliqation_jwt = jwt_token │
770
- │ ├─ Save storage state to: .auth/jwt.json │
771
- │ └─ Close browser │
772
- │ │
773
- │ ✅ Setup complete - All tests will use authenticated state │
774
- │ │
775
- └─────────────────────────────────────────────────────────────────┘
776
-
777
-
778
- ┌─────────────────────────────────────────────────────────────────┐
779
- │ TEST EXECUTION (Per Worker) │
780
- ├─────────────────────────────────────────────────────────────────┤
781
- │ │
782
- │ For each test: │
783
- │ │
784
- │ 1. Load storage state from .auth/jwt.json │
785
- │ └─ Browser starts with JWT cookie already set │
786
- │ │ │
787
- │ ▼ │
788
- │ 2. Run test code │
789
- │ ├─ mapAppqUuid(testInfo, '1154-uuid-here') │
790
- │ ├─ Execute test steps (page.goto, clicks, etc.) │
791
- │ └─ Collect result: passed/failed/skipped │
792
- │ │ │
793
- │ ▼ │
794
- │ 3. Reporter collects result │
795
- │ ├─ Extract UUID from test.info().annotations │
796
- │ ├─ Capture browser/OS/device metadata │
797
- │ ├─ Add to batch queue │
798
- │ └─ (Batch submitted when size reached or tests complete) │
799
- │ │
800
- └─────────────────────────────────────────────────────────────────┘
801
-
802
-
803
- ┌─────────────────────────────────────────────────────────────────┐
804
- │ REPORTER (After All Tests) │
805
- ├─────────────────────────────────────────────────────────────────┤
806
- │ │
807
- │ 1. Batch all test results │
808
- │ └─ Group by 50 results per batch (configurable) │
809
- │ │ │
810
- │ ▼ │
811
- │ 2. Submit to portal │
812
- │ POST /api/automation/result/batch │
813
- │ ├─ Send: run_id, results[], api_key │
814
- │ └─ Retry on failure (exponential backoff) │
815
- │ │ │
816
- │ ▼ │
817
- │ 3. Handle orphan tests (tests without UUIDs) │
818
- │ POST /api/automation/orphans │
819
- │ └─ Logs tests that need UUID mapping │
820
- │ │ │
821
- │ ▼ │
822
- │ ✅ All results submitted to portal │
823
- │ │
824
- └─────────────────────────────────────────────────────────────────┘
825
-
826
-
827
- ┌─────────────────────────────────────────────────────────────────┐
828
- │ GLOBAL TEARDOWN (Runs Once) │
829
- ├─────────────────────────────────────────────────────────────────┤
830
- │ │
831
- │ 1. Cleanup temporary files (optional) │
832
- │ 2. Log final summary │
833
- │ │
834
- │ ✅ Test run complete │
835
- │ │
836
- └─────────────────────────────────────────────────────────────────┘
837
- ```
838
-
839
- **Key Points:**
840
- - Authentication happens **once** in global-setup
841
- - JWT token saved to `.auth/jwt.json`
842
- - All test workers reuse the same authenticated state
843
- - No per-test login required!
844
-
845
- ### SDK Architecture
846
-
847
- ```
848
- ┌─────────────────────────────────────────────────────────────────┐
849
- │ Playwright Test Suite │
850
- │ │
851
- │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
852
- │ │ Test File 1 │ │ Test File 2 │ │ Test File 3 │ │
853
- │ │ │ │ │ │ │ │
854
- │ │ mapAppqUuid()│ │ mapAppqUuid()│ │ mapAppqUuid()│ │
855
- │ └──────────────┘ └──────────────┘ └──────────────┘ │
856
- │ │ │ │ │
857
- └─────────┼────────────────────┼────────────────────┼──────────────┘
858
- │ │ │
859
- └────────────────────┴────────────────────┘
860
-
861
-
862
- ┌─────────────────────────────────────────┐
863
- │ Appliqation SDK Reporter │
864
- │ │
865
- │ • Collects test results │
866
- │ • Extracts UUIDs from annotations │
867
- │ • Batches submissions │
868
- │ • Handles browser/OS/device metadata │
869
- └─────────────────────────────────────────┘
870
-
871
-
872
- ┌─────────────────────────────────────────┐
873
- │ Appliqation HTTP Client │
874
- │ │
875
- │ • API key authentication │
876
- │ • Connection pooling │
877
- │ • Exponential backoff retry │
878
- └─────────────────────────────────────────┘
879
-
880
-
881
- ┌─────────────────────────────────────────┐
882
- │ Appliqation Portal API │
883
- │ │
884
- │ • Validates API key │
885
- │ • Creates run matrices │
886
- │ • Stores test results │
887
- │ • Generates reports │
888
- └─────────────────────────────────────────┘
889
- ```
890
-
891
- ### File Structure After Setup
892
-
893
- ```
894
- your-playwright-project/
895
- ├── .auth/ # Auto-created by SDK global-setup
896
- │ └── jwt.json # Browser authentication state
897
-
898
- ├── .env # YOU CREATE THIS (Step 2)
899
- │ ├── APPLIQATION_API_KEY=appq_live_xxxxx
900
- │ ├── APPLIQATION_PROJECT_KEY=your-project-key
901
- │ ├── TEST_APP_URL=https://your-domain.com
902
-
903
-
904
- ├── playwright.config.js # YOU UPDATE THIS (Step 3)
905
- │ ├── globalSetup: require.resolve('@appliqation/automation-sdk/playwright/global-setup')
906
- │ ├── globalTeardown: require.resolve('@appliqation/automation-sdk/playwright/global-teardown')
907
- │ ├── use: { storageState: '.auth/jwt.json' }
908
- │ └── reporter: ['@appliqation/automation-sdk/playwright/reporter', config]
909
-
910
- ├── tests/
911
- │ ├── login.spec.js # YOUR TESTS (Step 4)
912
- │ │ ├── const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
913
- │ │ └── mapAppqUuid(testInfo, '1154-uuid-here');
914
- │ │
915
- │ └── checkout.spec.js
916
-
917
- ├── package.json
918
- │ └── dependencies:
919
- │ ├── @playwright/test
920
- │ ├── @appliqation/automation-sdk
921
- │ └── dotenv # Required for .env loading
922
-
923
- └── node_modules/
924
- └── @appliqation/automation-sdk/
925
- └── playwright/
926
- ├── global-setup.js # SDK provides this!
927
- ├── global-teardown.js # SDK provides this!
928
- └── index.js # Reporter
929
- ```
930
-
931
- ---
932
-
933
- ## Configuration Reference
934
-
935
- ### Environment Variables (.env)
936
-
937
- All environment variables and their purposes:
938
-
939
- | Variable | Required | Description | Example |
940
- |----------|----------|-------------|---------|
941
- | `TEST_APP_URL` | ✅ Yes | Your Test App URL (no trailing slash) | `https://example.com` |
942
- | `APPLIQATION_API_KEY` | ✅ Yes | API key from `/admin/config/appliqation/api-keys` | `appq_live_abc123xyz...` |
943
- | `APPLIQATION_PROJECT_KEY` | ✅ Yes | Project key from project settings | `my-project-key` |
944
-
945
-
946
- **Common Configurations:**
947
-
948
- **CI/CD Pipeline:**
949
- ```javascript
950
- {
951
- environment: process.env.CI_ENVIRONMENT || 'CI',
952
- title: `Build #${process.env.CI_BUILD_NUMBER}`,
953
- logLevel: 'ERROR', // Less verbose in CI
954
- batchSize: 100 // Larger batches for speed
955
- }
956
- ```
957
-
958
- **Local Development:**
959
- ```javascript
960
- {
961
- environment: 'Local',
962
- logLevel: 'DEBUG', // Detailed logs
963
- logOrphans: true, // See unmapped tests
964
- rejectUnauthorized: false // Allow local SSL
965
- }
966
- ```
967
-
968
- ---
969
-
970
- ## Adding Test Case UUIDs
971
-
972
- Map your automated tests to Appliqation test cases to track results.
973
-
974
- ### Method: mapAppqUuid()
975
-
976
- **Import the utility:**
977
- ```javascript
978
- const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
979
- ```
980
-
981
- **Use in tests:**
982
- ```javascript
983
- test('test description', async ({ page }, testInfo) => {
984
- // ^^^^^^^^ Required parameter!
134
+ const appliqationConfig = {
135
+ apiKey: process.env.APPLIQATION_API_KEY,
136
+ projectKey: process.env.APPLIQATION_PROJECT_KEY,
985
137
 
986
- // Map to test case UUID
987
- mapAppqUuid(testInfo, '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5');
138
+ scenarioId: parseInt(process.env.APPLIQATION_SCENARIO_ID) || undefined,
139
+ // testSetId: parseInt(process.env.MY_SMOKE_TEST_SET_ID) || undefined,
988
140
 
989
- // Your test code...
990
- });
141
+ // How to resolve a run whose executed tests fall outside the configured
142
+ // scope — 'cancel' (default, fail-safe), 'adhoc', or 'filter'.
143
+ onScopeMismatch: process.env.APPLIQATION_ON_SCOPE_MISMATCH,
144
+ };
991
145
  ```
992
146
 
993
- **Important:**
994
- - ⚠️ Always include `testInfo` as second parameter
995
- - ⚠️ UUID format: `nid-uuid` (e.g., `1154-abc123...`)
996
- - ⚠️ Get UUIDs from Appliqation portal test cases
997
-
998
- ### Getting UUIDs from Portal
147
+ Before the suite runs, the reporter checks every UUID it's about to execute
148
+ against the real membership of the configured scenario or test set, so a
149
+ tag-based selection (`-g`, `--grep`) that drifts outside it doesn't silently
150
+ write results into the wrong run:
999
151
 
1000
- 1. Login to Appliqation portal
1001
- 2. Navigate to **Test Cases** section
1002
- 3. Open the test case you want to map
1003
- 4. Copy the UUID (shown in test case details)
1004
- 5. Use format: `nid-uuid` where:
1005
- - `nid` = Test case node ID (e.g., `1154`)
1006
- - `uuid` = Test case UUID (e.g., `7a17b809-0ff9-4ba1-9322-4eb2a49abfc5`)
152
+ | Strategy | Behavior |
153
+ |---|---|
154
+ | `cancel` (default in CI) | Nothing submitted, exit code 1. Tests still run locally so you keep your own Playwright output. |
155
+ | `adhoc` | Overrides the configured scope and creates an ad-hoc run instead — everything is submitted. |
156
+ | `filter` | Submits only the in-scope results; out-of-scope tests still execute but aren't uploaded. |
1007
157
 
1008
- ### What About Tests Without UUIDs?
158
+ Outside CI, with an interactive terminal, you're prompted to choose one of
159
+ the three before the run starts.
1009
160
 
1010
- Tests without `mapAppqUuid()` calls are called **orphan tests**. The SDK will:
1011
- - ✅ Still run them normally
1012
- - ✅ Collect results
1013
- - ✅ Log them separately (if `logOrphans: true`)
1014
- - ❌ Won't report to portal (no UUID to map to)
161
+ ## Authenticated apps (gated SUTs)
1015
162
 
1016
- **Check orphan logs to see which tests need UUID mapping.**
163
+ If your application requires login, the SDK ships a portable auth setup
164
+ that works the same way in Appliqation's own executor and in your CI/local
165
+ runs. The login flow itself is **your code, in your repo**
166
+ (`tests/automan/auth/login.ts` by default — the path is configurable in
167
+ your project's Appliqation settings) — both environments run that same
168
+ function, so SSO, MFA, multi-step login, OAuth, and custom redirects all
169
+ work because you write the Playwright code that handles them.
1017
170
 
1018
- ---
171
+ ### One-time setup per project
1019
172
 
1020
- ## Troubleshooting
1021
-
1022
- ### Common Issues and Solutions
173
+ 1. **In Appliqation**: configure roles and credentials under **Project
174
+ Settings → Auth Config**. Credentials are encrypted server-side. This is
175
+ also where you'd change the login file's path/location if your project
176
+ doesn't use the default.
1023
177
 
1024
- #### Error: "APPLIQATION_API_KEY is required"
178
+ 2. **In your repo**, create `tests/automan/auth/login.ts`:
1025
179
 
1026
- **Cause:** `.env` file not loaded or missing variable
180
+ ```typescript
181
+ import { defineLogin } from '@appliqation/automation-sdk/login';
1027
182
 
1028
- **Fix:**
1029
- 1. Verify `.env` file exists in project root
1030
- 2. Check variable name spelling (no typos!)
1031
- 3. Ensure `require('dotenv').config()` at top of `playwright.config.js`
1032
- 4. No spaces around `=` sign:
1033
- ```bash
1034
- # ❌ Wrong
1035
- APPLIQATION_API_KEY = appq_live_xxx
183
+ export default defineLogin(async (page, { username, password, role, baseURL }) => {
184
+ await page.goto('/login'); // baseURL handles env (staging/prod)
185
+ await page.getByLabel('Email').fill(username);
186
+ await page.getByLabel('Password').fill(password);
187
+ await page.getByRole('button', { name: 'Sign in' }).click();
188
+ await page.waitForURL('**/dashboard');
1036
189
 
1037
- # Correct
1038
- APPLIQATION_API_KEY=appq_live_xxx
190
+ if (role === 'admin') {
191
+ await page.getByRole('button', { name: 'Switch to admin view' }).click();
192
+ }
193
+ });
1039
194
  ```
1040
195
 
1041
- ---
196
+ Push to your project's default branch — Appliqation's GitHub webhook
197
+ ingests the file automatically.
1042
198
 
1043
- #### Tests redirecting to login page (authentication failed)
1044
-
1045
- **Cause:** JWT authentication not working, storage state not loading
1046
-
1047
- **Fix:**
1048
- 1. Verify `globalSetup` configured correctly:
1049
- ```javascript
1050
- globalSetup: require.resolve('@appliqation/automation-sdk/playwright/global-setup')
1051
- ```
199
+ 3. **In Appliqation**, use the **download .env for CI** link on the project
200
+ settings page and add the values to your CI secrets:
1052
201
 
1053
- 2. Check `.auth/jwt.json` file exists after global-setup runs
1054
-
1055
- 3. Verify all projects use storage state:
1056
- ```javascript
1057
- projects: [{
1058
- name: 'chromium',
1059
- use: { storageState: '.auth/jwt.json' } // Must be set!
1060
- }]
1061
- ```
1062
-
1063
- 4. Check `.env` has correct `TEST_APP_URL` (no trailing slash):
1064
202
  ```bash
1065
- # Wrong
1066
- TEST_APP_URL=https://portal.com/
203
+ APPLIQATION_API_KEY="<project API key>"
204
+ APPLIQATION_BASE_URL="https://appliqation.io"
205
+ APPLIQATION_PROJECT_KEY=126
206
+ APPLIQATION_SUT_BASE_URL="<your SUT URL, e.g. https://staging.acme.com>"
1067
207
 
1068
- # ✅ Correct
1069
- TEST_APP_URL=https://portal.com
208
+ APPQ_PROJECT_126_DEFAULT_USERNAME="<username>"
209
+ APPQ_PROJECT_126_DEFAULT_PASSWORD="<password>"
1070
210
  ```
1071
211
 
1072
- ---
212
+ `APPLIQATION_SUT_BASE_URL` is what your login function's
213
+ `page.goto('/login')` resolves against, so the same `login.ts` works
214
+ across staging/preprod/prod by changing one env var.
1073
215
 
1074
- #### Error: "testInfo is not defined"
216
+ 4. **(Optional)** Use **Test login** on the project settings page to
217
+ validate `login.ts` against the live SUT before wiring up CI.
1075
218
 
1076
- **Cause:** Missing `testInfo` parameter in test function
219
+ ### In your test files
1077
220
 
1078
- **Fix:**
1079
- ```javascript
1080
- // Wrong - missing testInfo
1081
- test('my test', async ({ page }) => {
1082
- mapAppqUuid(testInfo, 'uuid-here'); // testInfo undefined!
1083
- });
221
+ ```typescript
222
+ const { mapAppqUuid, setupAuth } = require('@appliqation/automation-sdk/utils');
223
+ const { test, expect } = require('@playwright/test');
1084
224
 
1085
- // ✅ Correct - include testInfo
1086
- test('my test', async ({ page }, testInfo) => {
1087
- mapAppqUuid(testInfo, 'uuid-here');
225
+ test.use({
226
+ storageState: setupAuth({ project_id: 126, role: 'default' }),
1088
227
  });
1089
- ```
1090
-
1091
- ---
1092
228
 
1093
- #### Error: "Invalid UUID format"
1094
-
1095
- **Cause:** UUID not in `nid-uuid` format
1096
-
1097
- **Fix:**
1098
- ```javascript
1099
- // ❌ Wrong formats
1100
- mapAppqUuid(testInfo, '7a17b809-0ff9-4ba1-9322-4eb2a49abfc5'); // Missing nid
1101
- mapAppqUuid(testInfo, '1154'); // Missing UUID
1102
- mapAppqUuid(testInfo, 'test-case-123'); // Wrong format
1103
-
1104
- // ✅ Correct format
1105
- mapAppqUuid(testInfo, '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5');
229
+ test('manager dashboard loads', async ({ page }, testInfo) => {
230
+ mapAppqUuid(testInfo, '1141-...');
231
+ await page.goto('/dashboard'); // already authenticated
232
+ });
1106
233
  ```
1107
234
 
1108
- ---
1109
-
1110
- #### ❌ Error: "Module 'dotenv' not found"
235
+ `setupAuth()` returns a deterministic storage-state file path — it does
236
+ **not** perform login itself:
1111
237
 
1112
- **Cause:** `dotenv` package not installed
238
+ - **In Appliqation's own executor**, the login helper imports `login.ts`
239
+ from the canonical store and writes that state before your test runs.
240
+ Nothing else to do.
241
+ - **In your CI/local runs**, run `npx appq-auth-setup` once before
242
+ `playwright test`.
1113
243
 
1114
- **Fix:**
1115
244
  ```bash
1116
- npm install dotenv
245
+ npx appq-auth-setup --project-id 126 --role default
246
+ npx playwright test
1117
247
  ```
1118
248
 
1119
- ---
1120
-
1121
- #### ❌ Error: "unable to verify the first certificate" or SSL errors
249
+ Re-run the CLI whenever sessions expire (typically once per CI run) — it's
250
+ idempotent and fast on cache hits.
1122
251
 
1123
- **Cause:** Using self-signed SSL certificates in development environment
252
+ If `login.ts` is TypeScript, the CLI needs a TS loader as a dev dependency
253
+ (`npm install --save-dev tsx`, or `ts-node`). Plain `.js`/`.mjs`/`.cjs`
254
+ login files need neither. The `appq-auth-setup` CLI itself resolves the
255
+ login file path via `--login-file`, then `APPQ_LOGIN_FILE`, then its own
256
+ local default — set the path in Project Settings if you want Appliqation's
257
+ executor and your CLI/CI runs to agree on a non-default location.
1124
258
 
1125
- **Fix:**
259
+ **Multiple roles**: configure each in Project Settings, then run one
260
+ `appq-auth-setup` call per role and reference the matching role in
261
+ `setupAuth({ project_id, role })`:
1126
262
 
1127
- Add `rejectUnauthorized: false` to your SDK configuration in `playwright.config.js`:
263
+ ```bash
264
+ npx appq-auth-setup --project-id 126 --role default
265
+ npx appq-auth-setup --project-id 126 --role manager
266
+ ```
267
+
268
+ ## CI/CD
269
+
270
+ Any CI system works — the SDK just needs the same environment variables
271
+ your local run uses, provided as secrets. GitHub Actions example:
272
+
273
+ ```yaml
274
+ # .github/workflows/playwright.yml
275
+ name: Playwright Tests
276
+ on:
277
+ push:
278
+ branches: [main]
279
+ pull_request:
280
+
281
+ jobs:
282
+ test:
283
+ runs-on: ubuntu-latest
284
+ steps:
285
+ - uses: actions/checkout@v4
286
+ - uses: actions/setup-node@v4
287
+ with:
288
+ node-version: 20
289
+ - run: npm ci
290
+ - run: npx playwright install --with-deps chromium
291
+
292
+ # Only if your app requires login — see "Authenticated apps" above
293
+ - run: npx appq-auth-setup --project-id 126 --role default
294
+ env:
295
+ APPLIQATION_SUT_BASE_URL: ${{ vars.STAGING_URL }}
296
+ APPQ_PROJECT_126_DEFAULT_USERNAME: ${{ secrets.APPQ_DEFAULT_USERNAME }}
297
+ APPQ_PROJECT_126_DEFAULT_PASSWORD: ${{ secrets.APPQ_DEFAULT_PASSWORD }}
298
+
299
+ - name: Run tests and report to Appliqation
300
+ env:
301
+ APPQ_ENABLED: '1'
302
+ APPLIQATION_API_KEY: ${{ secrets.APPLIQATION_API_KEY }}
303
+ APPLIQATION_PROJECT_KEY: ${{ secrets.APPLIQATION_PROJECT_KEY }}
304
+ APPLIQATION_ENVIRONMENT: Staging
305
+ APPLIQATION_RUN_TITLE: "CI Build #${{ github.run_number }}"
306
+ run: npx playwright test
307
+ ```
308
+
309
+ Nothing here is GitHub-specific beyond the workflow syntax — the same
310
+ `npm ci && npx playwright install && APPQ_ENABLED=1 npx playwright test`
311
+ sequence, with the env vars below set as secrets, works on GitLab CI,
312
+ CircleCI, Jenkins, or any other runner.
313
+
314
+ ## Configuration reference
315
+
316
+ ### Environment variables
317
+
318
+ | Variable | Required | Description |
319
+ |---|---|---|
320
+ | `APPLIQATION_API_KEY` | Yes | API key from Project Settings → API Keys |
321
+ | `APPLIQATION_PROJECT_KEY` | Yes | Project key from Project Settings |
322
+ | `TEST_APP_URL` | Recommended | Your own convention for Playwright's `baseURL` — read it in your `playwright.config.js`, the SDK doesn't read it directly |
323
+ | `APPLIQATION_ENVIRONMENT` | No | Environment label for the run (e.g. `Staging`) — also settable via `--appq-env` |
324
+ | `APPLIQATION_RUN_TITLE` | No | Custom run title — also settable via `--appq_run_title` |
325
+ | `APPLIQATION_RUN_ID` | No | Reuse an existing run instead of creating one (TDD iteration mode) |
326
+ | `APPQ_ENABLED` | No | `1`/`true` enables reporting — alternative to the `--appq` CLI flag |
327
+ | `APPLIQATION_ON_SCOPE_MISMATCH` | No | `cancel` (default) / `adhoc` / `filter` — see [Scoping runs](#scoping-runs-scenario-or-test-set) |
328
+ | `APPLIQATION_AUTO_TAG_ENABLED` | No | `false` disables auto-tagging (default: enabled). The tag name itself (`Appq_Auto`) is fixed, not configurable — see [Auto-tagging](#auto-tagging-test-cases) |
329
+ | `APPLIQATION_INSECURE` | No | Set to `allow` to permit `rejectUnauthorized: false` in CI/production — see [Troubleshooting](#tls-certificate-errors) |
330
+ | `LOG_LEVEL` | No | `ERROR` / `WARN` / `INFO` (default) / `DEBUG` |
331
+
332
+ `scenarioId`/`testSetId` and orphan-run handling (below) are reporter
333
+ constructor options, not environment variables — read your own env var of
334
+ choice into them in `playwright.config.js`, the same way the examples above
335
+ do for `scenarioId`.
336
+
337
+ ### Reporter options (`playwright.config.js`)
1128
338
 
1129
339
  ```javascript
1130
- const appliqationConfig = {
340
+ ['@appliqation/automation-sdk/playwright/reporter', {
1131
341
  apiKey: process.env.APPLIQATION_API_KEY,
1132
342
  projectKey: process.env.APPLIQATION_PROJECT_KEY,
343
+ environment: process.env.APPLIQATION_ENVIRONMENT,
1133
344
 
1134
- // Add this for self-signed certificates
1135
- rejectUnauthorized: false // ⚠️ Only use in development!
1136
- };
1137
- ```
1138
-
1139
- **⚠️ Security Note:** Only use `rejectUnauthorized: false` in development environments with self-signed certificates. In production with valid SSL certificates, remove this setting or set it to `true`.
1140
-
1141
- ---
1142
-
1143
- #### ❌ Results not appearing in portal
1144
-
1145
- **Possible causes:**
1146
-
1147
- 1. **Reporting not enabled** - Missing `APPQ_ENABLE` env var or `--appq` flag (MOST COMMON!)
1148
- - **Fix (Method 1 - Recommended):** Set `APPQ_ENABLE=1` environment variable
1149
- - Example: `APPQ_ENABLE=1 npx playwright test`
1150
- - **Fix (Method 2):** Add `-- --appq` flag to your test command
1151
- - Example: `npx playwright test -- --appq`
1152
- - Check console output for: "Appliqation reporting disabled"
1153
-
1154
- 2. **Orphan tests** - Tests don't have `mapAppqUuid()` calls
1155
- - **Fix:** Add UUID mapping to all tests
1156
- - Enable `logOrphans: true` to see which tests are orphans
345
+ scenarioId: parseInt(process.env.APPLIQATION_SCENARIO_ID) || undefined,
346
+ onScopeMismatch: process.env.APPLIQATION_ON_SCOPE_MISMATCH,
1157
347
 
1158
- 3. **API key invalid** - Authentication failed
1159
- - **Fix:** Regenerate API key from portal
348
+ autoCreateRun: true, // default: true
349
+ batchSubmit: true, // default: true
350
+ batchSize: 50, // results per batch
351
+ logOrphans: true, // log tests with no mapped UUID
352
+ logLevel: 'INFO',
1160
353
 
1161
- 4. **Network issues** - Portal unreachable
1162
- - **Fix:** Check `TEST_APP_URL` is accessible
354
+ deleteOrphanOnlyRuns: true, // delete a run if every test in it was orphaned
355
+ failOnOrphanOnlyRuns: true, // exit 1 in that case, so CI catches it
1163
356
 
1164
- ---
1165
-
1166
- ### Debug Mode
1167
-
1168
- Enable detailed logging to troubleshoot issues:
1169
-
1170
- **In .env:**
1171
- ```bash
1172
- LOG_LEVEL=DEBUG
357
+ rejectUnauthorized: true, // set false only for local self-signed certs
358
+ }]
1173
359
  ```
1174
360
 
1175
- **Or in config:**
1176
- ```javascript
1177
- const appliqationConfig = {
1178
- // ... other config
1179
- logLevel: 'DEBUG'
1180
- };
1181
- ```
1182
-
1183
- **Debug output shows:**
1184
- - ✅ API requests and responses
1185
- - ✅ Authentication flow details
1186
- - ✅ Result submission batches
1187
- - ✅ Orphan test detection
1188
- - ✅ Error stack traces
361
+ ## Orphan test handling
1189
362
 
1190
- ---
363
+ A test with no `mapAppqUuid()` call still runs, but its result can't be
364
+ linked to an Appliqation test case — it's logged as an **orphan** instead
365
+ of being submitted.
1191
366
 
1192
- ### Test Connection
367
+ If **every** test in a run is orphaned, the run is deleted automatically
368
+ (`deleteOrphanOnlyRuns`, default `true`) and the process exits non-zero
369
+ (`failOnOrphanOnlyRuns`, default `true`), so a fully-unmapped suite fails
370
+ CI loudly instead of quietly writing an empty run with an N/A pass rate
371
+ into your dashboards. If only *some* tests are orphaned, the run is kept,
372
+ mapped results are submitted normally, and the orphans are logged as
373
+ warnings.
1193
374
 
1194
- Verify SDK can reach your portal:
1195
-
1196
- **Create test file:** `test-connection.js`
1197
- ```javascript
1198
- const AppliqationClient = require('@appliqation/automation-sdk');
1199
- require('dotenv').config();
1200
-
1201
- async function testConnection() {
1202
- const client = new AppliqationClient({
1203
- apiKey: process.env.APPLIQATION_API_KEY,
1204
- projectKey: process.env.APPLIQATION_PROJECT_KEY
1205
- });
1206
-
1207
- const result = await client.testConnection();
1208
- console.log('Connection test:', result);
1209
- }
1210
-
1211
- testConnection();
1212
- ```
1213
-
1214
- **Run:**
1215
- ```bash
1216
- node test-connection.js
1217
- ```
1218
-
1219
- **Expected output:**
1220
- ```
1221
- Connection test: { success: true, message: 'Connected to Appliqation portal' }
1222
- ```
375
+ ## Auto-tagging test cases
1223
376
 
1224
- ---
377
+ The first time the SDK successfully submits a result for a test case
378
+ (pass, fail, or skip — any result the backend accepts), it tags that test
379
+ case with `Appq_Auto` in Appliqation, so you can see which test cases have
380
+ real automation coverage. The tag name is fixed, not configurable — appq's
381
+ own backend writes this exact same tag when it auto-tags at run creation,
382
+ so the two stay consistent. Tagging is fire-and-forget: a tagging failure
383
+ is logged as a warning and never affects your test results or exit code.
384
+ Disable it entirely with `APPLIQATION_AUTO_TAG_ENABLED=false`.
1225
385
 
1226
- ## Advanced Features
386
+ ## Advanced
1227
387
 
1228
- ### Custom Playwright Fixture (Auto JWT Refresh)
388
+ ### Auto-refreshing JWT fixture
1229
389
 
1230
- For long-running test suites, use the SDK's custom fixture to automatically refresh JWT tokens:
390
+ For long-running suites, use the SDK's Playwright fixture in place of
391
+ `@playwright/test` directly — it checks JWT expiry before each test and
392
+ refreshes if less than 5 minutes remain, updating the saved storage state:
1231
393
 
1232
- **File:** `tests/example.spec.js`
1233
394
  ```javascript
1234
- // Use the SDK's test fixture instead of Playwright's default
1235
395
  const { test, expect } = require('@appliqation/automation-sdk/playwright');
1236
396
 
1237
- test.describe('Authenticated Tests', () => {
1238
- test('should have valid JWT throughout test', async ({ page }) => {
1239
- // JWT is automatically refreshed if < 5 minutes remaining
1240
- await page.goto('/dashboard');
1241
- // Your test logic...
1242
- });
397
+ test('long-running suite stays authenticated', async ({ page }) => {
398
+ await page.goto('/dashboard');
1243
399
  });
1244
400
  ```
1245
401
 
1246
- **What it does:**
1247
- - ✅ Checks JWT expiry before each test
1248
- - ✅ Automatically refreshes if < 5 minutes remaining
1249
- - ✅ Updates `.auth/jwt.json` with new token
1250
- - ✅ Prevents authentication failures in long test runs
1251
-
1252
- ### Using Core SDK Directly
402
+ ### Using the client directly
1253
403
 
1254
- For custom integrations or non-Playwright frameworks:
404
+ For custom integrations outside Playwright's reporter lifecycle:
1255
405
 
1256
406
  ```javascript
1257
407
  const AppliqationClient = require('@appliqation/automation-sdk');
1258
408
 
1259
- // Initialize client
1260
409
  const client = new AppliqationClient({
1261
410
  apiKey: process.env.APPLIQATION_API_KEY,
1262
- projectKey: process.env.APPLIQATION_PROJECT_KEY
411
+ projectKey: process.env.APPLIQATION_PROJECT_KEY,
1263
412
  });
1264
413
 
1265
- // Create run
1266
414
  const run = await client.createRun({
1267
- environment: 'Production',
415
+ environment: 'Staging',
1268
416
  browsers: ['Chrome'],
1269
417
  device: 'Desktop',
1270
- os: 'Windows 11'
418
+ os: 'Windows 11',
1271
419
  });
1272
420
 
1273
- console.log('Run created:', run.runId);
1274
-
1275
- // Submit single result
1276
421
  await client.submitResult(run.runId, {
1277
422
  uuid: '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5',
1278
423
  status: 'passed',
1279
424
  browser: 'Chrome',
1280
- comment: 'Test passed successfully'
1281
425
  });
1282
426
 
1283
- // Submit batch results
1284
- const results = [
427
+ const summary = await client.submitBatch([
1285
428
  { uuid: '1154-uuid-1', runId: run.runId, status: 'passed', browser: 'Chrome' },
1286
- { uuid: '1154-uuid-2', runId: run.runId, status: 'failed', browser: 'Chrome' }
1287
- ];
1288
-
1289
- const summary = await client.submitBatch(results);
1290
- console.log(`Submitted: ${summary.success}/${summary.total} successful`);
429
+ { uuid: '1154-uuid-2', runId: run.runId, status: 'failed', browser: 'Chrome' },
430
+ ]);
431
+ console.log(`Submitted: ${summary.success} succeeded, ${summary.failed} failed`);
1291
432
  ```
1292
433
 
1293
- ### Custom Run Titles
434
+ ## How it works
1294
435
 
1295
- Set custom titles for test runs:
436
+ 1. **Global setup** (once, if you're using JWT auth for a gated app):
437
+ creates the run via `POST /api/automation/run/create`, requests a
438
+ browser JWT via `POST /api/auth/jwt/browser`, and saves authenticated
439
+ storage state so every worker starts already logged in.
440
+ 2. **Per test**: the reporter reads the UUID off `testInfo`'s annotations,
441
+ captures browser/OS/device metadata, and queues the result.
442
+ 3. **After the run**: results are submitted in batches
443
+ (`POST /api/automation/result/batch`), orphan tests are logged, and — if
444
+ configured — an orphan-only run is deleted and the process exits
445
+ non-zero.
1296
446
 
1297
- **Method 1: Environment Variable**
1298
- ```bash
1299
- APPLIQATION_RUN_TITLE="Sprint 24 - Regression Tests" npx playwright test
1300
- ```
1301
- ---
1302
-
1303
- ## API Reference
447
+ A timestamped execution summary (counts, run IDs, and any rejected/orphan
448
+ detail) is always written to
449
+ `test-results/AppQ_Execution_Summary/` after each run, independent of
450
+ whatever Playwright reporters you also have configured.
1304
451
 
1305
- ### Quick Reference
452
+ ## Troubleshooting
1306
453
 
1307
- Most commonly used SDK exports:
454
+ **Results not appearing in the portal** — almost always reporting wasn't
455
+ enabled: confirm `APPQ_ENABLED=1` or `-- --appq` was actually passed (the
456
+ console prints "Appliqation reporting enabled" when it is). Next most
457
+ common cause is orphan tests — check for a "no mapped UUID" warning in the
458
+ output. If neither, verify the API key and `APPLIQATION_PROJECT_KEY` are
459
+ correct with:
1308
460
 
1309
- **Reporter (for playwright.config.js):**
1310
461
  ```javascript
1311
- ['@appliqation/automation-sdk/playwright/reporter', config]
462
+ const AppliqationClient = require('@appliqation/automation-sdk');
463
+ new AppliqationClient({
464
+ apiKey: process.env.APPLIQATION_API_KEY,
465
+ projectKey: process.env.APPLIQATION_PROJECT_KEY,
466
+ }).testConnection().then(() => console.log('OK')).catch(console.error);
1312
467
  ```
1313
468
 
1314
- **Global Setup/Teardown:**
1315
- ```javascript
1316
- require.resolve('@appliqation/automation-sdk/playwright/global-setup')
1317
- require.resolve('@appliqation/automation-sdk/playwright/global-teardown')
1318
- ```
469
+ **`APPLIQATION_API_KEY is required`** — the reporter only reads
470
+ `process.env`, so make sure the variable is actually exported/injected
471
+ into the process running `playwright test` (a CI secret not mapped to an
472
+ `env:` key, or a `.env` file your own tooling never loaded, are the usual
473
+ causes).
1319
474
 
1320
- **Utilities:**
1321
- ```javascript
1322
- const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
1323
- ```
475
+ **Tests redirect to a login page** — for JWT-based auth, confirm
476
+ `globalSetup` is `require.resolve('@appliqation/automation-sdk/playwright/global-setup')`
477
+ and every project's `use.storageState` points at the same file
478
+ (`.auth/jwt.json` by default) that setup wrote. For `defineLogin`-based
479
+ auth, confirm `npx appq-auth-setup` ran before the tests and its
480
+ `--project-id`/`--role` match what `setupAuth()` is called with.
1324
481
 
1325
- **Core Client:**
1326
- ```javascript
1327
- const AppliqationClient = require('@appliqation/automation-sdk');
1328
- ```
482
+ **`Invalid UUID format`** — UUIDs must be `{nid}-{uuid}`, e.g.
483
+ `1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5`. A bare UUID with no leading
484
+ node ID, or a bare node ID with no UUID, both fail validation.
485
+
486
+ ### TLS certificate errors
1329
487
 
1330
- ### Full API Documentation
488
+ For local self-signed certificates, set `rejectUnauthorized: false` in the
489
+ reporter config. In CI or production, this throws a configuration error by
490
+ design — TLS bypass there would let a MITM attacker intercept result
491
+ submissions. If you genuinely need it in CI, set
492
+ `APPLIQATION_INSECURE=allow` to explicitly acknowledge the risk.
1331
493
 
1332
- For complete API reference including all methods, parameters, and return types, see the source code documentation in the `/src` directory.
494
+ ## Further reading
1333
495
 
1334
- ---
496
+ - [docs/SETUP.md](./docs/SETUP.md) — step-by-step setup guide
497
+ - [docs/JWT-AUTHENTICATION.md](./docs/JWT-AUTHENTICATION.md) — JWT auth flow in depth
1335
498
 
1336
499
  ## Support
1337
500
 
1338
- - 📧 **Email**: support@appliqation.com
1339
- - 📖 **Documentation**: https://docs.appliqation.com
1340
- - 🐛 **Issues**: https://github.com/appliqation/automation-sdk-js/issues
501
+ - Issues: https://github.com/appliqation/automation-sdk-js/issues
1341
502
 
1342
503
  ## License
1343
504
 
1344
- MIT License - see LICENSE file for details.
505
+ MIT see [LICENSE](./LICENSE).