@camunda/e2e-test-suite 0.0.483 → 0.0.484

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.
@@ -119,6 +119,7 @@ declare class ModelerCreatePage {
119
119
  clickViewProcessInstanceLink(): Promise<void>;
120
120
  clickNameInput(): Promise<void>;
121
121
  clickUserTask(id: string): Promise<void>;
122
+ clickCanvasElement(elementId: string): Promise<void>;
122
123
  fillNameInput(name: string): Promise<void>;
123
124
  clickJobTypeInput(): Promise<void>;
124
125
  fillJobTypeInput(name: string): Promise<void>;
@@ -560,6 +560,12 @@ class ModelerCreatePage {
560
560
  const priorityUserTask = this.page.locator(`[data-element-id="${id}"]`);
561
561
  await priorityUserTask.click({ timeout: 60000 });
562
562
  }
563
+ async clickCanvasElement(elementId) {
564
+ await this.page
565
+ .locator(`[data-element-id="${elementId}"]`)
566
+ .first()
567
+ .click({ timeout: 30000 });
568
+ }
563
569
  async fillNameInput(name) {
564
570
  await this.nameInput.fill(name);
565
571
  }
@@ -65,6 +65,7 @@ class PlayPage {
65
65
  });
66
66
  }
67
67
  async clickCompleteJobButton() {
68
+ await this.completeJobButton.waitFor({ state: 'visible', timeout: 30000 });
68
69
  await this.completeJobButton.click();
69
70
  }
