@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 +330 -1169
- package/package.json +13 -34
- package/src/AppliqationClient.js +125 -25
- package/src/cli/auth-setup.js +308 -0
- package/src/constants.js +21 -1
- package/src/core/AuthManager.js +5 -0
- package/src/index.d.ts +159 -6
- package/src/login/index.d.ts +77 -0
- package/src/login/index.js +49 -0
- package/src/playwright/fixture.js +4 -1
- package/src/reporters/playwright/AppliqationReporter.js +159 -11
- package/src/services/OrphanTestService.js +21 -2
- package/src/services/ResultService.js +76 -45
- package/src/services/RunMatrixService.js +21 -1
- package/src/services/ScopeValidator.js +314 -0
- package/src/services/TaggingService.js +5 -5
- package/src/utils/PayloadBuilder.js +112 -21
- package/src/utils/index.js +12 -0
- package/src/utils/logger.js +59 -5
- package/src/utils/setupAuth.js +99 -0
- package/src/reporters/cypress/CypressReporter.js +0 -434
- package/src/reporters/cypress/UuidExtractor.js +0 -139
- package/src/reporters/cypress/index.js +0 -30
- package/src/reporters/jest/JestReporter.js +0 -408
- package/src/reporters/jest/UuidExtractor.js +0 -174
- package/src/reporters/jest/index.js +0 -28
package/README.md
CHANGED
|
@@ -1,169 +1,94 @@
|
|
|
1
1
|
# Appliqation Automation SDK
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
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
|
-
##
|
|
25
|
+
## Requirements
|
|
20
26
|
|
|
21
|
-
|
|
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
|
-
|
|
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
|
|
35
|
+
npm install @appliqation/automation-sdk --save-dev
|
|
52
36
|
```
|
|
53
37
|
|
|
54
|
-
|
|
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
|
-
###
|
|
45
|
+
### 1. Configure credentials
|
|
59
46
|
|
|
60
|
-
|
|
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
|
|
68
|
-
TEST_APP_URL=https://
|
|
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'],
|
|
127
|
-
['
|
|
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
|
-
**
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
116
|
+
# Enabled via env var (recommended)
|
|
117
|
+
APPQ_ENABLED=1 npx playwright test
|
|
296
118
|
|
|
297
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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
|
-
|
|
499
|
-
|
|
500
|
-
|
|
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
|
-
|
|
987
|
-
|
|
138
|
+
scenarioId: parseInt(process.env.APPLIQATION_SCENARIO_ID) || undefined,
|
|
139
|
+
// testSetId: parseInt(process.env.MY_SMOKE_TEST_SET_ID) || undefined,
|
|
988
140
|
|
|
989
|
-
//
|
|
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
|
-
|
|
994
|
-
|
|
995
|
-
-
|
|
996
|
-
|
|
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
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
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
|
-
|
|
158
|
+
Outside CI, with an interactive terminal, you're prompted to choose one of
|
|
159
|
+
the three before the run starts.
|
|
1009
160
|
|
|
1010
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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
|
-
|
|
178
|
+
2. **In your repo**, create `tests/automan/auth/login.ts`:
|
|
1025
179
|
|
|
1026
|
-
|
|
180
|
+
```typescript
|
|
181
|
+
import { defineLogin } from '@appliqation/automation-sdk/login';
|
|
1027
182
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
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
|
-
|
|
1038
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1066
|
-
|
|
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
|
-
|
|
1069
|
-
|
|
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
|
-
|
|
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
|
-
|
|
219
|
+
### In your test files
|
|
1077
220
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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
|
-
|
|
1086
|
-
|
|
1087
|
-
mapAppqUuid(testInfo, 'uuid-here');
|
|
225
|
+
test.use({
|
|
226
|
+
storageState: setupAuth({ project_id: 126, role: 'default' }),
|
|
1088
227
|
});
|
|
1089
|
-
```
|
|
1090
|
-
|
|
1091
|
-
---
|
|
1092
228
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1135
|
-
|
|
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
|
-
|
|
1159
|
-
|
|
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
|
-
|
|
1162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
386
|
+
## Advanced
|
|
1227
387
|
|
|
1228
|
-
###
|
|
388
|
+
### Auto-refreshing JWT fixture
|
|
1229
389
|
|
|
1230
|
-
For long-running
|
|
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
|
|
1238
|
-
|
|
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
|
-
|
|
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
|
|
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: '
|
|
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
|
-
|
|
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
|
-
|
|
434
|
+
## How it works
|
|
1294
435
|
|
|
1295
|
-
|
|
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
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
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
|
-
|
|
452
|
+
## Troubleshooting
|
|
1306
453
|
|
|
1307
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
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
|
-
**
|
|
1321
|
-
|
|
1322
|
-
|
|
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
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
|
505
|
+
MIT — see [LICENSE](./LICENSE).
|