@camunda/e2e-test-suite 0.0.901 → 0.0.903

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.
@@ -97,6 +97,7 @@ declare class ModelerCreatePage {
97
97
  assertThreeElementsVisible(): Promise<void>;
98
98
  clickForm(name: string): Promise<void>;
99
99
  runProcessInstance(variables?: string, tenant?: string, businessId?: string): Promise<void>;
100
+ private suppressTestModeAnnouncement;
100
101
  switchToPlay(): Promise<void>;
101
102
  clickGeneralPropertiesPanel(): Promise<void>;
102
103
  clickIdInput(): Promise<void>;
@@ -205,9 +205,14 @@ class ModelerCreatePage {
205
205
  .locator('[data-id="replace.template-io.camunda.connectors.webhook.WebhookConnectorIntermediate.v1"]');
206
206
  this.correlationKeyPayloadInput = page.getByLabel('Correlation key (payload)');
207
207
  this.correlationKeyProcessInput = page.getByLabel('Correlation key (process)');
208
- this.playTab = page.getByRole('tab', {
209
- name: 'Play',
210
- });
208
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
209
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
210
+ // tablist because the details panel also renders a tab named "Test".
211
+ this.playTab = page
212
+ .getByRole('tab', { name: 'Play' })
213
+ .or(page
214
+ .getByRole('tablist', { name: 'List of modes' })
215
+ .getByRole('tab', { name: 'Test', exact: true }));
211
216
  this.candidateUsersInput = page.getByRole('textbox', {
212
217
  name: 'candidate users',
213
218
  });
@@ -396,8 +401,17 @@ class ModelerCreatePage {
396
401
  }
397
402
  }
398
403
  }
404
+ // Test mode mounts a one-time "A new way to test your processes" modal
405
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
406
+ // It renders unless localStorage already carries the seen flag, which it
407
+ // reads on mount; a fresh Playwright context always starts empty, so set the
408
+ // flag before entering Test mode rather than clicking the modal away.
409
+ async suppressTestModeAnnouncement() {
410
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
411
+ }
399
412
  async switchToPlay() {
400
413
  await (0, test_1.expect)(this.playTab).toBeVisible();
414
+ await this.suppressTestModeAnnouncement();
401
415
  await this.playTab.click();
402
416
  }