70
71
  async clickStartInstanceButton() {
@@ -72,6 +73,7 @@ class PlayPage {
72
73
  let attempts = 0;
73
74
  while (attempts < maxRetries) {
74
75
  try {
76
+ await this.page.waitForLoadState('domcontentloaded');
75
77
  await this.diagram.waitFor({ state: 'visible', timeout: 60000 });
76
78
  await this.startInstanceButton
77
79
  .or(this.startInstanceWithCachedButton)
@@ -86,7 +88,7 @@ class PlayPage {
86
88
  catch (error) {
87
89
  if (attempts >= maxRetries - 1)
88
90
  throw error;
89
- await (0, sleep_1.sleep)(5000);
91
+ await this.page.waitForLoadState('load');
90
92
  attempts++;
91
93
  }
92
94
  }
@@ -98,12 +100,21 @@ class PlayPage {
98
100
  'Start new instance',
99
101
  'Start instance',
100
102
  ];
101
- for (const buttonName of buttonVariations) {
102
- const button = this.page.getByRole('button', { name: buttonName });
103
- const count = await button.count();
104
- if (count > 0) {
105
- await button.click();
106
- return;
103
+ // Wait for the page to settle before checking for modal buttons
104
+ await this.page.waitForLoadState('domcontentloaded');
105
+ const maxAttempts = 3;
106
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
107
+ for (const buttonName of buttonVariations) {
108
+ const button = this.page.getByRole('button', { name: buttonName });
109
+ const count = await button.count();
110
+ if (count > 0) {
111
+ await button.waitFor({ state: 'visible', timeout: 10000 });
112
+ await button.click();
113
+ return;
114
+ }
115
+ }
116
+ if (attempt < maxAttempts - 1) {
117
+ await this.page.waitForLoadState('load');
107
118
  }
108
119
  }
109
120
  throw new Error('Could not find start instance button with any expected variation');
@@ -113,44 +124,24 @@ class PlayPage {
113
124
  await this.startInstanceWithCachedButton.click({ timeout: 30000 });
114
125
  }
115
126
  async waitForInstanceDetailsToBeLoaded() {
116
- const maxRetries = 2;
117
- let attempts = 0;
118
- while (attempts < maxRetries) {
119
- try {
120
- await (0, test_1.expect)(this.page.getByText(/process instance key/i)).toBeVisible({
121
- timeout: maxWaitTimeSeconds,
122
- });
123
- await (0, test_1.expect)(this.page.getByText(/This process instance has no variables/i)).toBeVisible({
124
- timeout: maxWaitTimeSeconds,
125
- });
126
- return;
127
- }
128
- catch (error) {
129
- if (attempts >= maxRetries - 1)
130
- throw error;
131
- await this.page.reload();
132
- attempts++;
133
- }
134
- }
127
+ // Do NOT use page.reload() — it destroys Play's embedded context.
128
+ await (0, test_1.expect)(this.page.getByText(/process instance key/i)).toBeVisible({
129
+ timeout: maxWaitTimeSeconds,
130
+ });
131
+ await (0, test_1.expect)(this.page.getByText(/This process instance has no variables/i)).toBeVisible({
132
+ timeout: maxWaitTimeSeconds,
133
+ });
135
134
  }
136
135
  async waitForNextElementToBeActive(historyItem) {
137
136
  const locator = this.page.getByText(new RegExp(`^${historyItem}`, 'i'));
138
- const maxRetries = 6; // ~1 min with the waits below
139
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
140
- try {
141
- await (0, test_1.expect)(locator.first()).toBeVisible({ timeout: 20000 });
142
- return;
143
- }
144
- catch (e) {
145
- if (attempt === maxRetries)
146
- throw e;
147
- await this.page.reload();
148
- await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
149
- await this.page.waitForTimeout(5000);
150
- }
151
- }
137
+ // Do NOT use page.reload() here Play is embedded in the modeler and
138
+ // reloading destroys the Play instance context, making the diagram
139
+ // permanently invisible. Use a long timeout instead, consistent with
140
+ // waitForCompleteJobButtonToBeAvailable.
141
+ await (0, test_1.expect)(locator.first()).toBeVisible({ timeout: maxWaitTimeSeconds });
152
142
  }
153
143
  async waitForProcessToBeCompleted() {
144
+ // Do NOT use page.reload() — it destroys Play's embedded context.
154
145
  await (0, test_1.expect)(this.page.getByText('Completed')).toBeVisible({
155
146
  timeout: maxWaitTimeSeconds,
156
147
  });
@@ -171,6 +162,7 @@ class PlayPage {
171
162
  }
172
163
  }
173
164
  async clickViewScenarioButton() {
165
+ await this.viewScenarioButton.waitFor({ state: 'visible', timeout: 30000 });
174
166
  await this.viewScenarioButton.click();
175
167
  }
176
168
  async enterScenarioName(scenarioName) {
@@ -192,6 +184,10 @@ class PlayPage {
192
184
  await this.viewAllScenariosButton.click();
193
185
  }
194
186
  async confirmSaveScenario() {
187
+ await this.confirmSaveScenarioButton.waitFor({
188
+ state: 'visible',
189
+ timeout: 10000,
190
+ });
195
191
  await this.confirmSaveScenarioButton.click();
196
192
  }
197
193
  async getDeleteIconForScenario(scenarioName) {
@@ -202,12 +198,21 @@ class PlayPage {
202
198
  }
203
199
  async deleteScenario(scenarioName) {
204
200
  const deleteIcon = await this.getDeleteIconForScenario(scenarioName);
201
+ await deleteIcon.waitFor({ state: 'visible', timeout: 10000 });
205
202
  await deleteIcon.click();
206
203
  }
207
204
  async confirmDeleteScenario() {
205
+ await this.confirmDeleteScenarioButton.waitFor({
206
+ state: 'visible',
207
+ timeout: 10000,
208
+ });
208
209
  await this.confirmDeleteScenarioButton.click();
209
210
  }
210
211
  async clickRunAllScenariosButton() {
212
+ await this.runAllScenariosButton.waitFor({
213
+ state: 'visible',
214
+ timeout: 30000,
215
+ });
211
216
  await this.runAllScenariosButton.click();
212
217
  }
213
218
  async clickmessagePublishButton() {
@@ -221,8 +226,9 @@ class PlayPage {
221
226
  await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.page
222
227
  .locator('tr', { hasText: scenarioName })
223
228
  .locator('text=Completed'), {
224
- totalTimeout: 90000,
225
- visibilityTimeout: 20000,
229
+ totalTimeout: 120000,
230
+ visibilityTimeout: 30000,
231
+ maxRetries: 5,
226
232
  postAction: async () => {
227
233
  if (await this.retryButton.isVisible()) {
228
234
  await this.retryButton.click();
@@ -4,6 +4,7 @@ const test_1 = require("@playwright/test");
4
4
  const SM_8_10_1 = require("../../fixtures/SM-8.10");
5
5
  const _setup_1 = require("../../test-setup.js");
6
6
  const sleep_1 = require("../../utils/sleep");
7
+ const UtilitiesPage_1 = require("../../pages/SM-8.10/UtilitiesPage");
7
8
  SM_8_10_1.test.describe.configure({ mode: 'parallel' });
8
9
  SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
9
10
  SM_8_10_1.test.beforeEach(async ({ navigationPage }, testInfo) => {
@@ -13,49 +14,15 @@ SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
13
14
  await (0, _setup_1.captureScreenshot)(page, testInfo);
14
15
  await (0, _setup_1.captureFailureVideo)(page, testInfo);
15
16
  });
16
- (0, SM_8_10_1.test)('User Tasks and Service Task', async ({ modelerHomePage, modelerCreatePage, playPage, }) => {
17
+ (0, SM_8_10_1.test)('User Tasks and Service Task', async ({ page, modelerHomePage, modelerCreatePage, playPage, }) => {
17
18
  SM_8_10_1.test.slow();
18
19
  const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
19
20
  const processName = 'Play_Test_Process' + randomString;
20
21
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
21
22
  await modelerHomePage.clickCrossComponentProjectFolder();
22
23
  });
23
- await SM_8_10_1.test.step('Add A BPMN Template To The Project', async () => {
24
- await modelerHomePage.clickDiagramTypeDropdown();
25
- await modelerHomePage.clickBpmnTemplateOption();
26
- });
27
24
  await SM_8_10_1.test.step('Create a BPMN Diagram with user tasks and service task', async () => {
28
- await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
29
- timeout: 120000,
30
- });
31
- await modelerCreatePage.enterDiagramName(processName);
32
- await (0, sleep_1.sleep)(2000);
33
- // Add a user task with Zeebe user task implementation
34
- await modelerCreatePage.clickAppendElementButton();
35
- await modelerCreatePage.clickAppendTaskButton();
36
- await modelerCreatePage.clickChangeTypeButton();
37
- await modelerCreatePage.clickUserTaskOption();
38
- await modelerCreatePage.chooseImplementationOption('zeebeUserTask');
39
- await modelerCreatePage.clickGeneralPropertiesPanel();
40
- await modelerCreatePage.clickElemendIdInput();
41
- await modelerCreatePage.fillElementIdInput('zeebe-user-task' + randomString);
42
- await (0, sleep_1.sleep)(1000);
43
- // Add a service task
44
- await modelerCreatePage.clickAppendElementButton();
45
- await modelerCreatePage.clickAppendTaskButton();
46
- await modelerCreatePage.clickChangeTypeButton();
47
- await modelerCreatePage.clickServiceTaskOption();
48
- await modelerCreatePage.clickGeneralPropertiesPanel();
49
- await modelerCreatePage.clickElemendIdInput();
50
- await modelerCreatePage.fillElementIdInput('service-task' + randomString);
51
- await modelerCreatePage.clickTaskDefinitionPropertiesPanel();
52
- await modelerCreatePage.clickJobTypeInput();
53
- await modelerCreatePage.fillJobTypeInput('someJob' + randomString);
54
- await (0, sleep_1.sleep)(1000);
55
- // Add end event
56
- await modelerCreatePage.clickAppendElementButton();
57
- await modelerCreatePage.clickAppendEndEventButton();
58
- await (0, sleep_1.sleep)(2000);
25
+ await (0, UtilitiesPage_1.modelDiagramFromFile)(page, modelerHomePage, modelerCreatePage, processName, 'Play_Test_User_Service_Task');
59
26
  });
60
27
  await SM_8_10_1.test.step('Open Play', async () => {
61
28
  await modelerCreatePage.switchToPlay();
@@ -65,10 +32,10 @@ SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
65
32
  await playPage.dismissStartModal();
66
33
  await playPage.clickStartInstanceButton();
67
34
  await playPage.waitForInstanceDetailsToBeLoaded();
68
- await playPage.waitForNextElementToBeActive('zeebe-user-task' + randomString);
35
+ await playPage.waitForNextElementToBeActive('play-user-task');
69
36
  await playPage.waitForCompleteJobButtonToBeAvailable();
70
37
  await playPage.clickCompleteJobButton();
71
- await playPage.waitForNextElementToBeActive('service-task' + randomString);
38
+ await playPage.waitForNextElementToBeActive('play-service-task');
72
39
  await playPage.waitForCompleteJobButtonToBeAvailable();
73
40
  await playPage.clickCompleteJobButton();
74
41
  await playPage.waitForProcessToBeCompleted();
@@ -96,7 +63,11 @@ SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
96
63
  await modelerCreatePage.clickSecondPlacedGateway();
97
64
  await modelerCreatePage.clickAppendElementButton();
98
65
  await modelerCreatePage.clickAppendEndEventButton('parallelGateway');
99
- await (0, sleep_1.sleep)(5000);
66
+ await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
67
+ timeout: 30000,
68
+ });
69
+ // Wait for modeler background auto-save to complete
70
+ await (0, sleep_1.sleep)(2000);
100
71
  });
101
72
  await SM_8_10_1.test.step('Open Play', async () => {
102
73
  await modelerCreatePage.switchToPlay();
@@ -113,17 +84,23 @@ SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
113
84
  await playPage.clickSaveScenarioButton();
114
85
  await playPage.enterScenarioName(scenarioName);
115
86
  await playPage.confirmSaveScenario();
116
- await (0, sleep_1.sleep)(2000);
87
+ await (0, test_1.expect)(playPage.saveScenarioModal).toBeHidden({ timeout: 10000 });
117
88
  });
118
89
  await SM_8_10_1.test.step('Update the saved scenario', async () => {
119
90
  await modelerCreatePage.switchToImplementTab();
120
- await (0, sleep_1.sleep)(2000);
91
+ await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
92
+ timeout: 30000,
93
+ });
121
94
  await modelerCreatePage.clickFirstPlacedGateway();
122
95
  await modelerCreatePage.clickAppendElementButton();
123
96
  await modelerCreatePage.clickAppendTaskButton();
124
97
  await modelerCreatePage.clickConnectToOtherElementButton();
125
98
  await modelerCreatePage.clickSecondPlacedGateway();
126
- await (0, sleep_1.sleep)(5000);
99
+ await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
100
+ timeout: 30000,
101
+ });
102
+ // Wait for modeler background auto-save to complete
103
+ await (0, sleep_1.sleep)(2000);
127
104
  await modelerCreatePage.switchToPlay();
128
105
  // After diagram modification, Play may show a "Continue" button
129
106
  // to redeploy, or it may show the diagram directly. Try clicking
@@ -153,7 +130,9 @@ SM_8_10_1.test.describe('Deploy and run a process in Play', () => {
153
130
  await SM_8_10_1.test.step('Delete test scenario', async () => {
154
131
  await playPage.deleteScenario(scenarioName);
155
132
  await playPage.confirmDeleteScenario();
156
- await (0, test_1.expect)(playPage.getScenarioRow(scenarioName)).toHaveCount(0);
133
+ await (0, test_1.expect)(playPage.getScenarioRow(scenarioName)).toHaveCount(0, {
134
+ timeout: 10000,
135
+ });
157
136
  });
158
137
  });
159
138
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.483",
3
+ "version": "0.0.484",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler" exporterVersion="ff1274a" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.10.0">
3
+ <bpmn:process id="Play_Test_User_Service_Task" name="Play_Test_User_Service_Task" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1">
5
+ <bpmn:outgoing>Flow_1</bpmn:outgoing>
6
+ </bpmn:startEvent>
7
+ <bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="play-user-task" />
8
+ <bpmn:userTask id="play-user-task" name="play-user-task">
9
+ <bpmn:extensionElements>
10
+ <zeebe:userTask />
11
+ </bpmn:extensionElements>
12
+ <bpmn:incoming>Flow_1</bpmn:incoming>
13
+ <bpmn:outgoing>Flow_2</bpmn:outgoing>
14
+ </bpmn:userTask>
15
+ <bpmn:sequenceFlow id="Flow_2" sourceRef="play-user-task" targetRef="play-service-task" />
16
+ <bpmn:serviceTask id="play-service-task" name="play-service-task">
17
+ <bpmn:extensionElements>
18
+ <zeebe:taskDefinition type="play-job-type" />
19
+ </bpmn:extensionElements>
20
+ <bpmn:incoming>Flow_2</bpmn:incoming>
21
+ <bpmn:outgoing>Flow_3</bpmn:outgoing>
22
+ </bpmn:serviceTask>
23
+ <bpmn:endEvent id="EndEvent_1">
24
+ <bpmn:incoming>Flow_3</bpmn:incoming>
25
+ </bpmn:endEvent>
26
+ <bpmn:sequenceFlow id="Flow_3" sourceRef="play-service-task" targetRef="EndEvent_1" />
27
+ </bpmn:process>
28
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
29
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Play_Test_User_Service_Task">
30
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
31
+ <dc:Bounds x="150" y="100" width="36" height="36" />
32
+ </bpmndi:BPMNShape>
33
+ <bpmndi:BPMNShape id="Activity_UserTask_di" bpmnElement="play-user-task">
34
+ <dc:Bounds x="240" y="78" width="100" height="80" />
35
+ </bpmndi:BPMNShape>
36
+ <bpmndi:BPMNShape id="Activity_ServiceTask_di" bpmnElement="play-service-task">
37
+ <dc:Bounds x="400" y="78" width="100" height="80" />
38
+ </bpmndi:BPMNShape>
39
+ <bpmndi:BPMNShape id="Event_EndEvent_di" bpmnElement="EndEvent_1">
40
+ <dc:Bounds x="562" y="100" width="36" height="36" />
41
+ </bpmndi:BPMNShape>
42
+ <bpmndi:BPMNEdge id="Flow_1_di" bpmnElement="Flow_1">
43
+ <di:waypoint x="186" y="118" />
44
+ <di:waypoint x="240" y="118" />
45
+ </bpmndi:BPMNEdge>
46
+ <bpmndi:BPMNEdge id="Flow_2_di" bpmnElement="Flow_2">
47
+ <di:waypoint x="340" y="118" />
48
+ <di:waypoint x="400" y="118" />
49
+ </bpmndi:BPMNEdge>
50
+ <bpmndi:BPMNEdge id="Flow_3_di" bpmnElement="Flow_3">
51
+ <di:waypoint x="500" y="118" />
52
+ <di:waypoint x="562" y="118" />
53
+ </bpmndi:BPMNEdge>
54
+ </bpmndi:BPMNPlane>
55
+ </bpmndi:BPMNDiagram>
56
+ </bpmn:definitions>