@camunda/e2e-test-suite 0.0.1132 → 0.0.1133
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.
|
@@ -1316,7 +1316,14 @@ class ModelerCreatePage {
|
|
|
1316
1316
|
}
|
|
1317
1317
|
async switchToPlay() {
|
|
1318
1318
|
await this.suppressTestModeAnnouncement();
|
|
1319
|
-
|
|
1319
|
+
// completePlayConfiguration re-enters Play after ensureStageCluster's
|
|
1320
|
+
// detour, which comes back through goto(..., 'domcontentloaded'). The
|
|
1321
|
+
// modeler mounts its mode tablist well after that event -- measurably
|
|
1322
|
+
// longer than the 10s default actionTimeout this click would otherwise
|
|
1323
|
+
// inherit, which failed the re-entry outright on every run of the
|
|
1324
|
+
// dispatched test. Wait for the tab to exist before clicking it.
|
|
1325
|
+
await (0, test_1.expect)(this.playTab).toBeVisible({ timeout: 90000 });
|
|
1326
|
+
await this.playTab.click({ timeout: 30000 });
|
|
1320
1327
|
}
|
|
1321
1328
|
async completePlayConfiguration(clusterName) {
|
|
1322
1329
|
// Play is a tab on the diagram page, not its own URL, so the stage-cluster
|
|
@@ -1421,15 +1428,34 @@ class ModelerCreatePage {
|
|
|
1421
1428
|
// keying on it would fall through to the legacy Continue flow.
|
|
1422
1429
|
const isNewFlow = await configurationOverlay.isVisible();
|
|
1423
1430
|
if (isNewFlow) {
|
|
1424
|
-
// Step 1: connect cluster if not yet connected (modal with cluster
|
|
1431
|
+
// Step 1: connect cluster if not yet connected (modal with cluster
|
|
1432
|
+
// dropdown). camunda-hub's ClusterStepContent renders "Connect cluster"
|
|
1433
|
+
// only while NO cluster is bound; once one is, the very same modal is
|
|
1434
|
+
// reached through "Change", and an unusable cluster shows the
|
|
1435
|
+
// "Cluster unavailable. Choose a healthy cluster." error instead. That
|
|
1436
|
+
// second state is not a slow state: DeployStepContent hardcodes
|
|
1437
|
+
// `disabled={!isClusterStepComplete}`, so an unhealthy cluster keeps the
|
|
1438
|
+
// Deploy button disabled forever -- which is exactly how the dispatched
|
|
1439
|
+
// nightly failed, burning the whole 60s toBeEnabled budget. Treat it as
|
|
1440
|
+
// "step 1 not done" and drive the same modal through "Change".
|
|
1425
1441
|
const connectClusterButton = this.page.getByRole('button', {
|
|
1426
1442
|
name: 'Connect cluster',
|
|
1427
1443
|
});
|
|
1428
|
-
const
|
|
1429
|
-
.
|
|
1444
|
+
const changeClusterButton = this.page
|
|
1445
|
+
.getByRole('button', { name: 'Change', exact: true })
|
|
1446
|
+
.first();
|
|
1447
|
+
const clusterHealthyIcon = this.page.locator('[aria-label="Cluster healthy"]');
|
|
1448
|
+
const clusterUnavailableIcon = this.page.locator('[aria-label="Cluster unavailable"]');
|
|
1449
|
+
const hasConnectButton = await connectClusterButton
|
|
1450
|
+
.isVisible()
|
|
1430
1451
|
.catch(() => false);
|
|
1452
|
+
const needsConnect = hasConnectButton ||
|
|
1453
|
+
(await clusterUnavailableIcon.isVisible().catch(() => false));
|
|
1431
1454
|
if (needsConnect) {
|
|
1432
|
-
|
|
1455
|
+
const openClusterModalButton = hasConnectButton
|
|
1456
|
+
? connectClusterButton
|
|
1457
|
+
: changeClusterButton;
|
|
1458
|
+
await openClusterModalButton.click({ timeout });
|
|
1433
1459
|
const configureEnvDialog = this.page
|
|
1434
1460
|
.getByRole('dialog')
|
|
1435
1461
|
.filter({ hasText: 'Configure environment' });
|
|
@@ -1458,6 +1484,15 @@ class ModelerCreatePage {
|
|
|
1458
1484
|
.getByRole('button', { name: 'Save' })
|
|
1459
1485
|
.click({ timeout });
|
|
1460
1486
|
}
|
|
1487
|
+
// Gate the deploy step on the cluster step actually having completed.
|
|
1488
|
+
// ClusterStepIcon renders this label only for
|
|
1489
|
+
// `!isVerifyingClusterAvailability && hasCluster && isClusterHealthy` --
|
|
1490
|
+
// the exact condition DeployStepContent gates its Deploy button on --
|
|
1491
|
+
// and it lives in the accordion *heading*, so it stays readable while
|
|
1492
|
+
// the item collapses. Without this the flow raced ahead into step 2 and
|
|
1493
|
+
// reported "Deploy button never enabled", which says nothing about the
|
|
1494
|
+
// cluster being the thing that was wrong.
|
|
1495
|
+
await (0, test_1.expect)(clusterHealthyIcon).toBeVisible({ timeout: 90000 });
|
|
1461
1496
|
// Step 2: deploy, unless the overlay already opened with the
|
|
1462
1497
|
// deploy step complete. checkExistingDeployment only runs when
|
|
1463
1498
|
// processApplicationId is defined, which it now is, so re-entering
|
|
@@ -1493,12 +1528,23 @@ class ModelerCreatePage {
|
|
|
1493
1528
|
// which expands itself once the cluster step completes. Nudge the
|
|
1494
1529
|
// heading if it is still collapsed, otherwise the button is present
|
|
1495
1530
|
// but hidden and the click below would time out.
|
|
1531
|
+
//
|
|
1532
|
+
// This probe HAS to wait. `locator.isVisible({timeout})` never does --
|
|
1533
|
+
// it answers for the DOM as it is right now and ignores the timeout --
|
|
1534
|
+
// so it reported "not shown" in the gap before the item auto-expanded,
|
|
1535
|
+
// and the nudge below then hit an item that was already open. That
|
|
1536
|
+
// click is not idempotent: TestConfigurationPanel's
|
|
1537
|
+
// handleDeployHeadingClick sets manualSetupStep to 'none' when the
|
|
1538
|
+
// item was open, collapsing BOTH setup steps, and the retry loop that
|
|
1539
|
+
// follows only ever clicked a *visible* button -- so the deploy was
|
|
1540
|
+
// never triggered and the loop timed out with the step collapsed.
|
|
1496
1541
|
const deployButtonShown = await setupDeployButton
|
|
1497
|
-
.
|
|
1542
|
+
.waitFor({ state: 'visible', timeout: 30000 })
|
|
1543
|
+
.then(() => true)
|
|
1498
1544
|
.catch(() => false);
|
|
1499
1545
|
if (!deployButtonShown) {
|
|
1500
1546
|
const canExpandDeployStep = await deployStepHeading
|
|
1501
|
-
.isEnabled(
|
|
1547
|
+
.isEnabled()
|
|
1502
1548
|
.catch(() => false);
|
|
1503
1549
|
if (canExpandDeployStep) {
|
|
1504
1550
|
await deployStepHeading.click({ timeout });
|
|
@@ -1520,9 +1566,21 @@ class ModelerCreatePage {
|
|
|
1520
1566
|
if (await isDeployComplete()) {
|
|
1521
1567
|
return;
|
|
1522
1568
|
}
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1569
|
+
const isButtonShown = await setupDeployButton
|
|
1570
|
+
.isVisible()
|
|
1571
|
+
.catch(() => false);
|
|
1572
|
+
if (!isButtonShown) {
|
|
1573
|
+
// Collapsed, not gone: re-open the step instead of waiting the
|
|
1574
|
+
// budget out on a button that can never become visible on its own
|
|
1575
|
+
// once manualSetupStep is 'none'.
|
|
1576
|
+
const canExpand = await deployStepHeading
|
|
1577
|
+
.isEnabled()
|
|
1578
|
+
.catch(() => false);
|
|
1579
|
+
if (canExpand) {
|
|
1580
|
+
await deployStepHeading.click({ timeout });
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
else if (await setupDeployButton.isEnabled().catch(() => false)) {
|
|
1526
1584
|
await setupDeployButton.click({ timeout });
|
|
1527
1585
|
}
|
|
1528
1586
|
(0, test_1.expect)(await isDeployComplete()).toBe(true);
|
|
@@ -145,7 +145,6 @@ class ProcessApplicationPage {
|
|
|
145
145
|
// taken -- callers that care assert the name in the deploy dialog anyway.
|
|
146
146
|
async defineDevelopmentStage(clusterName) {
|
|
147
147
|
await (0, test_1.expect)(this.defineStagesDialog).toBeVisible({ timeout: 60000 });
|
|
148
|
-
await this.developmentClusterSelect.click({ timeout: 30000 });
|
|
149
148
|
// Escape before interpolating: a cluster name can carry regex
|
|
150
149
|
// metacharacters -- "Test Cluster (v2)" is the common case -- which would
|
|
151
150
|
// otherwise mis-match or throw. Same treatment as
|
|
@@ -159,9 +158,52 @@ class ProcessApplicationPage {
|
|
|
159
158
|
.getByRole('option')
|
|
160
159
|
.filter({ hasNotText: 'Select a development cluster' })
|
|
161
160
|
.first();
|
|
162
|
-
|
|
161
|
+
// The dropdown is fully controlled and DefineStagesModal resets its local
|
|
162
|
+
// state from processApplication.default*ClusterId in an effect. The modal
|
|
163
|
+
// itself triggers a cluster/application refresh when it opens, so a
|
|
164
|
+
// selection made before that refresh lands is silently reverted to
|
|
165
|
+
// whatever the application already pointed at -- and Save then persists
|
|
166
|
+
// THAT cluster. A failing nightly trace shows exactly this: the option
|
|
167
|
+
// click committed "Test Cluster", and ~0.5s later, with the Save click
|
|
168
|
+
// already in flight, the field had snapped back to "First RBA V2 Cluster".
|
|
169
|
+
// The application bound the wrong cluster, and Play's "Choose where to
|
|
170
|
+
// run" step then reported "Cluster unavailable" for it, which leaves the
|
|
171
|
+
// Deploy button hardcoded-disabled and fails the test 60s later, far from
|
|
172
|
+
// the cause. Re-select until the field still reads the requested cluster.
|
|
173
|
+
const selectedCluster = this.developmentClusterSelect.getByRole('combobox');
|
|
174
|
+
const isRequestedCluster = async () => {
|
|
175
|
+
const label = (await selectedCluster.textContent()) ?? '';
|
|
176
|
+
return clusterName
|
|
177
|
+
? new RegExp(`^${escapedClusterName}`).test(label)
|
|
178
|
+
: !label.startsWith('[Select a');
|
|
179
|
+
};
|
|
180
|
+
await (0, test_1.expect)(async () => {
|
|
181
|
+
if (!(await isRequestedCluster())) {
|
|
182
|
+
await this.developmentClusterSelect.click({ timeout: 30000 });
|
|
183
|
+
await option.click({ timeout: 30000 });
|
|
184
|
+
}
|
|
185
|
+
(0, test_1.expect)(await isRequestedCluster()).toBe(true);
|
|
186
|
+
}).toPass({ timeout: 90000, intervals: [1000, 2000, 5000] });
|
|
163
187
|
await this.defineStagesSaveButton.click({ timeout: 30000 });
|
|
164
188
|
await (0, test_1.expect)(this.defineStagesDialog).toBeHidden({ timeout: 60000 });
|
|
189
|
+
// Verify what was actually persisted, not what was typed into the modal:
|
|
190
|
+
// the revert above can also land between the last check and the Save
|
|
191
|
+
// click. The Connected clusters card renders one row per bound stage with
|
|
192
|
+
// the cluster's full "<name> <generation>" as its title, so it is the
|
|
193
|
+
// cheapest read of the saved binding. Failing here re-runs the whole bind
|
|
194
|
+
// through ensureStageCluster's retry, which re-navigates first.
|
|
195
|
+
if (clusterName) {
|
|
196
|
+
const developmentRow = this.page
|
|
197
|
+
.getByRole('listitem')
|
|
198
|
+
.filter({
|
|
199
|
+
has: this.page.getByRole('button', {
|
|
200
|
+
name: 'Development',
|
|
201
|
+
exact: true,
|
|
202
|
+
}),
|
|
203
|
+
})
|
|
204
|
+
.first();
|
|
205
|
+
await (0, test_1.expect)(developmentRow.getByTitle(new RegExp(`^${escapedClusterName}( |$)`))).toBeVisible({ timeout: 60000 });
|
|
206
|
+
}
|
|
165
207
|
}
|
|
166
208
|
rememberResourceContainer(url) {
|
|
167
209
|
resourceContainers.set(this.page, { url });
|