@camunda/e2e-test-suite 0.0.902 → 0.0.904

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.
@@ -204,6 +204,7 @@ declare class ModelerCreatePage {
204
204
  clickTaskDefinitionPropertiesPanel(): Promise<void>;
205
205
  clickJobTypeInput(): Promise<void>;
206
206
  fillJobTypeInput(name: string): Promise<void>;
207
+ private suppressTestModeAnnouncement;
207
208
  switchToPlay(): Promise<void>;
208
209
  completePlayConfiguration(clusterName: string): Promise<void>;
209
210
  embedForm(formName: string): Promise<void>;
@@ -256,9 +256,14 @@ class ModelerCreatePage {
256
256
  this.serviceTaskOption = page.locator('.djs-popup-results [data-id="replace-with-service-task"]');
257
257
  this.taskDefinitionPanel = page.locator('[data-group-id="group-taskDefinition"]');
258
258
  this.jobTypeInput = page.getByRole('textbox', { name: /job type/i });
259
- this.playTab = page.getByRole('tab', {
260
- name: 'Play',
261
- });
259
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
260
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
261
+ // tablist because the details panel also renders a tab named "Test".
262
+ this.playTab = page
263
+ .getByRole('tab', { name: 'Play' })
264
+ .or(page
265
+ .getByRole('tablist', { name: 'List of modes' })
266
+ .getByRole('tab', { name: 'Test', exact: true }));
262
267
  this.continueToPlayButton = page.getByRole('button', { name: 'Continue' });
263
268
  this.assignmentSection = page.locator('[data-group-id="group-assignmentDefinition"]');
264
269
  this.assigneeInput = page.getByRole('textbox', { name: 'assignee' });
@@ -1124,7 +1129,16 @@ class ModelerCreatePage {
1124
1129
  async fillJobTypeInput(name) {
1125
1130
  await this.jobTypeInput.fill(name);
1126
1131
  }
1132
+ // Test mode mounts a one-time "A new way to test your processes" modal
1133
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
1134
+ // It renders unless localStorage already carries the seen flag, which it
1135
+ // reads on mount; a fresh Playwright context always starts empty, so set the
1136
+ // flag before entering Test mode rather than clicking the modal away.
1137
+ async suppressTestModeAnnouncement() {
1138
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
1139
+ }
1127
1140
  async switchToPlay() {
1141
+ await this.suppressTestModeAnnouncement();
1128
1142
  await this.playTab.click();
1129
1143
  }
1130
1144
  async completePlayConfiguration(clusterName) {
@@ -1132,14 +1146,15 @@ class ModelerCreatePage {
1132
1146
  // New flow (8.10+): "Setup environment" panel with three steps:
1133
1147
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
1134
1148
  // 2. Deploy process → wait for success banner
1135
- // 3. Configure scenario
1149
+ // 3. Configure test case
1136
1150
  const setupDeployButton = this.page
1137
1151
  .getByText('Deploy process')
1138
1152
  .locator('..')
1139
1153
  .getByRole('button', { name: 'Deploy' });
1140
- const configureScenarioButton = this.page.getByRole('button', {
1141
- name: 'Configure scenario',
1142
- });
1154
+ // Keyed on the test id, not the label: the button reads "Configure test
1155
+ // case" since camunda-hub a90fd06 and "Configure scenario" before it, while
1156
+ // the test id kept its original wording across the rename.
1157
+ const configureScenarioButton = this.page.getByTestId('play-configuration-configure-scenario-button');
1143
1158
  // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
1144
1159
  // button to appear. Using .or() avoids separate sequential timeouts that would
1145
1160
  // both expire before the page finishes loading on a slow cluster.
@@ -198,6 +198,7 @@ declare class ModelerCreatePage {
198
198
  clickTaskDefinitionPropertiesPanel(): Promise<void>;
199
199
  clickJobTypeInput(): Promise<void>;
200
200
  fillJobTypeInput(name: string): Promise<void>;
201
+ private suppressTestModeAnnouncement;
201
202
  switchToPlay(): Promise<void>;
202
203
  completePlayConfiguration(clusterName: string): Promise<void>;
203
204
  selectCluster(clusterName: string): Promise<void>;
@@ -223,9 +223,14 @@ class ModelerCreatePage {
223
223
  this.serviceTaskOption = page.locator('.djs-popup-results [data-id="replace-with-service-task"]');
224
224
  this.taskDefinitionPanel = page.locator('[data-group-id="group-taskDefinition"]');
225
225
  this.jobTypeInput = page.getByRole('textbox', { name: /job type/i });
226
- this.playTab = page.getByRole('tab', {
227
- name: 'Play',
228
- });
226
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
227
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
228
+ // tablist because the details panel also renders a tab named "Test".
229
+ this.playTab = page
230
+ .getByRole('tab', { name: 'Play' })
231
+ .or(page
232
+ .getByRole('tablist', { name: 'List of modes' })
233
+ .getByRole('tab', { name: 'Test', exact: true }));
229
234
  this.continueToPlayButton = page.getByRole('button', { name: 'Continue' });
230
235
  this.assignmentSection = page.locator('[data-group-id="group-assignmentDefinition"]');
231
236
  this.assigneeInput = page.getByRole('textbox', { name: 'assignee' });
@@ -1022,7 +1027,16 @@ class ModelerCreatePage {
1022
1027
  async fillJobTypeInput(name) {
1023
1028
  await this.jobTypeInput.fill(name);
1024
1029
  }
1030
+ // Test mode mounts a one-time "A new way to test your processes" modal
1031
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
1032
+ // It renders unless localStorage already carries the seen flag, which it
1033
+ // reads on mount; a fresh Playwright context always starts empty, so set the
1034
+ // flag before entering Test mode rather than clicking the modal away.
1035
+ async suppressTestModeAnnouncement() {
1036
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
1037
+ }
1025
1038
  async switchToPlay() {
1039
+ await this.suppressTestModeAnnouncement();
1026
1040
  await this.playTab.click();
1027
1041
  }
1028
1042
  async completePlayConfiguration(clusterName) {
@@ -1030,14 +1044,15 @@ class ModelerCreatePage {
1030
1044
  // New flow (8.10+): "Setup environment" panel with three steps:
1031
1045
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
1032
1046
  // 2. Deploy process → wait for success banner
1033
- // 3. Configure scenario
1047
+ // 3. Configure test case
1034
1048
  const setupDeployButton = this.page
1035
1049
  .getByText('Deploy process')
1036
1050
  .locator('..')
1037
1051
  .getByRole('button', { name: 'Deploy' });
1038
- const configureScenarioButton = this.page.getByRole('button', {
1039
- name: 'Configure scenario',
1040
- });
1052
+ // Keyed on the test id, not the label: the button reads "Configure test
1053
+ // case" since camunda-hub a90fd06 and "Configure scenario" before it, while
1054
+ // the test id kept its original wording across the rename.
1055
+ const configureScenarioButton = this.page.getByTestId('play-configuration-configure-scenario-button');
1041
1056
  // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
1042
1057
  // button to appear.
1043
1058
  const setupOrContinue = setupDeployButton.or(this.continueToPlayButton);
@@ -15,7 +15,14 @@ class PlayPage {
15
15
  constructor(page) {
16
16
  this.page = page;
17
17
  this.diagram = page.getByTestId('diagram');
18
- this.playTab = page.getByRole('tab', { name: 'Play' });
18
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
19
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
20
+ // tablist because the details panel also renders a tab named "Test".
21
+ this.playTab = page
22
+ .getByRole('tab', { name: 'Play' })
23
+ .or(page
24
+ .getByRole('tablist', { name: 'List of modes' })
25
+ .getByRole('tab', { name: 'Test', exact: true }));
19
26
  this.completeJobButton = this.diagram.getByLabel('Complete job');
20
27
  // Newer Modeler Play UI: the "Configure Scenario" floating card hosts a
21
28
  // primary "Start" Carbon button (variants: "Start", "Start with
@@ -203,6 +203,7 @@ declare class ModelerCreatePage {
203
203
  clickTaskDefinitionPropertiesPanel(): Promise<void>;
204
204
  clickJobTypeInput(): Promise<void>;
205
205
  fillJobTypeInput(name: string): Promise<void>;
206
+ private suppressTestModeAnnouncement;
206
207
  switchToPlay(): Promise<void>;
207
208
  completePlayConfiguration(clusterName: string): Promise<void>;
208
209
  embedForm(formName: string): Promise<void>;
@@ -255,9 +255,14 @@ class ModelerCreatePage {
255
255
  this.serviceTaskOption = page.locator('.djs-popup-results [data-id="replace-with-service-task"]');
256
256
  this.taskDefinitionPanel = page.locator('[data-group-id="group-taskDefinition"]');
257
257
  this.jobTypeInput = page.getByRole('textbox', { name: /job type/i });
258
- this.playTab = page.getByRole('tab', {
259
- name: 'Play',
260
- });
258
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
259
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
260
+ // tablist because the details panel also renders a tab named "Test".
261
+ this.playTab = page
262
+ .getByRole('tab', { name: 'Play' })
263
+ .or(page
264
+ .getByRole('tablist', { name: 'List of modes' })
265
+ .getByRole('tab', { name: 'Test', exact: true }));
261
266
  this.continueToPlayButton = page.getByRole('button', { name: 'Continue' });
262
267
  this.assignmentSection = page.locator('[data-group-id="group-assignmentDefinition"]');
263
268
  this.assigneeInput = page.getByRole('textbox', { name: 'assignee' });
@@ -1171,7 +1176,16 @@ class ModelerCreatePage {
1171
1176
  async fillJobTypeInput(name) {
1172
1177
  await this.jobTypeInput.fill(name);
1173
1178
  }
1179
+ // Test mode mounts a one-time "A new way to test your processes" modal
1180
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
1181
+ // It renders unless localStorage already carries the seen flag, which it
1182
+ // reads on mount; a fresh Playwright context always starts empty, so set the
1183
+ // flag before entering Test mode rather than clicking the modal away.
1184
+ async suppressTestModeAnnouncement() {
1185
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
1186
+ }
1174
1187
  async switchToPlay() {
1188
+ await this.suppressTestModeAnnouncement();
1175
1189
  await this.playTab.click();
1176
1190
  }
1177
1191
  async completePlayConfiguration(clusterName) {
@@ -1179,14 +1193,15 @@ class ModelerCreatePage {
1179
1193
  // New flow (8.10+): "Setup environment" panel with three steps:
1180
1194
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
1181
1195
  // 2. Deploy process → wait for success banner
1182
- // 3. Configure scenario
1196
+ // 3. Configure test case
1183
1197
  const setupDeployButton = this.page
1184
1198
  .getByText('Deploy process')
1185
1199
  .locator('..')
1186
1200
  .getByRole('button', { name: 'Deploy' });
1187
- const configureScenarioButton = this.page.getByRole('button', {
1188
- name: 'Configure scenario',
1189
- });
1201
+ // Keyed on the test id, not the label: the button reads "Configure test
1202
+ // case" since camunda-hub a90fd06 and "Configure scenario" before it, while
1203
+ // the test id kept its original wording across the rename.
1204
+ const configureScenarioButton = this.page.getByTestId('play-configuration-configure-scenario-button');
1190
1205
  // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
1191
1206
  // button to appear. Using .or() avoids separate sequential timeouts that would
1192
1207
  // both expire before the page finishes loading on a slow cluster.
@@ -203,6 +203,7 @@ declare class ModelerCreatePage {
203
203
  clickTaskDefinitionPropertiesPanel(): Promise<void>;
204
204
  clickJobTypeInput(): Promise<void>;
205
205
  fillJobTypeInput(name: string): Promise<void>;
206
+ private suppressTestModeAnnouncement;
206
207
  switchToPlay(): Promise<void>;
207
208
  completePlayConfiguration(clusterName: string): Promise<void>;
208
209
  embedForm(formName: string): Promise<void>;
@@ -255,9 +255,14 @@ class ModelerCreatePage {
255
255
  this.serviceTaskOption = page.locator('.djs-popup-results [data-id="replace-with-service-task"]');
256
256
  this.taskDefinitionPanel = page.locator('[data-group-id="group-taskDefinition"]');
257
257
  this.jobTypeInput = page.getByRole('textbox', { name: /job type/i });
258
- this.playTab = page.getByRole('tab', {
259
- name: 'Play',
260
- });
258
+ // Modeler renamed the third mode tab "Play" -> "Test" (camunda-hub
259
+ // a90fd06). Accept either label; the "Test" branch is scoped to the modes
260
+ // tablist because the details panel also renders a tab named "Test".
261
+ this.playTab = page
262
+ .getByRole('tab', { name: 'Play' })
263
+ .or(page
264
+ .getByRole('tablist', { name: 'List of modes' })
265
+ .getByRole('tab', { name: 'Test', exact: true }));
261
266
  this.continueToPlayButton = page.getByRole('button', { name: 'Continue' });
262
267
  this.assignmentSection = page.locator('[data-group-id="group-assignmentDefinition"]');
263
268
  this.assigneeInput = page.getByRole('textbox', { name: 'assignee' });
@@ -1119,7 +1124,16 @@ class ModelerCreatePage {
1119
1124
  async fillJobTypeInput(name) {
1120
1125
  await this.jobTypeInput.fill(name);
1121
1126
  }
1127
+ // Test mode mounts a one-time "A new way to test your processes" modal
1128
+ // (camunda-hub TestAnnouncementModal) that covers the setup steps behind it.
1129
+ // It renders unless localStorage already carries the seen flag, which it
1130
+ // reads on mount; a fresh Playwright context always starts empty, so set the
1131
+ // flag before entering Test mode rather than clicking the modal away.
1132
+ async suppressTestModeAnnouncement() {
1133
+ await this.page.evaluate(() => localStorage.setItem('play-testAnnouncementSeen', 'true'));
1134
+ }
1122
1135
  async switchToPlay() {
1136
+ await this.suppressTestModeAnnouncement();
1123
1137
  await this.playTab.click();
1124
1138
  }
1125
1139
  async completePlayConfiguration(clusterName) {
@@ -1127,14 +1141,15 @@ class ModelerCreatePage {
1127
1141
  // New flow (8.10+): "Setup environment" panel with three steps:
1128
1142
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
1129
1143
  // 2. Deploy process → wait for success banner
1130
- // 3. Configure scenario
1144
+ // 3. Configure test case
1131
1145
  const setupDeployButton = this.page
1132
1146
  .getByText('Deploy process')
1133
1147
  .locator('..')
1134
1148
  .getByRole('button', { name: 'Deploy' });
1135
- const configureScenarioButton = this.page.getByRole('button', {
1136
- name: 'Configure scenario',
1137
- });
1149
+ // Keyed on the test id, not the label: the button reads "Configure test
1150
+ // case" since camunda-hub a90fd06 and "Configure scenario" before it, while
1151
+ // the test id kept its original wording across the rename.
1152
+ const configureScenarioButton = this.page.getByTestId('play-configuration-configure-scenario-button');
1138
1153
  // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
1139
1154
  // button to appear. Using .or() avoids separate sequential timeouts that would
1140
1155
  // both expire before the page finishes loading on a slow cluster.
@@ -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.902",
3
+ "version": "0.0.904",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",