@appliqation/automation-sdk 2.7.0 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +299 -1273
- package/package.json +5 -34
- package/src/AppliqationClient.js +125 -25
- package/src/cli/auth-setup.js +71 -8
- package/src/constants.js +21 -1
- package/src/core/AuthManager.js +5 -0
- package/src/index.d.ts +102 -6
- package/src/login/index.d.ts +2 -1
- package/src/login/index.js +2 -1
- package/src/playwright/fixture.js +4 -1
- package/src/reporters/playwright/AppliqationReporter.js +191 -13
- 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/logger.js +59 -5
- 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://
|
|
52
|
+
APPLIQATION_PROJECT_KEY=your-project-key
|
|
53
|
+
TEST_APP_URL=https://staging.your-app.com # used as Playwright's baseURL
|
|
69
54
|
```
|
|
70
55
|
|
|
71
|
-
|
|
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
|
|
80
|
-
```
|
|
81
|
-
|
|
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
|
|
156
|
-
|
|
157
|
-
Map your automated tests to Appliqation test cases using `mapAppqUuid()`:
|
|
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.
|
|
158
84
|
|
|
159
|
-
|
|
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,163 +98,126 @@ 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
|
-
|
|
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).
|
|
191
109
|
|
|
192
|
-
|
|
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-...`)
|
|
110
|
+
### 4. Run with reporting enabled
|
|
196
111
|
|
|
197
|
-
---
|
|
198
|
-
|
|
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
115
|
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
```
|
|
116
|
+
# Enabled via env var (recommended)
|
|
117
|
+
APPQ_ENABLED=1 npx playwright test
|
|
214
118
|
|
|
215
|
-
|
|
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)
|
|
119
|
+
# Enabled via CLI flag (note the -- separator, required by Playwright)
|
|
230
120
|
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
121
|
```
|
|
239
122
|
|
|
240
|
-
|
|
123
|
+
Both forms accept the usual Playwright flags (`--project`, `--headed`,
|
|
124
|
+
`-g`, a file path, etc.).
|
|
241
125
|
|
|
242
|
-
|
|
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`
|
|
126
|
+
## Scoping runs: Scenario or Test Set
|
|
248
127
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
- Results collected by SDK reporter
|
|
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.
|
|
254
132
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
4. **Global Teardown Runs** (once after all tests):
|
|
261
|
-
- Cleanup temporary files
|
|
262
|
-
- Log final summary
|
|
133
|
+
```javascript
|
|
134
|
+
const appliqationConfig = {
|
|
135
|
+
apiKey: process.env.APPLIQATION_API_KEY,
|
|
136
|
+
projectKey: process.env.APPLIQATION_PROJECT_KEY,
|
|
263
137
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- Navigate to the scenario you configured
|
|
267
|
-
- See test results in the run matrix!
|
|
138
|
+
scenarioId: parseInt(process.env.APPLIQATION_SCENARIO_ID) || undefined,
|
|
139
|
+
// testSetId: parseInt(process.env.MY_SMOKE_TEST_SET_ID) || undefined,
|
|
268
140
|
|
|
269
|
-
|
|
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
|
+
};
|
|
145
|
+
```
|
|
270
146
|
|
|
271
|
-
|
|
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:
|
|
272
151
|
|
|
273
|
-
|
|
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. |
|
|
274
157
|
|
|
275
|
-
|
|
158
|
+
Outside CI, with an interactive terminal, you're prompted to choose one of
|
|
159
|
+
the three before the run starts.
|
|
276
160
|
|
|
277
161
|
## Authenticated apps (gated SUTs)
|
|
278
162
|
|
|
279
163
|
If your application requires login, the SDK ships a portable auth setup
|
|
280
|
-
that works the same way in Appliqation's executor and in your
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
SSO, MFA, multi-step login, OAuth,
|
|
285
|
-
because you write the Playwright code that handles them.
|
|
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.
|
|
286
170
|
|
|
287
171
|
### One-time setup per project
|
|
288
172
|
|
|
289
|
-
1. **In Appliqation**: configure roles
|
|
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.
|
|
290
177
|
|
|
291
|
-
2. **In your repo
|
|
178
|
+
2. **In your repo**, create `tests/automan/auth/login.ts`:
|
|
292
179
|
|
|
293
180
|
```typescript
|
|
294
181
|
import { defineLogin } from '@appliqation/automation-sdk/login';
|
|
295
182
|
|
|
296
183
|
export default defineLogin(async (page, { username, password, role, baseURL }) => {
|
|
297
|
-
await page.goto('/login');
|
|
184
|
+
await page.goto('/login'); // baseURL handles env (staging/prod)
|
|
298
185
|
await page.getByLabel('Email').fill(username);
|
|
299
186
|
await page.getByLabel('Password').fill(password);
|
|
300
187
|
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
301
188
|
await page.waitForURL('**/dashboard');
|
|
302
189
|
|
|
303
|
-
// Branch on role for multi-role flows / SSO / role-specific landing pages
|
|
304
190
|
if (role === 'admin') {
|
|
305
191
|
await page.getByRole('button', { name: 'Switch to admin view' }).click();
|
|
306
192
|
}
|
|
307
193
|
});
|
|
308
194
|
```
|
|
309
195
|
|
|
310
|
-
Push to
|
|
196
|
+
Push to your project's default branch — Appliqation's GitHub webhook
|
|
197
|
+
ingests the file automatically.
|
|
311
198
|
|
|
312
|
-
3. **In Appliqation
|
|
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:
|
|
313
201
|
|
|
314
202
|
```bash
|
|
315
|
-
APPLIQATION_API_KEY="<
|
|
203
|
+
APPLIQATION_API_KEY="<project API key>"
|
|
316
204
|
APPLIQATION_BASE_URL="https://appliqation.io"
|
|
317
205
|
APPLIQATION_PROJECT_KEY=126
|
|
318
206
|
APPLIQATION_SUT_BASE_URL="<your SUT URL, e.g. https://staging.acme.com>"
|
|
319
207
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
APPQ_PROJECT_126_DEFAULT_PASSWORD="<paste password>"
|
|
208
|
+
APPQ_PROJECT_126_DEFAULT_USERNAME="<username>"
|
|
209
|
+
APPQ_PROJECT_126_DEFAULT_PASSWORD="<password>"
|
|
323
210
|
```
|
|
324
211
|
|
|
325
|
-
`APPLIQATION_SUT_BASE_URL` is
|
|
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.
|
|
326
215
|
|
|
327
|
-
4. **(Optional)**
|
|
216
|
+
4. **(Optional)** Use **Test login** on the project settings page to
|
|
217
|
+
validate `login.ts` against the live SUT before wiring up CI.
|
|
328
218
|
|
|
329
219
|
### In your test files
|
|
330
220
|
|
|
331
|
-
Use `setupAuth` to declare which storage state Playwright should use:
|
|
332
|
-
|
|
333
221
|
```typescript
|
|
334
222
|
const { mapAppqUuid, setupAuth } = require('@appliqation/automation-sdk/utils');
|
|
335
223
|
const { test, expect } = require('@playwright/test');
|
|
@@ -344,1136 +232,274 @@ test('manager dashboard loads', async ({ page }, testInfo) => {
|
|
|
344
232
|
});
|
|
345
233
|
```
|
|
346
234
|
|
|
347
|
-
`setupAuth()` returns a deterministic file path
|
|
348
|
-
|
|
349
|
-
- **In Appliqation's executor (cloud runs)**: the LoginHelper imports your `login.ts` from the canonical store, runs it, and writes the storage state at this path before your test runs. Nothing else for you to do.
|
|
350
|
-
- **In your CI / local**: run `npx appq-auth-setup` once before `playwright test`.
|
|
235
|
+
`setupAuth()` returns a deterministic storage-state file path — it does
|
|
236
|
+
**not** perform login itself:
|
|
351
237
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
- run: npx playwright test
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
The CLI:
|
|
361
|
-
1. Reads `APPQ_PROJECT_126_DEFAULT_USERNAME` / `_PASSWORD` from env
|
|
362
|
-
2. Reads `APPLIQATION_SUT_BASE_URL` for the SUT base URL
|
|
363
|
-
3. Dynamically imports `tests/appliqation/auth/login.ts` from your local checkout
|
|
364
|
-
4. Launches Chromium, runs your login function, saves the storage state to the path `setupAuth()` will resolve to
|
|
365
|
-
5. Tests run, already authenticated
|
|
366
|
-
|
|
367
|
-
Re-run the CLI when sessions expire (typical: once per CI run). Idempotent and fast on cache hits.
|
|
368
|
-
|
|
369
|
-
#### TypeScript loader (peer dependency)
|
|
370
|
-
|
|
371
|
-
If your `login.ts` is TypeScript (recommended for the type checking on `LoginContext`), the CLI needs a TS loader installed in your project. Install one as a dev dep:
|
|
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`.
|
|
372
243
|
|
|
373
244
|
```bash
|
|
374
|
-
|
|
375
|
-
# or
|
|
376
|
-
npm install --save-dev ts-node
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Plain `.js` / `.mjs` / `.cjs` login files don't need either.
|
|
380
|
-
|
|
381
|
-
#### Custom login file path
|
|
382
|
-
|
|
383
|
-
Default convention is `tests/appliqation/auth/login.ts`. Override with the `--login-file` flag or `APPQ_LOGIN_FILE` env var if your project uses a different layout:
|
|
384
|
-
|
|
385
|
-
```yaml
|
|
386
|
-
- run: npx appq-auth-setup --project-id 126 --role default --login-file e2e/auth/login.ts
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### Multiple roles
|
|
390
|
-
|
|
391
|
-
Configure each role in Project Settings, download the updated `.env` template (it lists all configured roles), fill in the values:
|
|
392
|
-
|
|
393
|
-
```bash
|
|
394
|
-
APPQ_PROJECT_126_DEFAULT_USERNAME="..."
|
|
395
|
-
APPQ_PROJECT_126_DEFAULT_PASSWORD="..."
|
|
396
|
-
APPQ_PROJECT_126_MANAGER_USERNAME="..."
|
|
397
|
-
APPQ_PROJECT_126_MANAGER_PASSWORD="..."
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
Then in CI — one `appq-auth-setup` call per role you want to test:
|
|
401
|
-
|
|
402
|
-
```yaml
|
|
403
|
-
- run: npx appq-auth-setup --project-id 126 --role default
|
|
404
|
-
- run: npx appq-auth-setup --project-id 126 --role manager
|
|
405
|
-
- run: npx playwright test
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
Tests reference the role they need: `setupAuth({ project_id: 126, role: 'manager' })`. Your `login.ts` receives the role in its `LoginContext` so you can branch login flow per role if needed.
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
## Enabling Appliqation Reporting (--appq Flag)
|
|
413
|
-
|
|
414
|
-
By default, Appliqation reporting is **DISABLED**. You must explicitly enable it by adding the `--appq` flag to your test command.
|
|
415
|
-
|
|
416
|
-
### Why Opt-In?
|
|
417
|
-
|
|
418
|
-
This design allows you to:
|
|
419
|
-
- ✅ Run tests locally without creating runs in Appliqation
|
|
420
|
-
- ✅ Debug and develop tests without affecting production data
|
|
421
|
-
- ✅ Control when results are sent to Appliqation portal
|
|
422
|
-
- ✅ Avoid accidental test runs in your dashboard
|
|
423
|
-
|
|
424
|
-
### How to Enable
|
|
425
|
-
|
|
426
|
-
You can enable Appliqation reporting in two ways:
|
|
427
|
-
|
|
428
|
-
#### Method 1: Environment Variable (Recommended - Simpler)
|
|
429
|
-
|
|
430
|
-
Set the `APPQ_ENABLE` environment variable to `1` or `true`:
|
|
431
|
-
|
|
432
|
-
```bash
|
|
433
|
-
# Enable reporting with environment variable
|
|
434
|
-
APPQ_ENABLE=1 npx playwright test
|
|
435
|
-
|
|
436
|
-
# Works with any other flags
|
|
437
|
-
APPQ_ENABLE=1 npx playwright test tests/login.spec.js --headed --project=chromium
|
|
438
|
-
|
|
439
|
-
# Also works with APPLIQATION_ENABLE
|
|
440
|
-
APPLIQATION_ENABLE=true npx playwright test
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
#### Method 2: CLI Flag (Requires `--` Separator)
|
|
444
|
-
|
|
445
|
-
Add `--appq` flag after the `--` separator:
|
|
446
|
-
|
|
447
|
-
```bash
|
|
448
|
-
# Enable reporting with CLI flag (note the -- separator)
|
|
449
|
-
npx playwright test -- --appq
|
|
450
|
-
|
|
451
|
-
# Works with any other flags
|
|
452
|
-
npx playwright test tests/login.spec.js --headed --project=chromium -- --appq
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
**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.
|
|
456
|
-
|
|
457
|
-
### Setting Run Title via CLI
|
|
458
|
-
|
|
459
|
-
You can also specify the run title directly in the command line using the `--appq_run_title` flag:
|
|
460
|
-
|
|
461
|
-
```bash
|
|
462
|
-
# Set run title via CLI flag
|
|
463
|
-
npx playwright test -- --appq --appq_run_title="My Custom Run Title"
|
|
464
|
-
|
|
465
|
-
# Works with other flags
|
|
466
|
-
npx playwright test tests/login.spec.js --headed --project=chromium -- --appq --appq_run_title="Login Tests"
|
|
467
|
-
|
|
468
|
-
# With quotes for titles containing spaces
|
|
469
|
-
npx playwright test -- --appq --appq_run_title="Regression Suite - Sprint 23"
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
**Priority Order for Run Title:**
|
|
473
|
-
1. Config file `title` option (if specified)
|
|
474
|
-
2. CLI flag `--appq_run_title` (new!)
|
|
475
|
-
3. Environment variable `APPLIQATION_RUN_TITLE`
|
|
476
|
-
4. Auto-generated timestamp (default)
|
|
477
|
-
|
|
478
|
-
**Examples:**
|
|
479
|
-
```bash
|
|
480
|
-
# Method 1: Environment variable
|
|
481
|
-
APPLIQATION_RUN_TITLE="My Run" npx playwright test -- --appq
|
|
482
|
-
|
|
483
|
-
# Method 2: CLI flag (overrides environment variable)
|
|
484
|
-
APPLIQATION_RUN_TITLE="Old Title" npx playwright test -- --appq --appq_run_title="New Title"
|
|
485
|
-
# Result: Run title will be "New Title"
|
|
486
|
-
|
|
487
|
-
# Method 3: Combined usage
|
|
488
|
-
npx playwright test -- --appq --appq_run_title="Sprint 23 Regression"
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
### What Happens When Reporting is Disabled
|
|
492
|
-
|
|
493
|
-
When you run tests **without** enabling reporting (no flag, no env var):
|
|
494
|
-
- ✅ Tests execute normally
|
|
495
|
-
- ✅ Execution summary file is still created
|
|
496
|
-
- ❌ No run is created in Appliqation
|
|
497
|
-
- ❌ No results are sent to Appliqation portal
|
|
498
|
-
- ℹ️ Console shows: "Appliqation reporting disabled: Add --appq flag to send results"
|
|
499
|
-
|
|
500
|
-
**Example:**
|
|
501
|
-
```bash
|
|
502
|
-
# Reporting disabled - no results sent to Appliqation
|
|
245
|
+
npx appq-auth-setup --project-id 126 --role default
|
|
503
246
|
npx playwright test
|
|
504
247
|
```
|
|
505
248
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
When you run tests **with** reporting enabled (using flag or env var):
|
|
509
|
-
- ✅ Tests execute normally
|
|
510
|
-
- ✅ Run matrix created in Appliqation
|
|
511
|
-
- ✅ Results sent to Appliqation portal
|
|
512
|
-
- ✅ Execution summary file created
|
|
513
|
-
- ✅ Console shows: "Appliqation reporting enabled: Results will be sent to Appliqation portal"
|
|
514
|
-
|
|
515
|
-
**Examples:**
|
|
516
|
-
```bash
|
|
517
|
-
# Reporting enabled with environment variable
|
|
518
|
-
APPQ_ENABLE=1 npx playwright test
|
|
519
|
-
|
|
520
|
-
# Reporting enabled with CLI flag
|
|
521
|
-
npx playwright test -- --appq
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
---
|
|
525
|
-
|
|
526
|
-
## Execution Summary Files
|
|
527
|
-
|
|
528
|
-
After each test run, the SDK automatically creates a timestamped summary file with comprehensive results.
|
|
529
|
-
|
|
530
|
-
**Location:** `test-results/AppQ_Execution_Summary/`
|
|
531
|
-
|
|
532
|
-
**Filename Format:** `{run_title}_2025-01-21_14-30-45.txt`
|
|
533
|
-
|
|
534
|
-
**What's Included:**
|
|
535
|
-
- ✅ Execution time (start, end, duration)
|
|
536
|
-
- ✅ Test counts (submitted, accepted, rejected, passed, failed, skipped)
|
|
537
|
-
- ✅ Run IDs for all created matrices
|
|
538
|
-
- ✅ Detailed error information (duplicates, orphans, backend rejections)
|
|
539
|
-
- ✅ Complete ASCII table (same as terminal output)
|
|
540
|
-
|
|
541
|
-
**Example:**
|
|
542
|
-
```
|
|
543
|
-
test-results/
|
|
544
|
-
└── AppQ_Execution_Summary/
|
|
545
|
-
├── My_Test_Run_2025-01-21_09-30-15.txt
|
|
546
|
-
├── My_Test_Run_2025-01-21_14-45-30.txt
|
|
547
|
-
└── Regression_Suite_2025-01-22_08-00-00.txt
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
**Features:**
|
|
551
|
-
- Always enabled automatically (no configuration needed)
|
|
552
|
-
- Each run creates a NEW file (never overwrites)
|
|
553
|
-
- If file writing fails, tests continue normally (non-blocking)
|
|
554
|
-
|
|
555
|
-
**Sample File Content:**
|
|
556
|
-
```
|
|
557
|
-
═══════════════════════════════════════════════════════════
|
|
558
|
-
APPLIQATION TEST EXECUTION SUMMARY
|
|
559
|
-
═══════════════════════════════════════════════════════════
|
|
560
|
-
|
|
561
|
-
EXECUTION METADATA:
|
|
562
|
-
─────────────────────────────────────────────────────────
|
|
563
|
-
Start Time: 2025-01-21T14:30:15.123Z
|
|
564
|
-
End Time: 2025-01-21T14:35:45.456Z
|
|
565
|
-
Duration: 5m 30s
|
|
566
|
-
Run Title: My_Test_Run
|
|
567
|
-
|
|
568
|
-
╔═══════════════════════════════════════════════════════════╗
|
|
569
|
-
║ Appliqation Test Results Summary ║
|
|
570
|
-
╠═══════════════════════════════════════════════════════════╣
|
|
571
|
-
║ Submitted to Backend: ║
|
|
572
|
-
║ Total Submitted: 10 ║
|
|
573
|
-
║ ✅ Accepted: 8 ║
|
|
574
|
-
║ ❌ Rejected: 2 ║
|
|
575
|
-
║ ║
|
|
576
|
-
║ Test Execution Results (Playwright): ║
|
|
577
|
-
║ Passed: 8 ║
|
|
578
|
-
║ Failed: 0 ║
|
|
579
|
-
║ Skipped: 0 ║
|
|
580
|
-
║ ║
|
|
581
|
-
║ Not Submitted: ║
|
|
582
|
-
║ Orphan (No UUID): 3 ║
|
|
583
|
-
║ Duplicates: 2 ║
|
|
584
|
-
╠═══════════════════════════════════════════════════════════╣
|
|
585
|
-
║ Run Matrices Created: 2 ║
|
|
586
|
-
║ Desktop-Windows : run_abc123_1234567890 ║
|
|
587
|
-
║ Desktop-Linux : run_xyz789_0987654321 ║
|
|
588
|
-
╚═══════════════════════════════════════════════════════════╝
|
|
589
|
-
|
|
590
|
-
DETAILED ERRORS & WARNINGS:
|
|
591
|
-
═══════════════════════════════════════════════════════════
|
|
592
|
-
[Duplicate UUIDs, Orphan Tests, and Backend Rejections details...]
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
---
|
|
596
|
-
|
|
597
|
-
## Auto-Tagging Test Cases
|
|
598
|
-
|
|
599
|
-
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.
|
|
600
|
-
|
|
601
|
-
### How It Works
|
|
602
|
-
|
|
603
|
-
1. **Test runs and passes** → SDK submits result to Appliqation
|
|
604
|
-
2. **Backend accepts result** → SDK triggers auto-tagging (fire-and-forget)
|
|
605
|
-
3. **Check if already tagged** → Skip if test case already has the tag
|
|
606
|
-
4. **Add tag** → Test case gets tagged in Appliqation UI
|
|
607
|
-
|
|
608
|
-
**Key Features:**
|
|
609
|
-
- ✅ **Enabled by default** when Appliqation reporting is enabled
|
|
610
|
-
- ✅ **Fire-and-forget** - tagging failures never block your test runs
|
|
611
|
-
- ✅ **Smart deduplication** - checks before tagging, won't create duplicate tags
|
|
612
|
-
- ✅ **Only accepted results** - backend-rejected results are NOT tagged
|
|
613
|
-
- ✅ **Works for both** single and batch result submissions
|
|
614
|
-
- ✅ **Async execution** - zero impact on test execution performance
|
|
615
|
-
|
|
616
|
-
### Configuration
|
|
617
|
-
|
|
618
|
-
#### Environment Variables
|
|
619
|
-
|
|
620
|
-
Add to your `.env` file:
|
|
621
|
-
|
|
622
|
-
```bash
|
|
623
|
-
# Auto-Tagging Configuration (optional - all have sensible defaults)
|
|
624
|
-
APPLIQATION_AUTO_TAG_ENABLED=true # Enable/disable (default: true)
|
|
625
|
-
APPLIQATION_AUTO_TAG_NAME=Appq_automated # Custom tag name (default: Appq_automated)
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
#### Playwright Reporter Config
|
|
629
|
-
|
|
630
|
-
Configure in `playwright.config.js`:
|
|
631
|
-
|
|
632
|
-
```javascript
|
|
633
|
-
reporter: [
|
|
634
|
-
['@appliqation/automation-sdk/playwright/reporter', {
|
|
635
|
-
apiKey: process.env.APPLIQATION_API_KEY,
|
|
636
|
-
projectKey: process.env.APPLIQATION_PROJECT_KEY,
|
|
637
|
-
|
|
638
|
-
// Auto-tagging options (optional)
|
|
639
|
-
autoTag: true, // Enable auto-tagging (default: true)
|
|
640
|
-
autoTagName: 'My_Custom_Tag' // Custom tag name (default: 'Appq_automated')
|
|
641
|
-
}]
|
|
642
|
-
]
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
#### Programmatic Configuration
|
|
249
|
+
Re-run the CLI whenever sessions expire (typically once per CI run) — it's
|
|
250
|
+
idempotent and fast on cache hits.
|
|
646
251
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
apiKey: 'your_api_key',
|
|
654
|
-
projectKey: 'your_project_key',
|
|
655
|
-
|
|
656
|
-
// Auto-tagging options
|
|
657
|
-
options: {
|
|
658
|
-
autoTag: true, // Enable auto-tagging (default: true)
|
|
659
|
-
autoTagName: 'Automated_Test' // Custom tag name (default: 'Appq_automated')
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
```
|
|
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.
|
|
663
258
|
|
|
664
|
-
|
|
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 })`:
|
|
665
262
|
|
|
666
|
-
If you want to disable auto-tagging:
|
|
667
|
-
|
|
668
|
-
**Option 1: Environment Variable**
|
|
669
263
|
```bash
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
**Option 2: Config**
|
|
674
|
-
```javascript
|
|
675
|
-
{
|
|
676
|
-
options: {
|
|
677
|
-
autoTag: false
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
### What You'll See
|
|
683
|
-
|
|
684
|
-
When auto-tagging is working:
|
|
685
|
-
|
|
686
|
-
```
|
|
687
|
-
✅ Auto-tagged 3 test case(s) with "Appq_automated"
|
|
264
|
+
npx appq-auth-setup --project-id 126 --role default
|
|
265
|
+
npx appq-auth-setup --project-id 126 --role manager
|
|
688
266
|
```
|
|
689
267
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
```
|
|
693
|
-
DEBUG: Skipped 3 already-tagged test case(s)
|
|
694
|
-
```
|
|
268
|
+
## CI/CD
|
|
695
269
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
```
|
|
699
|
-
⚠️ Auto-tagging failed (non-blocking): Connection timeout
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Troubleshooting
|
|
703
|
-
|
|
704
|
-
**Q: I don't see the tag in Appliqation UI**
|
|
705
|
-
|
|
706
|
-
Check:
|
|
707
|
-
1. Is `APPQ_ENABLE=1` set? (Auto-tagging only works when reporting is enabled)
|
|
708
|
-
2. Did the test result get accepted by backend? (Check for backend validation errors)
|
|
709
|
-
3. Check SDK logs for "Auto-tagged X test case(s)" message
|
|
710
|
-
|
|
711
|
-
**Q: Can I use a custom tag name?**
|
|
712
|
-
|
|
713
|
-
Yes! Set `APPLIQATION_AUTO_TAG_NAME=Your_Tag_Name` in your `.env` file or use the config options shown above.
|
|
714
|
-
|
|
715
|
-
**Q: Does tagging failure affect my test results?**
|
|
716
|
-
|
|
717
|
-
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.
|
|
718
|
-
|
|
719
|
-
---
|
|
720
|
-
|
|
721
|
-
## Handling Orphan Tests
|
|
722
|
-
|
|
723
|
-
### What are Orphan Tests?
|
|
724
|
-
|
|
725
|
-
**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."
|
|
726
|
-
|
|
727
|
-
```javascript
|
|
728
|
-
// ❌ This test will be orphaned (no UUID annotation)
|
|
729
|
-
test('Login with valid credentials', async ({ page }) => {
|
|
730
|
-
await page.goto('/login');
|
|
731
|
-
await page.fill('#username', 'user@example.com');
|
|
732
|
-
// ... test code
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
// ✅ This test will be properly mapped (has UUID annotation)
|
|
736
|
-
test('Login with valid credentials', { tag: '@uuid:1154-abc-def' }, async ({ page }) => {
|
|
737
|
-
await page.goto('/login');
|
|
738
|
-
await page.fill('#username', 'user@example.com');
|
|
739
|
-
// ... test code
|
|
740
|
-
});
|
|
741
|
-
```
|
|
270
|
+
Any CI system works — the SDK just needs the same environment variables
|
|
271
|
+
your local run uses, provided as secrets. GitHub Actions example:
|
|
742
272
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
###
|
|
808
|
-
|
|
809
|
-
When your test suite has **both valid and orphan tests**, the SDK handles it gracefully:
|
|
810
|
-
|
|
811
|
-
```javascript
|
|
812
|
-
// Project 1162: 3 tests total
|
|
813
|
-
test('Valid Test 1', { tag: '@uuid:1154-abc' }, async ({ page }) => {
|
|
814
|
-
// ✅ Will be submitted to Appliqation
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
test('Orphan Test 1', async ({ page }) => {
|
|
818
|
-
// ⚠️ Logged as warning, not submitted
|
|
819
|
-
});
|
|
820
|
-
|
|
821
|
-
test('Valid Test 2', { tag: '@uuid:1155-def' }, async ({ page }) => {
|
|
822
|
-
// ✅ Will be submitted to Appliqation
|
|
823
|
-
});
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
**Result:**
|
|
827
|
-
- ✅ Run is kept (because 2 tests have UUIDs)
|
|
828
|
-
- ✅ 2 valid results submitted to Appliqation
|
|
829
|
-
- ⚠️ 1 orphan logged in console and summary file
|
|
830
|
-
- ✅ CI/CD passes (because at least some tests were valid)
|
|
831
|
-
- ✅ Analytics remain accurate (only valid tests counted)
|
|
832
|
-
|
|
833
|
-
### Troubleshooting FAQ
|
|
834
|
-
|
|
835
|
-
**Q: Why does my run get deleted?**
|
|
836
|
-
|
|
837
|
-
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.
|
|
838
|
-
|
|
839
|
-
**Q: How do I disable automatic deletion?**
|
|
840
|
-
|
|
841
|
-
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.
|
|
842
|
-
|
|
843
|
-
**Q: Can I keep orphan-only runs but still fail CI/CD?**
|
|
844
|
-
|
|
845
|
-
Yes! Set:
|
|
846
|
-
```env
|
|
847
|
-
APPLIQATION_DELETE_ORPHAN_RUNS=false
|
|
848
|
-
APPLIQATION_FAIL_ON_ORPHAN_RUNS=true
|
|
849
|
-
```
|
|
850
|
-
|
|
851
|
-
This will create the run in Appliqation but still fail your pipeline, forcing developers to fix UUIDs.
|
|
852
|
-
|
|
853
|
-
**Q: Where do I find UUIDs for my tests?**
|
|
854
|
-
|
|
855
|
-
1. Log into Appliqation portal
|
|
856
|
-
2. Navigate to your project
|
|
857
|
-
3. Go to "Test Cases" tab
|
|
858
|
-
4. Find your test case
|
|
859
|
-
5. The UUID is in the format: `{test_nid}-{uuid}` (e.g., `1154-c1f9559c-b978-43cc-9c76-fd539c717cb4`)
|
|
860
|
-
|
|
861
|
-
**Q: Does orphan cleanup affect test execution?**
|
|
862
|
-
|
|
863
|
-
No! Cleanup happens **after** all tests complete in the `onEnd()` hook. Test execution is never blocked or interrupted.
|
|
864
|
-
|
|
865
|
-
**Q: What if deletion fails?**
|
|
866
|
-
|
|
867
|
-
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.
|
|
868
|
-
|
|
869
|
-
---
|
|
870
|
-
|
|
871
|
-
## How It Works
|
|
872
|
-
|
|
873
|
-
Understanding the SDK's authentication and result submission flow helps troubleshoot issues.
|
|
874
|
-
|
|
875
|
-
### Authentication & Test Execution Flow
|
|
876
|
-
|
|
877
|
-
```
|
|
878
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
879
|
-
│ GLOBAL SETUP (Runs Once) │
|
|
880
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
881
|
-
│ │
|
|
882
|
-
│ 1. Read .env configuration │
|
|
883
|
-
│ ├─ APPLIQATION_API_KEY │
|
|
884
|
-
│ ├─ APPLIQATION_PROJECT_KEY │
|
|
885
|
-
│ ├─ TEST_APP_URL │
|
|
886
|
-
│
|
|
887
|
-
│ │ │
|
|
888
|
-
│ ▼ │
|
|
889
|
-
│ 2. Create automation run via API │
|
|
890
|
-
│ POST /api/automation/run/create │
|
|
891
|
-
│ ├─ Returns: run_id, api_token │
|
|
892
|
-
│ └─ Saves to: process.env.APPLIQATION_RUN_ID │
|
|
893
|
-
│ │ │
|
|
894
|
-
│ ▼ │
|
|
895
|
-
│ 3. Request browser JWT token │
|
|
896
|
-
│ POST /api/auth/jwt/browser │
|
|
897
|
-
│ ├─ Send: api_key │
|
|
898
|
-
│ └─ Returns: jwt_token, expires_in │
|
|
899
|
-
│ │ │
|
|
900
|
-
│ ▼ │
|
|
901
|
-
│ 4. Setup browser authentication │
|
|
902
|
-
│ ├─ Launch headless browser │
|
|
903
|
-
│ ├─ Navigate to baseURL │
|
|
904
|
-
│ ├─ Set cookie: appliqation_jwt = jwt_token │
|
|
905
|
-
│ ├─ Save storage state to: .auth/jwt.json │
|
|
906
|
-
│ └─ Close browser │
|
|
907
|
-
│ │
|
|
908
|
-
│ ✅ Setup complete - All tests will use authenticated state │
|
|
909
|
-
│ │
|
|
910
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
911
|
-
│
|
|
912
|
-
▼
|
|
913
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
914
|
-
│ TEST EXECUTION (Per Worker) │
|
|
915
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
916
|
-
│ │
|
|
917
|
-
│ For each test: │
|
|
918
|
-
│ │
|
|
919
|
-
│ 1. Load storage state from .auth/jwt.json │
|
|
920
|
-
│ └─ Browser starts with JWT cookie already set │
|
|
921
|
-
│ │ │
|
|
922
|
-
│ ▼ │
|
|
923
|
-
│ 2. Run test code │
|
|
924
|
-
│ ├─ mapAppqUuid(testInfo, '1154-uuid-here') │
|
|
925
|
-
│ ├─ Execute test steps (page.goto, clicks, etc.) │
|
|
926
|
-
│ └─ Collect result: passed/failed/skipped │
|
|
927
|
-
│ │ │
|
|
928
|
-
│ ▼ │
|
|
929
|
-
│ 3. Reporter collects result │
|
|
930
|
-
│ ├─ Extract UUID from test.info().annotations │
|
|
931
|
-
│ ├─ Capture browser/OS/device metadata │
|
|
932
|
-
│ ├─ Add to batch queue │
|
|
933
|
-
│ └─ (Batch submitted when size reached or tests complete) │
|
|
934
|
-
│ │
|
|
935
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
936
|
-
│
|
|
937
|
-
▼
|
|
938
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
939
|
-
│ REPORTER (After All Tests) │
|
|
940
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
941
|
-
│ │
|
|
942
|
-
│ 1. Batch all test results │
|
|
943
|
-
│ └─ Group by 50 results per batch (configurable) │
|
|
944
|
-
│ │ │
|
|
945
|
-
│ ▼ │
|
|
946
|
-
│ 2. Submit to portal │
|
|
947
|
-
│ POST /api/automation/result/batch │
|
|
948
|
-
│ ├─ Send: run_id, results[], api_key │
|
|
949
|
-
│ └─ Retry on failure (exponential backoff) │
|
|
950
|
-
│ │ │
|
|
951
|
-
│ ▼ │
|
|
952
|
-
│ 3. Handle orphan tests (tests without UUIDs) │
|
|
953
|
-
│ POST /api/automation/orphans │
|
|
954
|
-
│ └─ Logs tests that need UUID mapping │
|
|
955
|
-
│ │ │
|
|
956
|
-
│ ▼ │
|
|
957
|
-
│ ✅ All results submitted to portal │
|
|
958
|
-
│ │
|
|
959
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
960
|
-
│
|
|
961
|
-
▼
|
|
962
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
963
|
-
│ GLOBAL TEARDOWN (Runs Once) │
|
|
964
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
965
|
-
│ │
|
|
966
|
-
│ 1. Cleanup temporary files (optional) │
|
|
967
|
-
│ 2. Log final summary │
|
|
968
|
-
│ │
|
|
969
|
-
│ ✅ Test run complete │
|
|
970
|
-
│ │
|
|
971
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
972
|
-
```
|
|
973
|
-
|
|
974
|
-
**Key Points:**
|
|
975
|
-
- Authentication happens **once** in global-setup
|
|
976
|
-
- JWT token saved to `.auth/jwt.json`
|
|
977
|
-
- All test workers reuse the same authenticated state
|
|
978
|
-
- No per-test login required!
|
|
979
|
-
|
|
980
|
-
### SDK Architecture
|
|
981
|
-
|
|
982
|
-
```
|
|
983
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
984
|
-
│ Playwright Test Suite │
|
|
985
|
-
│ │
|
|
986
|
-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
987
|
-
│ │ Test File 1 │ │ Test File 2 │ │ Test File 3 │ │
|
|
988
|
-
│ │ │ │ │ │ │ │
|
|
989
|
-
│ │ mapAppqUuid()│ │ mapAppqUuid()│ │ mapAppqUuid()│ │
|
|
990
|
-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
991
|
-
│ │ │ │ │
|
|
992
|
-
└─────────┼────────────────────┼────────────────────┼──────────────┘
|
|
993
|
-
│ │ │
|
|
994
|
-
└────────────────────┴────────────────────┘
|
|
995
|
-
│
|
|
996
|
-
▼
|
|
997
|
-
┌─────────────────────────────────────────┐
|
|
998
|
-
│ Appliqation SDK Reporter │
|
|
999
|
-
│ │
|
|
1000
|
-
│ • Collects test results │
|
|
1001
|
-
│ • Extracts UUIDs from annotations │
|
|
1002
|
-
│ • Batches submissions │
|
|
1003
|
-
│ • Handles browser/OS/device metadata │
|
|
1004
|
-
└─────────────────────────────────────────┘
|
|
1005
|
-
│
|
|
1006
|
-
▼
|
|
1007
|
-
┌─────────────────────────────────────────┐
|
|
1008
|
-
│ Appliqation HTTP Client │
|
|
1009
|
-
│ │
|
|
1010
|
-
│ • API key authentication │
|
|
1011
|
-
│ • Connection pooling │
|
|
1012
|
-
│ • Exponential backoff retry │
|
|
1013
|
-
└─────────────────────────────────────────┘
|
|
1014
|
-
│
|
|
1015
|
-
▼
|
|
1016
|
-
┌─────────────────────────────────────────┐
|
|
1017
|
-
│ Appliqation Portal API │
|
|
1018
|
-
│ │
|
|
1019
|
-
│ • Validates API key │
|
|
1020
|
-
│ • Creates run matrices │
|
|
1021
|
-
│ • Stores test results │
|
|
1022
|
-
│ • Generates reports │
|
|
1023
|
-
└─────────────────────────────────────────┘
|
|
1024
|
-
```
|
|
1025
|
-
|
|
1026
|
-
### File Structure After Setup
|
|
1027
|
-
|
|
1028
|
-
```
|
|
1029
|
-
your-playwright-project/
|
|
1030
|
-
├── .auth/ # Auto-created by SDK global-setup
|
|
1031
|
-
│ └── jwt.json # Browser authentication state
|
|
1032
|
-
│
|
|
1033
|
-
├── .env # YOU CREATE THIS (Step 2)
|
|
1034
|
-
│ ├── APPLIQATION_API_KEY=appq_live_xxxxx
|
|
1035
|
-
│ ├── APPLIQATION_PROJECT_KEY=your-project-key
|
|
1036
|
-
│ ├── TEST_APP_URL=https://your-domain.com
|
|
1037
|
-
│
|
|
1038
|
-
│
|
|
1039
|
-
├── playwright.config.js # YOU UPDATE THIS (Step 3)
|
|
1040
|
-
│ ├── globalSetup: require.resolve('@appliqation/automation-sdk/playwright/global-setup')
|
|
1041
|
-
│ ├── globalTeardown: require.resolve('@appliqation/automation-sdk/playwright/global-teardown')
|
|
1042
|
-
│ ├── use: { storageState: '.auth/jwt.json' }
|
|
1043
|
-
│ └── reporter: ['@appliqation/automation-sdk/playwright/reporter', config]
|
|
1044
|
-
│
|
|
1045
|
-
├── tests/
|
|
1046
|
-
│ ├── login.spec.js # YOUR TESTS (Step 4)
|
|
1047
|
-
│ │ ├── const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
|
|
1048
|
-
│ │ └── mapAppqUuid(testInfo, '1154-uuid-here');
|
|
1049
|
-
│ │
|
|
1050
|
-
│ └── checkout.spec.js
|
|
1051
|
-
│
|
|
1052
|
-
├── package.json
|
|
1053
|
-
│ └── dependencies:
|
|
1054
|
-
│ ├── @playwright/test
|
|
1055
|
-
│ ├── @appliqation/automation-sdk
|
|
1056
|
-
│ └── dotenv # Required for .env loading
|
|
1057
|
-
│
|
|
1058
|
-
└── node_modules/
|
|
1059
|
-
└── @appliqation/automation-sdk/
|
|
1060
|
-
└── playwright/
|
|
1061
|
-
├── global-setup.js # SDK provides this!
|
|
1062
|
-
├── global-teardown.js # SDK provides this!
|
|
1063
|
-
└── index.js # Reporter
|
|
1064
|
-
```
|
|
1065
|
-
|
|
1066
|
-
---
|
|
1067
|
-
|
|
1068
|
-
## Configuration Reference
|
|
1069
|
-
|
|
1070
|
-
### Environment Variables (.env)
|
|
1071
|
-
|
|
1072
|
-
All environment variables and their purposes:
|
|
1073
|
-
|
|
1074
|
-
| Variable | Required | Description | Example |
|
|
1075
|
-
|----------|----------|-------------|---------|
|
|
1076
|
-
| `TEST_APP_URL` | ✅ Yes | Your Test App URL (no trailing slash) | `https://example.com` |
|
|
1077
|
-
| `APPLIQATION_API_KEY` | ✅ Yes | API key from `/admin/config/appliqation/api-keys` | `appq_live_abc123xyz...` |
|
|
1078
|
-
| `APPLIQATION_PROJECT_KEY` | ✅ Yes | Project key from project settings | `my-project-key` |
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
**Common Configurations:**
|
|
1082
|
-
|
|
1083
|
-
**CI/CD Pipeline:**
|
|
1084
|
-
```javascript
|
|
1085
|
-
{
|
|
1086
|
-
environment: process.env.CI_ENVIRONMENT || 'CI',
|
|
1087
|
-
title: `Build #${process.env.CI_BUILD_NUMBER}`,
|
|
1088
|
-
logLevel: 'ERROR', // Less verbose in CI
|
|
1089
|
-
batchSize: 100 // Larger batches for speed
|
|
1090
|
-
}
|
|
1091
|
-
```
|
|
1092
|
-
|
|
1093
|
-
**Local Development:**
|
|
1094
|
-
```javascript
|
|
1095
|
-
{
|
|
1096
|
-
environment: 'Local',
|
|
1097
|
-
logLevel: 'DEBUG', // Detailed logs
|
|
1098
|
-
logOrphans: true, // See unmapped tests
|
|
1099
|
-
rejectUnauthorized: false // Allow local SSL
|
|
1100
|
-
}
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
---
|
|
1104
|
-
|
|
1105
|
-
## Adding Test Case UUIDs
|
|
1106
|
-
|
|
1107
|
-
Map your automated tests to Appliqation test cases to track results.
|
|
1108
|
-
|
|
1109
|
-
### Method: mapAppqUuid()
|
|
1110
|
-
|
|
1111
|
-
**Import the utility:**
|
|
1112
|
-
```javascript
|
|
1113
|
-
const { mapAppqUuid } = require('@appliqation/automation-sdk/utils');
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
**Use in tests:**
|
|
1117
|
-
```javascript
|
|
1118
|
-
test('test description', async ({ page }, testInfo) => {
|
|
1119
|
-
// ^^^^^^^^ Required parameter!
|
|
1120
|
-
|
|
1121
|
-
// Map to test case UUID
|
|
1122
|
-
mapAppqUuid(testInfo, '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5');
|
|
1123
|
-
|
|
1124
|
-
// Your test code...
|
|
1125
|
-
});
|
|
1126
|
-
```
|
|
1127
|
-
|
|
1128
|
-
**Important:**
|
|
1129
|
-
- ⚠️ Always include `testInfo` as second parameter
|
|
1130
|
-
- ⚠️ UUID format: `nid-uuid` (e.g., `1154-abc123...`)
|
|
1131
|
-
- ⚠️ Get UUIDs from Appliqation portal test cases
|
|
1132
|
-
|
|
1133
|
-
### Getting UUIDs from Portal
|
|
1134
|
-
|
|
1135
|
-
1. Login to Appliqation portal
|
|
1136
|
-
2. Navigate to **Test Cases** section
|
|
1137
|
-
3. Open the test case you want to map
|
|
1138
|
-
4. Copy the UUID (shown in test case details)
|
|
1139
|
-
5. Use format: `nid-uuid` where:
|
|
1140
|
-
- `nid` = Test case node ID (e.g., `1154`)
|
|
1141
|
-
- `uuid` = Test case UUID (e.g., `7a17b809-0ff9-4ba1-9322-4eb2a49abfc5`)
|
|
1142
|
-
|
|
1143
|
-
### What About Tests Without UUIDs?
|
|
1144
|
-
|
|
1145
|
-
Tests without `mapAppqUuid()` calls are called **orphan tests**. The SDK will:
|
|
1146
|
-
- ✅ Still run them normally
|
|
1147
|
-
- ✅ Collect results
|
|
1148
|
-
- ✅ Log them separately (if `logOrphans: true`)
|
|
1149
|
-
- ❌ Won't report to portal (no UUID to map to)
|
|
1150
|
-
|
|
1151
|
-
**Check orphan logs to see which tests need UUID mapping.**
|
|
1152
|
-
|
|
1153
|
-
---
|
|
1154
|
-
|
|
1155
|
-
## Troubleshooting
|
|
1156
|
-
|
|
1157
|
-
### Common Issues and Solutions
|
|
1158
|
-
|
|
1159
|
-
#### ❌ Error: "APPLIQATION_API_KEY is required"
|
|
1160
|
-
|
|
1161
|
-
**Cause:** `.env` file not loaded or missing variable
|
|
1162
|
-
|
|
1163
|
-
**Fix:**
|
|
1164
|
-
1. Verify `.env` file exists in project root
|
|
1165
|
-
2. Check variable name spelling (no typos!)
|
|
1166
|
-
3. Ensure `require('dotenv').config()` at top of `playwright.config.js`
|
|
1167
|
-
4. No spaces around `=` sign:
|
|
1168
|
-
```bash
|
|
1169
|
-
# ❌ Wrong
|
|
1170
|
-
APPLIQATION_API_KEY = appq_live_xxx
|
|
1171
|
-
|
|
1172
|
-
# ✅ Correct
|
|
1173
|
-
APPLIQATION_API_KEY=appq_live_xxx
|
|
1174
|
-
```
|
|
1175
|
-
|
|
1176
|
-
---
|
|
1177
|
-
|
|
1178
|
-
#### ❌ Tests redirecting to login page (authentication failed)
|
|
1179
|
-
|
|
1180
|
-
**Cause:** JWT authentication not working, storage state not loading
|
|
1181
|
-
|
|
1182
|
-
**Fix:**
|
|
1183
|
-
1. Verify `globalSetup` configured correctly:
|
|
1184
|
-
```javascript
|
|
1185
|
-
globalSetup: require.resolve('@appliqation/automation-sdk/playwright/global-setup')
|
|
1186
|
-
```
|
|
1187
|
-
|
|
1188
|
-
2. Check `.auth/jwt.json` file exists after global-setup runs
|
|
1189
|
-
|
|
1190
|
-
3. Verify all projects use storage state:
|
|
1191
|
-
```javascript
|
|
1192
|
-
projects: [{
|
|
1193
|
-
name: 'chromium',
|
|
1194
|
-
use: { storageState: '.auth/jwt.json' } // Must be set!
|
|
1195
|
-
}]
|
|
1196
|
-
```
|
|
1197
|
-
|
|
1198
|
-
4. Check `.env` has correct `TEST_APP_URL` (no trailing slash):
|
|
1199
|
-
```bash
|
|
1200
|
-
# ❌ Wrong
|
|
1201
|
-
TEST_APP_URL=https://portal.com/
|
|
1202
|
-
|
|
1203
|
-
# ✅ Correct
|
|
1204
|
-
TEST_APP_URL=https://portal.com
|
|
1205
|
-
```
|
|
1206
|
-
|
|
1207
|
-
---
|
|
1208
|
-
|
|
1209
|
-
#### ❌ Error: "testInfo is not defined"
|
|
1210
|
-
|
|
1211
|
-
**Cause:** Missing `testInfo` parameter in test function
|
|
1212
|
-
|
|
1213
|
-
**Fix:**
|
|
1214
|
-
```javascript
|
|
1215
|
-
// ❌ Wrong - missing testInfo
|
|
1216
|
-
test('my test', async ({ page }) => {
|
|
1217
|
-
mapAppqUuid(testInfo, 'uuid-here'); // testInfo undefined!
|
|
1218
|
-
});
|
|
1219
|
-
|
|
1220
|
-
// ✅ Correct - include testInfo
|
|
1221
|
-
test('my test', async ({ page }, testInfo) => {
|
|
1222
|
-
mapAppqUuid(testInfo, 'uuid-here');
|
|
1223
|
-
});
|
|
1224
|
-
```
|
|
1225
|
-
|
|
1226
|
-
---
|
|
1227
|
-
|
|
1228
|
-
#### ❌ Error: "Invalid UUID format"
|
|
1229
|
-
|
|
1230
|
-
**Cause:** UUID not in `nid-uuid` format
|
|
1231
|
-
|
|
1232
|
-
**Fix:**
|
|
1233
|
-
```javascript
|
|
1234
|
-
// ❌ Wrong formats
|
|
1235
|
-
mapAppqUuid(testInfo, '7a17b809-0ff9-4ba1-9322-4eb2a49abfc5'); // Missing nid
|
|
1236
|
-
mapAppqUuid(testInfo, '1154'); // Missing UUID
|
|
1237
|
-
mapAppqUuid(testInfo, 'test-case-123'); // Wrong format
|
|
1238
|
-
|
|
1239
|
-
// ✅ Correct format
|
|
1240
|
-
mapAppqUuid(testInfo, '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5');
|
|
1241
|
-
```
|
|
1242
|
-
|
|
1243
|
-
---
|
|
1244
|
-
|
|
1245
|
-
#### ❌ Error: "Module 'dotenv' not found"
|
|
1246
|
-
|
|
1247
|
-
**Cause:** `dotenv` package not installed
|
|
1248
|
-
|
|
1249
|
-
**Fix:**
|
|
1250
|
-
```bash
|
|
1251
|
-
npm install dotenv
|
|
1252
|
-
```
|
|
1253
|
-
|
|
1254
|
-
---
|
|
1255
|
-
|
|
1256
|
-
#### ❌ Error: "unable to verify the first certificate" or SSL errors
|
|
1257
|
-
|
|
1258
|
-
**Cause:** Using self-signed SSL certificates in development environment
|
|
1259
|
-
|
|
1260
|
-
**Fix:**
|
|
1261
|
-
|
|
1262
|
-
Add `rejectUnauthorized: false` to your SDK configuration in `playwright.config.js`:
|
|
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`)
|
|
1263
338
|
|
|
1264
339
|
```javascript
|
|
1265
|
-
|
|
340
|
+
['@appliqation/automation-sdk/playwright/reporter', {
|
|
1266
341
|
apiKey: process.env.APPLIQATION_API_KEY,
|
|
1267
342
|
projectKey: process.env.APPLIQATION_PROJECT_KEY,
|
|
343
|
+
environment: process.env.APPLIQATION_ENVIRONMENT,
|
|
1268
344
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
};
|
|
1272
|
-
```
|
|
1273
|
-
|
|
1274
|
-
**⚠️ 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`.
|
|
1275
|
-
|
|
1276
|
-
---
|
|
1277
|
-
|
|
1278
|
-
#### ❌ Results not appearing in portal
|
|
1279
|
-
|
|
1280
|
-
**Possible causes:**
|
|
1281
|
-
|
|
1282
|
-
1. **Reporting not enabled** - Missing `APPQ_ENABLE` env var or `--appq` flag (MOST COMMON!)
|
|
1283
|
-
- **Fix (Method 1 - Recommended):** Set `APPQ_ENABLE=1` environment variable
|
|
1284
|
-
- Example: `APPQ_ENABLE=1 npx playwright test`
|
|
1285
|
-
- **Fix (Method 2):** Add `-- --appq` flag to your test command
|
|
1286
|
-
- Example: `npx playwright test -- --appq`
|
|
1287
|
-
- Check console output for: "Appliqation reporting disabled"
|
|
1288
|
-
|
|
1289
|
-
2. **Orphan tests** - Tests don't have `mapAppqUuid()` calls
|
|
1290
|
-
- **Fix:** Add UUID mapping to all tests
|
|
1291
|
-
- 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,
|
|
1292
347
|
|
|
1293
|
-
|
|
1294
|
-
|
|
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',
|
|
1295
353
|
|
|
1296
|
-
|
|
1297
|
-
|
|
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
|
|
1298
356
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
### Debug Mode
|
|
1302
|
-
|
|
1303
|
-
Enable detailed logging to troubleshoot issues:
|
|
1304
|
-
|
|
1305
|
-
**In .env:**
|
|
1306
|
-
```bash
|
|
1307
|
-
LOG_LEVEL=DEBUG
|
|
357
|
+
rejectUnauthorized: true, // set false only for local self-signed certs
|
|
358
|
+
}]
|
|
1308
359
|
```
|
|
1309
360
|
|
|
1310
|
-
|
|
1311
|
-
```javascript
|
|
1312
|
-
const appliqationConfig = {
|
|
1313
|
-
// ... other config
|
|
1314
|
-
logLevel: 'DEBUG'
|
|
1315
|
-
};
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
**Debug output shows:**
|
|
1319
|
-
- ✅ API requests and responses
|
|
1320
|
-
- ✅ Authentication flow details
|
|
1321
|
-
- ✅ Result submission batches
|
|
1322
|
-
- ✅ Orphan test detection
|
|
1323
|
-
- ✅ Error stack traces
|
|
361
|
+
## Orphan test handling
|
|
1324
362
|
|
|
1325
|
-
|
|
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.
|
|
1326
366
|
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
require('dotenv').config();
|
|
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.
|
|
1335
374
|
|
|
1336
|
-
|
|
1337
|
-
const client = new AppliqationClient({
|
|
1338
|
-
apiKey: process.env.APPLIQATION_API_KEY,
|
|
1339
|
-
projectKey: process.env.APPLIQATION_PROJECT_KEY
|
|
1340
|
-
});
|
|
375
|
+
## Auto-tagging test cases
|
|
1341
376
|
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
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`.
|
|
1345
385
|
|
|
1346
|
-
|
|
1347
|
-
```
|
|
386
|
+
## Advanced
|
|
1348
387
|
|
|
1349
|
-
|
|
1350
|
-
```bash
|
|
1351
|
-
node test-connection.js
|
|
1352
|
-
```
|
|
388
|
+
### Auto-refreshing JWT fixture
|
|
1353
389
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
```
|
|
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:
|
|
1358
393
|
|
|
1359
|
-
---
|
|
1360
|
-
|
|
1361
|
-
## Advanced Features
|
|
1362
|
-
|
|
1363
|
-
### Custom Playwright Fixture (Auto JWT Refresh)
|
|
1364
|
-
|
|
1365
|
-
For long-running test suites, use the SDK's custom fixture to automatically refresh JWT tokens:
|
|
1366
|
-
|
|
1367
|
-
**File:** `tests/example.spec.js`
|
|
1368
394
|
```javascript
|
|
1369
|
-
// Use the SDK's test fixture instead of Playwright's default
|
|
1370
395
|
const { test, expect } = require('@appliqation/automation-sdk/playwright');
|
|
1371
396
|
|
|
1372
|
-
test
|
|
1373
|
-
|
|
1374
|
-
// JWT is automatically refreshed if < 5 minutes remaining
|
|
1375
|
-
await page.goto('/dashboard');
|
|
1376
|
-
// Your test logic...
|
|
1377
|
-
});
|
|
397
|
+
test('long-running suite stays authenticated', async ({ page }) => {
|
|
398
|
+
await page.goto('/dashboard');
|
|
1378
399
|
});
|
|
1379
400
|
```
|
|
1380
401
|
|
|
1381
|
-
|
|
1382
|
-
- ✅ Checks JWT expiry before each test
|
|
1383
|
-
- ✅ Automatically refreshes if < 5 minutes remaining
|
|
1384
|
-
- ✅ Updates `.auth/jwt.json` with new token
|
|
1385
|
-
- ✅ Prevents authentication failures in long test runs
|
|
1386
|
-
|
|
1387
|
-
### Using Core SDK Directly
|
|
402
|
+
### Using the client directly
|
|
1388
403
|
|
|
1389
|
-
For custom integrations
|
|
404
|
+
For custom integrations outside Playwright's reporter lifecycle:
|
|
1390
405
|
|
|
1391
406
|
```javascript
|
|
1392
407
|
const AppliqationClient = require('@appliqation/automation-sdk');
|
|
1393
408
|
|
|
1394
|
-
// Initialize client
|
|
1395
409
|
const client = new AppliqationClient({
|
|
1396
410
|
apiKey: process.env.APPLIQATION_API_KEY,
|
|
1397
|
-
projectKey: process.env.APPLIQATION_PROJECT_KEY
|
|
411
|
+
projectKey: process.env.APPLIQATION_PROJECT_KEY,
|
|
1398
412
|
});
|
|
1399
413
|
|
|
1400
|
-
// Create run
|
|
1401
414
|
const run = await client.createRun({
|
|
1402
|
-
environment: '
|
|
415
|
+
environment: 'Staging',
|
|
1403
416
|
browsers: ['Chrome'],
|
|
1404
417
|
device: 'Desktop',
|
|
1405
|
-
os: 'Windows 11'
|
|
418
|
+
os: 'Windows 11',
|
|
1406
419
|
});
|
|
1407
420
|
|
|
1408
|
-
console.log('Run created:', run.runId);
|
|
1409
|
-
|
|
1410
|
-
// Submit single result
|
|
1411
421
|
await client.submitResult(run.runId, {
|
|
1412
422
|
uuid: '1154-7a17b809-0ff9-4ba1-9322-4eb2a49abfc5',
|
|
1413
423
|
status: 'passed',
|
|
1414
424
|
browser: 'Chrome',
|
|
1415
|
-
comment: 'Test passed successfully'
|
|
1416
425
|
});
|
|
1417
426
|
|
|
1418
|
-
|
|
1419
|
-
const results = [
|
|
427
|
+
const summary = await client.submitBatch([
|
|
1420
428
|
{ uuid: '1154-uuid-1', runId: run.runId, status: 'passed', browser: 'Chrome' },
|
|
1421
|
-
{ uuid: '1154-uuid-2', runId: run.runId, status: 'failed', browser: 'Chrome' }
|
|
1422
|
-
];
|
|
1423
|
-
|
|
1424
|
-
const summary = await client.submitBatch(results);
|
|
1425
|
-
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`);
|
|
1426
432
|
```
|
|
1427
433
|
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
Set custom titles for test runs:
|
|
434
|
+
## How it works
|
|
1431
435
|
|
|
1432
|
-
**
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
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.
|
|
1437
446
|
|
|
1438
|
-
|
|
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.
|
|
1439
451
|
|
|
1440
|
-
|
|
452
|
+
## Troubleshooting
|
|
1441
453
|
|
|
1442
|
-
|
|
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:
|
|
1443
460
|
|
|
1444
|
-
**Reporter (for playwright.config.js):**
|
|
1445
461
|
```javascript
|
|
1446
|
-
|
|
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);
|
|
1447
467
|
```
|
|
1448
468
|
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
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).
|
|
1454
474
|
|
|
1455
|
-
**
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
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.
|
|
1459
481
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
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
|
|
1464
487
|
|
|
1465
|
-
|
|
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.
|
|
1466
493
|
|
|
1467
|
-
|
|
494
|
+
## Further reading
|
|
1468
495
|
|
|
1469
|
-
|
|
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
|
|
1470
498
|
|
|
1471
499
|
## Support
|
|
1472
500
|
|
|
1473
|
-
-
|
|
1474
|
-
- 📖 **Documentation**: https://docs.appliqation.com
|
|
1475
|
-
- 🐛 **Issues**: https://github.com/appliqation/automation-sdk-js/issues
|
|
501
|
+
- Issues: https://github.com/appliqation/automation-sdk-js/issues
|
|
1476
502
|
|
|
1477
503
|
## License
|
|
1478
504
|
|
|
1479
|
-
MIT
|
|
505
|
+
MIT — see [LICENSE](./LICENSE).
|