@camunda/e2e-test-suite 0.0.1129 → 0.0.1131
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 +10 -10
- package/dist/tests/8.10/test-setup.spec.js +78 -17
- package/dist/tests/8.10/web-modeler-user-flows.spec.js +2 -2
- package/dist/tests/8.7/web-modeler-user-flows.spec.js +2 -2
- package/dist/tests/8.8/web-modeler-user-flows.spec.js +2 -2
- package/dist/tests/8.9/web-modeler-user-flows.spec.js +2 -2
- package/dist/utils/users.js +9 -1
- package/package.json +1 -1
- package/playwright.config.ts +10 -3
package/README.md
CHANGED
|
@@ -419,22 +419,22 @@ See [docs/ci-failure-categories.md](docs/ci-failure-categories.md) for the full
|
|
|
419
419
|
|
|
420
420
|
When a PR opens in [camunda/camunda](https://github.com/camunda/camunda) or [camunda/connectors](https://github.com/camunda/connectors), AlwaysGreen dispatches a subset of this suite against that PR's build. This is separate from this repo's own [Automatic test runs on PR](#automatic-test-runs-on-pr) above, which cover changes to the test suite itself rather than to the product.
|
|
421
421
|
|
|
422
|
-
| leg | scope |
|
|
423
|
-
| --- | --- |
|
|
424
|
-
| SaaS smoke | `test-setup`, `navigation`, `smoke-tests` |
|
|
425
|
-
| SaaS full | remaining specs (minus exclusions below) |
|
|
426
|
-
| SM smoke | smoke suite |
|
|
427
|
-
| SM full | full suite |
|
|
422
|
+
| leg | scope |
|
|
423
|
+
| --- | --- |
|
|
424
|
+
| SaaS smoke | `test-setup`, `navigation`, `smoke-tests` |
|
|
425
|
+
| SaaS full | remaining specs (minus exclusions below) |
|
|
426
|
+
| SM smoke | smoke suite |
|
|
427
|
+
| SM full | full suite |
|
|
428
428
|
|
|
429
|
-
|
|
429
|
+
Whether a given leg gates a merge is decided by the caller repo's own branch protection / merge-queue configuration, not by this suite — that can change independently of anything documented here, so it's deliberately not claimed above. Runtime is likewise omitted: it shifts as specs are added, excluded, or reworked, and a stale number here is worse than none.
|
|
430
|
+
|
|
431
|
+
**Excluded from PR level entirely — nightly only.** Third-party model-endpoint specs bill an external provider on every run they're included in, so they stay out of the PR-level full-suite pass:
|
|
430
432
|
|
|
431
433
|
- By spec file: `agentic-ai-user-flows.spec.ts`, `idp-user-flows.spec.ts`, `aws-connectors-user-flows.spec.ts` (AWS Bedrock, AgentCore, Vertex, Azure OpenAI)
|
|
432
|
-
- By tag `@ai-external`:
|
|
434
|
+
- By tag `@ai-external`: both `Form.js Integration with AI generated Start form` and `Form.js Integration with User Task and AI Generated Form` inside `web-modeler-user-flows.spec.ts` -- both call `formJsPage.generateAIForm()` (a paid model call), so both are excluded.
|
|
433
435
|
|
|
434
436
|
**Kept in at PR level despite touching external systems:** Connector Secrets tests (reads from our own AWS/GCP secret managers — no model endpoint, no meaningful per-run cost) and MCP tests (run against our own cluster — no cost).
|
|
435
437
|
|
|
436
|
-
See [AlwaysGreen Iteration 2 - Alpha 5: Coverage & Optimisation](https://github.com/camunda/team-test-automation/issues/78) for the full rationale and current SaaS/SM stability data behind these boundaries.
|
|
437
|
-
|
|
438
438
|
## Test Suite Structure
|
|
439
439
|
|
|
440
440
|
The test suite is organized using the Page Object Model design pattern, where each test file contains test scenarios related to a specific component or feature of the Camunda C8 product stack. Additionally, it leverages separate page objects for each web page or component being tested.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const test_1 = require("@playwright/test");
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
4
8
|
const _8_10_1 = require("../../fixtures/8.10");
|
|
5
9
|
const _setup_1 = require("../../test-setup.js");
|
|
6
10
|
const connectorSecrets_1 = require("../../utils/connectorSecrets");
|
|
@@ -38,26 +42,49 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
38
42
|
}
|
|
39
43
|
await clusterPage.clickClusterLink(clusterName);
|
|
40
44
|
await clusterDetailsPage.assertComponentsHealth();
|
|
41
|
-
|
|
45
|
+
// API-client creation is needed whenever this run will also exercise the
|
|
46
|
+
// full-suite pass: many of those specs call the Zeebe REST API directly
|
|
47
|
+
// and need CAMUNDA_OPTIMIZE_BASE_URL for Optimize session login, even
|
|
48
|
+
// though IS_AG=true skips this for the usual smoke-only case.
|
|
49
|
+
if (process.env.IS_AG !== 'true' || process.env.RUN_FULL_SUITE === 'true') {
|
|
42
50
|
await clusterDetailsPage.clickAPITab();
|
|
43
|
-
await clusterDetailsPage.createAPIClientAndReturnVariables(apiClientName);
|
|
51
|
+
const zeebeCredentials = await clusterDetailsPage.createAPIClientAndReturnVariables(apiClientName);
|
|
44
52
|
await clusterDetailsPage.clickCloseModalButton();
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
if (process.env.RUN_FULL_SUITE === 'true') {
|
|
54
|
+
// Written to disk, not just process.env: the full-suite pass runs as
|
|
55
|
+
// a separate `npm run test` process (see run-tests-smoke-int's
|
|
56
|
+
// action.yml) that does not inherit this process's env mutations.
|
|
57
|
+
// mode 0o600: this file holds a live Zeebe API client secret.
|
|
58
|
+
fs_1.default.writeFileSync('cluster-credentials.json', JSON.stringify(zeebeCredentials), { mode: 0o600 });
|
|
59
|
+
}
|
|
60
|
+
// Deliberately NOT extended to RUN_FULL_SUITE like the API client
|
|
61
|
+
// above: clickConnectorSecretsTab hits the same pre-existing "click
|
|
62
|
+
// after 3 attempts" UI-contention flakiness seen throughout this
|
|
63
|
+
// suite, and here it's on test-setup's blocking critical path -- a
|
|
64
|
+
// transient failure takes down cluster provisioning entirely (and
|
|
65
|
+
// with it, both smoke and the full-suite pass), confirmed on a real
|
|
66
|
+
// run. connectors-user-flows.spec.ts's "Connector Secrets User Flow"
|
|
67
|
+
// tests keep failing in the full-suite pass without this, but that's
|
|
68
|
+
// a bounded, non-blocking loss -- not worth risking the whole run for.
|
|
69
|
+
if (process.env.IS_AG !== 'true') {
|
|
70
|
+
await clusterPage.clickConnectorSecretsTab(clusterName);
|
|
71
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.awsSecretsValues);
|
|
72
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.openAiSecretsValues);
|
|
73
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.gcpSecretsValues);
|
|
74
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.azureSecretsValues);
|
|
75
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.connectorSecretsValues);
|
|
76
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.bedrockKbSecretsValues);
|
|
77
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.agentcoreSecretsValues);
|
|
78
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.agentcoreLtmSecretsValues);
|
|
79
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.bedrockCodeInterpreterSecretsValues);
|
|
80
|
+
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.anthropicBedrockMantleSecretsValues);
|
|
81
|
+
}
|
|
56
82
|
}
|
|
57
83
|
});
|
|
58
84
|
(0, _8_10_1.test)('Create Agentic Orchestration Cluster', async ({ page, loginPage, homePage, clusterPage, clusterDetailsPage, clusterSecretsPage, }, testInfo) => {
|
|
59
85
|
_8_10_1.test.skip(process.env.IS_PROD === 'true', 'Skipping test because not required on PROD test org');
|
|
60
|
-
_8_10_1.test.skip(process.env.IS_AG === 'true', 'Skipping test because not required when IS_AG is true'
|
|
86
|
+
_8_10_1.test.skip(process.env.IS_AG === 'true' && process.env.RUN_FULL_SUITE !== 'true', 'Skipping test because not required when IS_AG is true -- unless ' +
|
|
87
|
+
'RUN_FULL_SUITE also needs this cluster for the MCP suite.');
|
|
61
88
|
_8_10_1.test.slow();
|
|
62
89
|
const clusterName = 'Agentic Orchestration Cluster';
|
|
63
90
|
const apiClientName = 'Test_API_Client' + (await (0, _setup_1.generateRandomStringAsync)(3));
|
|
@@ -82,7 +109,14 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
82
109
|
await clusterPage.assertClusterHealthyStatusWithRetry(clusterName);
|
|
83
110
|
await clusterPage.clickClusterLink(clusterName);
|
|
84
111
|
await clusterDetailsPage.clickAPITab();
|
|
85
|
-
await clusterDetailsPage.createAPIClientAndReturnVariables(apiClientName, true, 'agentic_cluster');
|
|
112
|
+
const agenticCredentials = await clusterDetailsPage.createAPIClientAndReturnVariables(apiClientName, true, 'agentic_cluster');
|
|
113
|
+
if (process.env.RUN_FULL_SUITE === 'true') {
|
|
114
|
+
// Written to disk, not just process.env: the full-suite pass runs as
|
|
115
|
+
// a separate `npm run test` process (see run-tests-smoke-int's
|
|
116
|
+
// action.yml) that does not inherit this process's env mutations.
|
|
117
|
+
// mode 0o600: this file holds a live Zeebe API client secret.
|
|
118
|
+
fs_1.default.writeFileSync('agentic-cluster-credentials.json', JSON.stringify(agenticCredentials), { mode: 0o600 });
|
|
119
|
+
}
|
|
86
120
|
await clusterDetailsPage.clickCloseModalButton();
|
|
87
121
|
const mcpCredentials = await clusterDetailsPage.createMCPClientAndReturnVariables(mcpClientName);
|
|
88
122
|
await clusterDetailsPage.clickCloseModalButton();
|
|
@@ -109,10 +143,22 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
109
143
|
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.connectorSecretsValues);
|
|
110
144
|
}
|
|
111
145
|
});
|
|
146
|
+
// Stagger 5x wider than the other setup tests above, capped at 60s: this
|
|
147
|
+
// loop logs in getTestUsers().length users (up to 27, one per worker) at
|
|
148
|
+
// once, so at 1000ms/worker the whole burst lands inside a ~20-30s window
|
|
149
|
+
// and trips Auth0's rate limiter (AUTH0_RATE_LIMIT, e.g. run 34099726060's
|
|
150
|
+
// User 18 failure) well before loginWithRetry's own 60-90s backoff gets a
|
|
151
|
+
// chance to help. An uncapped 5000ms/worker fixed the rate limit (run
|
|
152
|
+
// 34103380836 had none) but then burned up to 90s of the highest-indexed
|
|
153
|
+
// worker's fixed 12-minute test timeout on pure stagger sleep before its
|
|
154
|
+
// first login attempt, leaving too little budget for the retry loop to
|
|
155
|
+
// recover from an unrelated slow-page timeout (also run 34103380836,
|
|
156
|
+
// User 18 again). The 60s cap keeps most of the wider spread while
|
|
157
|
+
// bounding worst-case pre-login wait to 1/12 of the test budget.
|
|
112
158
|
for (const [index, user] of (0, users_1.getTestUsers)().entries()) {
|
|
113
159
|
(0, _8_10_1.test)(`Create Project Folder for User ${index + 1}`, async ({ page, loginPage, homePage, appsPage, modelerHomePage, }, testInfo) => {
|
|
114
160
|
await _8_10_1.test.step('Log in', async () => {
|
|
115
|
-
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, user, (testInfo.workerIndex + 1) *
|
|
161
|
+
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, user, Math.min((testInfo.workerIndex + 1) * 5000, 60000));
|
|
116
162
|
});
|
|
117
163
|
await _8_10_1.test.step('Navigate to Web Modeler', async () => {
|
|
118
164
|
await (0, test_1.expect)(homePage.camundaComponentsButton).toBeVisible({
|
|
@@ -121,8 +167,23 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
121
167
|
await appsPage.openModelerWithRetry(modelerHomePage.modelerPageBanner, 180000);
|
|
122
168
|
});
|
|
123
169
|
await _8_10_1.test.step('Create Cross Component Project Folder', async () => {
|
|
124
|
-
await (0, UtilitiesPage_1.withSessionRecovery)(page, loginPage, appsPage, modelerHomePage.modelerPageBanner, user, (testInfo.workerIndex + 1) *
|
|
170
|
+
await (0, UtilitiesPage_1.withSessionRecovery)(page, loginPage, appsPage, modelerHomePage.modelerPageBanner, user, Math.min((testInfo.workerIndex + 1) * 5000, 60000), async () => {
|
|
125
171
|
await homePage.clickSkipCustomization();
|
|
172
|
+
// Reverted the "only User 1 creates" leader-election attempt: it made
|
|
173
|
+
// things worse, not better. Run 34191243820 showed followers still
|
|
174
|
+
// timing out waiting for the folder even well after User 1 (2.9min)
|
|
175
|
+
// had already finished creating it -- not a wait-budget problem, since
|
|
176
|
+
// widening it wouldn't fix a folder that isn't becoming visible to
|
|
177
|
+
// other sessions at all. Nightly (run-tests-saas) and on-demand never
|
|
178
|
+
// hit this because both run test-setup.spec.ts as part of one
|
|
179
|
+
// unfiltered `--project=X` invocation together with hundreds of other
|
|
180
|
+
// tests, rather than isolating it into its own "Provision cluster"
|
|
181
|
+
// step the way this PR's action.yml does -- that isolation is what
|
|
182
|
+
// creates the every-worker-races-at-once window in the first place.
|
|
183
|
+
// Back to every user independently checking-and-creating: still races
|
|
184
|
+
// sometimes (3-7 of 18 users per run, per the create-organization
|
|
185
|
+
// rate-limit findings above), but that's a smaller, known failure mode
|
|
186
|
+
// than the 100% follower failure the leader-election attempt caused.
|
|
126
187
|
await modelerHomePage.createCrossComponentProjectFolder();
|
|
127
188
|
await modelerHomePage.clickHomeBreadcrumb();
|
|
128
189
|
await (0, test_1.expect)(modelerHomePage.crossComponentProjectFolder).toBeVisible({ timeout: 60000 });
|
|
@@ -34,7 +34,7 @@ _8_10_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
34
34
|
await (0, mailSlurpClient_1.deleteInbox)(inboxes[testInfo.title]);
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
-
(0, _8_10_1.test)('Form.js Integration with User Task and AI Generated Form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
37
|
+
(0, _8_10_1.test)('Form.js Integration with User Task and AI Generated Form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
38
38
|
_8_10_1.test.slow();
|
|
39
39
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
40
40
|
const processName = 'User_Task_Process_With_AI_Form' + randomString;
|
|
@@ -92,7 +92,7 @@ _8_10_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
92
92
|
await operateTabTaskDetailsPage.clickCompleteTaskButton();
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
-
(0, _8_10_1.test)('Form.js Integration with AI generated Start form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
95
|
+
(0, _8_10_1.test)('Form.js Integration with AI generated Start form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
96
96
|
_8_10_1.test.slow();
|
|
97
97
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
98
98
|
const processName = 'AI-generated-Start-form' + randomString;
|
|
@@ -33,7 +33,7 @@ _8_7_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
33
33
|
await (0, mailSlurpClient_1.deleteInbox)(inboxes[testInfo.title]);
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
(0, _8_7_1.test)('Form.js Integration with User Task and AI Generated Form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
36
|
+
(0, _8_7_1.test)('Form.js Integration with User Task and AI Generated Form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
37
37
|
_8_7_1.test.slow();
|
|
38
38
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
39
39
|
const processName = 'User_Task_Process_With_AI_Form' + randomString;
|
|
@@ -280,7 +280,7 @@ _8_7_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
280
280
|
});
|
|
281
281
|
});
|
|
282
282
|
});
|
|
283
|
-
(0, _8_7_1.test)('Form.js Integration with AI generated Start form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
283
|
+
(0, _8_7_1.test)('Form.js Integration with AI generated Start form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
284
284
|
_8_7_1.test.slow();
|
|
285
285
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
286
286
|
const processName = 'AI-generated-Start-form' + randomString;
|
|
@@ -31,7 +31,7 @@ _8_8_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
31
31
|
await (0, mailSlurpClient_1.deleteInbox)(inboxes[testInfo.title]);
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
|
-
(0, _8_8_1.test)('Form.js Integration with User Task and AI Generated Form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
34
|
+
(0, _8_8_1.test)('Form.js Integration with User Task and AI Generated Form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
35
35
|
_8_8_1.test.slow();
|
|
36
36
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
37
37
|
const processName = 'User_Task_Process_With_AI_Form' + randomString;
|
|
@@ -88,7 +88,7 @@ _8_8_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
88
88
|
await operateTabTaskDetailsPage.clickCompleteTaskButton();
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
|
-
(0, _8_8_1.test)('Form.js Integration with AI generated Start form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
91
|
+
(0, _8_8_1.test)('Form.js Integration with AI generated Start form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
92
92
|
_8_8_1.test.slow();
|
|
93
93
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
94
94
|
const processName = 'AI-generated-Start-form' + randomString;
|
|
@@ -34,7 +34,7 @@ _8_9_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
34
34
|
await (0, mailSlurpClient_1.deleteInbox)(inboxes[testInfo.title]);
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
-
(0, _8_9_1.test)('Form.js Integration with User Task and AI Generated Form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
37
|
+
(0, _8_9_1.test)('Form.js Integration with User Task and AI Generated Form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
38
38
|
_8_9_1.test.slow();
|
|
39
39
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
40
40
|
const processName = 'User_Task_Process_With_AI_Form' + randomString;
|
|
@@ -92,7 +92,7 @@ _8_9_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
92
92
|
await operateTabTaskDetailsPage.clickCompleteTaskButton();
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
-
(0, _8_9_1.test)('Form.js Integration with AI generated Start form', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
95
|
+
(0, _8_9_1.test)('Form.js Integration with AI generated Start form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
96
96
|
_8_9_1.test.slow();
|
|
97
97
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
98
98
|
const processName = 'AI-generated-Start-form' + randomString;
|
package/dist/utils/users.js
CHANGED
|
@@ -98,7 +98,15 @@ function getTestUser(userKey) {
|
|
|
98
98
|
}
|
|
99
99
|
exports.getTestUser = getTestUser;
|
|
100
100
|
function getTestUsers() {
|
|
101
|
-
|
|
101
|
+
// test-setup.spec.ts loops over this list to provision one Cross Component
|
|
102
|
+
// Project folder per user. Full-suite specs each log in as a different
|
|
103
|
+
// named user (getTestUser('eleventhUser') etc.) via getTestUser, not one
|
|
104
|
+
// of the 3 smokeTestUsers -- so under IS_AG=true, RUN_FULL_SUITE=true still
|
|
105
|
+
// needs the full list, or every one of those users hits a folder that was
|
|
106
|
+
// never created for them.
|
|
107
|
+
if (process.env.IS_AG === 'true' &&
|
|
108
|
+
process.env.MULTI_USERS === 'true' &&
|
|
109
|
+
process.env.RUN_FULL_SUITE !== 'true') {
|
|
102
110
|
return Object.values(exports.smokeTestUsers);
|
|
103
111
|
}
|
|
104
112
|
else if (process.env.MULTI_USERS === 'true') {
|
package/package.json
CHANGED
package/playwright.config.ts
CHANGED
|
@@ -10,17 +10,23 @@ if (!process.env.CAMUNDA_OPTIMIZE_BASE_URL && process.env.BASE_URL) {
|
|
|
10
10
|
|
|
11
11
|
const projectName = process.env.PROJECT! || 'Chromium'; // Default to 'default-project' if PROJECT is not set
|
|
12
12
|
|
|
13
|
+
// Set only by the concurrent full-suite pass in run-tests-smoke-int's action.yml,
|
|
14
|
+
// so it doesn't clobber the smoke pass's report files when both `npm run test`
|
|
15
|
+
// invocations run at the same time against the same working directory.
|
|
16
|
+
// Empty by default -- every other caller is unaffected.
|
|
17
|
+
const reportSuffix = process.env.REPORT_SUFFIX || '';
|
|
18
|
+
|
|
13
19
|
const junitOptions = {
|
|
14
20
|
embedAnnotationsAsProperties: true,
|
|
15
|
-
outputFile:
|
|
21
|
+
outputFile: `./test-results${reportSuffix}/junit-report.xml`,
|
|
16
22
|
};
|
|
17
23
|
|
|
18
24
|
// Define reporters without SlackReporter
|
|
19
25
|
const useReportersWithoutSlack: any[] = [
|
|
20
26
|
['list'],
|
|
21
27
|
['junit', junitOptions],
|
|
22
|
-
['html', {outputFolder:
|
|
23
|
-
['json', {outputFile: `json-report/results.json`}],
|
|
28
|
+
['html', {outputFolder: `html-report${reportSuffix}`}],
|
|
29
|
+
['json', {outputFile: `json-report${reportSuffix}/results.json`}],
|
|
24
30
|
];
|
|
25
31
|
|
|
26
32
|
// Define reporters with SlackReporter
|
|
@@ -256,6 +262,7 @@ export default defineConfig({
|
|
|
256
262
|
workers: workerCount(),
|
|
257
263
|
retries: 1,
|
|
258
264
|
fullyParallel: false,
|
|
265
|
+
outputDir: `test-results${reportSuffix}`,
|
|
259
266
|
use: {
|
|
260
267
|
baseURL: getBaseURL(),
|
|
261
268
|
actionTimeout: 10000,
|