403
417
  async clickGeneralPropertiesPanel() {
@@ -857,14 +871,15 @@ class ModelerCreatePage {
857
871
  // New flow (8.10+): "Setup environment" panel with three steps:
858
872
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
859
873
  // 2. Deploy process → wait for success banner
860
- // 3. Configure scenario
874
+ // 3. Configure test case
861
875
  const setupDeployButton = this.page
862
876
  .getByText('Deploy process')
863
877
  .locator('..')
864
878
  .getByRole('button', { name: 'Deploy' });
865
- const configureScenarioButton = this.page.getByRole('button', {
866
- name: 'Configure scenario',
867
- });
879
+ // Keyed on the test id, not the label: the button reads "Configure test
880
+ // case" since camunda-hub a90fd06 and "Configure scenario" before it, while
881
+ // the test id kept its original wording across the rename.
882
+ const configureScenarioButton = this.page.getByTestId('play-configuration-configure-scenario-button');
868
883
  // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
869
884
  // button to appear. Using .or() avoids separate sequential timeouts that would
870
885
  // both expire before the page finishes loading on a slow cluster.
@@ -1251,7 +1266,7 @@ class ModelerCreatePage {
1251
1266
  .getByTestId('instance-header')
1252
1267
  .getByText(scenarioName)
1253
1268
  .or(this.page
1254
- .getByRole('region', { name: 'Scenarios' })
1269
+ .getByRole('region', { name: /^(Scenarios|Test cases)$/i })
1255
1270
  .getByText(scenarioName, { exact: false }))).toBeVisible();
1256
1271
  }
1257
1272
  async fillStartEventVariablesForDocHandling(zeebeUrl, zeebeClientId, zeebeClientSecret) {
@@ -33,12 +33,17 @@ class PlayPage {
33
33
  this.completeJobButton = page
34
34
  .getByTestId('diagram')
35
35
  .getByLabel('Complete job');
36
- this.viewScenarioButton = page.getByRole('button', { name: 'View scenario' });
36
+ // Test mode renamed "scenario" to "test case" across this panel
37
+ // (camunda-hub a90fd06). Each label below accepts both wordings so the
38
+ // page object works either side of the rename.
39
+ this.viewScenarioButton = page.getByRole('button', {
40
+ name: /^View (scenario|test case)$/i,
41
+ });
37
42
  this.runAllScenariosButton = page.getByRole('button', {
38
- name: 'Run all scenarios',
43
+ name: /^Run all (scenarios|test cases)$/i,
39
44
  });
40
45
  this.confirmDeleteScenarioButton = page
41
- .getByRole('dialog', { name: 'Delete scenario' })
46
+ .getByRole('dialog', { name: /^Delete (scenario|test case)$/i })
42
47
  .getByRole('button', { name: 'Delete', exact: true });
43
48
  // After saving a scenario, the Scenarios panel is in detail-view mode.
44
49
  // To get back to the list (where "Run all scenarios" lives in
@@ -47,8 +52,7 @@ class PlayPage {
47
52
  // This replaces the legacy bottom-bar `(View all)` link that used to
48
53
  // close the saved-scenario view.
49
54
  this.viewAllScenariosButton = page.getByRole('button', {
50
- name: 'Back to scenarios',
51
- exact: true,
55
+ name: /^Back to (scenarios|test cases)$/i,
52
56
  });
53
57
  this.getScenarioRowByName = (scenarioName) => page.locator('tr', { hasText: scenarioName });
54
58
  this.getScenarioRow = (scenarioName) => page.locator('tr', { hasText: scenarioName });
@@ -68,8 +72,7 @@ class PlayPage {
68
72
  // ScenarioDetail/useScenarioEditor.ts.
69
73
  this.scenarioDetailNameInput = page.locator('input#scenario-name');
70
74
  this.scenarioDetailSaveButton = page.getByRole('button', {
71
- name: 'Save scenario',
72
- exact: true,
75
+ name: /^Save (scenario|test case)$/i,
73
76
  });
74
77
  // c4-notifications wraps Carbon ToastNotification with role="alert" for
75
78
  // non-actionable toasts (see Notification.tsx in @camunda/c4-notifications).
@@ -77,7 +80,7 @@ class PlayPage {
77
80
  // locator is resilient to Carbon version bumps.
78
81
  this.scenarioSavedToast = page
79
82
  .getByRole('alert')
80
- .filter({ hasText: 'Scenario saved' });
83
+ .filter({ hasText: /(Scenario|Test case) saved/i });
81
84
  this.loadingInstanceDetailsText = this.page.getByText('Loading instance details...');
82
85
  this.retryButton = this.page.getByRole('button', { name: 'Retry' });
83
86
  // New Play UI (8.10+): "Configure scenario" opens an input panel with a plain "Start" button.
@@ -96,9 +99,11 @@ class PlayPage {
96
99
  await this.completeJobButton.click();
97
100
  }
98
101
  async clickStartInstanceButton() {
99
- const scenariosRegion = this.page.getByRole('region', { name: 'Scenarios' });
102
+ const scenariosRegion = this.page.getByRole('region', {
103
+ name: /^(Scenarios|Test cases)$/i,
104
+ });
100
105
  const backToScenariosButton = scenariosRegion.getByRole('button', {
101
- name: 'Back to scenarios',
106
+ name: /^Back to (scenarios|test cases)$/i,
102
107
  });
103
108
  const closeScenariosButton = scenariosRegion.getByRole('button', {
104
109
  name: 'Close',
@@ -231,20 +236,27 @@ class PlayPage {
231
236
  await (0, test_1.expect)(this.scenarioSavedToast).toBeVisible({ timeout: 30000 });
232
237
  }
233
238
  async assertSavedScenarioNameInPanel(scenarioName) {
234
- // After save, useScenarioEditor.saveTest() calls
235
- // scenariosStore.stopRecording() + setSelectedScenario(newScenario) and
236
- // processInstanceStore.reset(). The Scenarios side panel stays open in
237
- // 'view' mode for the just-saved scenario, rendering the name as the
238
- // TestName h4 (see ScenarioDetail/styled.tsx and index.tsx). The legacy
239
- // instance-header scenarioName slot is cleared by the reset and is no
240
- // longer the source of truth for the saved name.
241
- await (0, test_1.expect)(this.page.getByRole('heading', { name: scenarioName, exact: true })).toBeVisible({ timeout: 30000 });
239
+ // After save the detail view stays open on the just-saved test case. It
240
+ // renders the name as a TestName heading only when the environment is
241
+ // read-only; otherwise the name lives in the editable Name field (see
242
+ // TestCaseDetail/index.tsx, gated on testEnvironmentStore.isReadOnly).
243
+ // Assert the exact name either way.
244
+ const heading = this.page.getByRole('heading', {
245
+ name: scenarioName,
246
+ exact: true,
247
+ });
248
+ if (await heading.isVisible({ timeout: 3000 }).catch(() => false)) {
249
+ return;
250
+ }
251
+ await (0, test_1.expect)(this.scenarioDetailNameInput).toHaveValue(scenarioName, {
252
+ timeout: 30000,
253
+ });
242
254
  }
243
255
  async getDeleteIconForScenario(scenarioName) {
244
256
  const scenarioRow = this.page
245
257
  .locator('tr')
246
258
  .filter({ has: this.page.getByText(scenarioName, { exact: true }) });
247
- return scenarioRow.getByLabel('Delete scenario');
259
+ return scenarioRow.getByLabel(/^Delete (scenario|test case)$/i);
248
260
  }
249
261
  async deleteScenario(scenarioName) {
250
262
  const deleteIcon = await this.getDeleteIconForScenario(scenarioName);
@@ -77,6 +77,7 @@ declare class ModelerCreatePage {
77
77
  assertThreeElementsVisible(): Promise<void>;
78
78
  clickForm(name: string): Promise<void>;
79
79
  runProcessInstance(variables?: string): Promise<void>;
80
+ private suppressTestModeAnnouncement;
80
81
  switchToPlay(): Promise<void>;
81
82
  clickGeneralPropertiesPanel(): Promise<void>;
82
83
  clickIdInput(): Promise<void>;
@@ -172,9 +172,14 @@ class ModelerCreatePage {
172
172
  });
173
173
  this.correlationKeyPayloadInput = page.getByLabel('Correlation key (payload)');
174
174
  this.correlationKeyProcessInput = page.getByLabel('Correlation key (process)');
175
- this.playTab = page.getByRole('tab', {
176
- name: 'Play',
177
- });
175
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
176
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
177
+ // tablist because the details panel also renders a tab named "Test".
178
+ this.playTab = page
179
+ .getByRole('tab', { name: 'Play' })
180
+ .or(page
181
+ .getByRole('tablist', { name: 'List of modes' })
182
+ .getByRole('tab', { name: 'Test', exact: true }));
178
183
  this.candidateUsersInput = page.getByRole('textbox', {
179
184
  name: 'candidate users',
180
185
  });
@@ -288,7 +293,16 @@ class ModelerCreatePage {
288
293
  await this.clickStartInstanceSubButton();
289
294
  await this.instanceStartedAssertion();
290
295
  }
296
+ // Test mode mounts a one-time "A new way to test your processes" modal
297
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
298
+ // It renders unless localStorage already carries the seen flag, which it
299
+ // reads on mount; a fresh Playwright context always starts empty, so set the
300
+ // flag before entering Test mode rather than clicking the modal away.
301
+ async suppressTestModeAnnouncement() {
302
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
303
+ }
291
304
  async switchToPlay() {
305
+ await this.suppressTestModeAnnouncement();
292
306
  await this.playTab.click();
293
307
  }
294
308
  async clickGeneralPropertiesPanel() {
@@ -96,6 +96,7 @@ declare class ModelerCreatePage {
96
96
  assertThreeElementsVisible(): Promise<void>;
97
97
  clickForm(name: string): Promise<void>;
98
98
  runProcessInstance(variables?: string, tenant?: string): Promise<void>;
99
+ private suppressTestModeAnnouncement;
99
100
  switchToPlay(): Promise<void>;
100
101
  clickGeneralPropertiesPanel(): Promise<void>;
101
102
  clickIdInput(): Promise<void>;
@@ -197,9 +197,14 @@ class ModelerCreatePage {
197
197
  });
198
198
  this.correlationKeyPayloadInput = page.getByLabel('Correlation key (payload)');
199
199
  this.correlationKeyProcessInput = page.getByLabel('Correlation key (process)');
200
- this.playTab = page.getByRole('tab', {
201
- name: 'Play',
202
- });
200
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
201
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
202
+ // tablist because the details panel also renders a tab named "Test".
203
+ this.playTab = page
204
+ .getByRole('tab', { name: 'Play' })
205
+ .or(page
206
+ .getByRole('tablist', { name: 'List of modes' })
207
+ .getByRole('tab', { name: 'Test', exact: true }));
203
208
  this.candidateUsersInput = page.getByRole('textbox', {
204
209
  name: 'candidate users',
205
210
  });
@@ -396,8 +401,17 @@ class ModelerCreatePage {
396
401
  }
397
402
  }
398
403
  }
404
+ // Test mode mounts a one-time "A new way to test your processes" modal
405
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
406
+ // It renders unless localStorage already carries the seen flag, which it
407
+ // reads on mount; a fresh Playwright context always starts empty, so set the
408
+ // flag before entering Test mode rather than clicking the modal away.
409
+ async suppressTestModeAnnouncement() {
410
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
411
+ }
399
412
  async switchToPlay() {
400
413
  await (0, test_1.expect)(this.playTab).toBeVisible();
414
+ await this.suppressTestModeAnnouncement();
401
415
  await this.playTab.click();
402
416
  }
403
417
  async clickGeneralPropertiesPanel() {
@@ -94,6 +94,7 @@ declare class ModelerCreatePage {
94
94
  assertThreeElementsVisible(): Promise<void>;
95
95
  clickForm(name: string): Promise<void>;
96
96
  runProcessInstance(variables?: string, tenant?: string): Promise<void>;
97
+ private suppressTestModeAnnouncement;
97
98
  switchToPlay(): Promise<void>;
98
99
  clickGeneralPropertiesPanel(): Promise<void>;
99
100
  clickIdInput(): Promise<void>;
@@ -182,9 +182,14 @@ class ModelerCreatePage {
182
182
  });
183
183
  this.correlationKeyPayloadInput = page.getByLabel('Correlation key (payload)');
184
184
  this.correlationKeyProcessInput = page.getByLabel('Correlation key (process)');
185
- this.playTab = page.getByRole('tab', {
186
- name: 'Play',
187
- });
185
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
186
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
187
+ // tablist because the details panel also renders a tab named "Test".
188
+ this.playTab = page
189
+ .getByRole('tab', { name: 'Play' })
190
+ .or(page
191
+ .getByRole('tablist', { name: 'List of modes' })
192
+ .getByRole('tab', { name: 'Test', exact: true }));
188
193
  this.candidateUsersInput = page.getByRole('textbox', {
189
194
  name: 'candidate users',
190
195
  });
@@ -367,8 +372,17 @@ class ModelerCreatePage {
367
372
  }
368
373
  }
369
374
  }
375
+ // Test mode mounts a one-time "A new way to test your processes" modal
376
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
377
+ // It renders unless localStorage already carries the seen flag, which it
378
+ // reads on mount; a fresh Playwright context always starts empty, so set the
379
+ // flag before entering Test mode rather than clicking the modal away.
380
+ async suppressTestModeAnnouncement() {
381
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
382
+ }
370
383
  async switchToPlay() {
371
384
  await (0, test_1.expect)(this.playTab).toBeVisible();
385
+ await this.suppressTestModeAnnouncement();
372
386
  await this.playTab.click();
373
387
  }
374
388
  async clickGeneralPropertiesPanel() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.901",
3
+ "version": "0.0.903",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",