@camunda/e2e-test-suite 0.0.148 → 0.0.150

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.
@@ -70,6 +70,7 @@ declare class ModelerCreatePage {
70
70
  readonly additionalActionsButton: Locator;
71
71
  readonly closeModalButton: Locator;
72
72
  readonly deployErrorMessage: Locator;
73
+ readonly implementTab: Locator;
73
74
  readonly bpmnReplaceMenu: Locator;
74
75
  readonly connectorsDocHandlingStartEventElement: Locator;
75
76
  readonly startEventVariableInputWithThreeVariables: Locator;
@@ -177,6 +178,10 @@ declare class ModelerCreatePage {
177
178
  fillTimerValue(value: string): Promise<void>;
178
179
  clickEighthPlacedElement(): Promise<void>;
179
180
  assertNameInput(processName: string): Promise<void>;
181
+ switchToImplementTab(): Promise<void>;
182
+ clickStartEvent(): Promise<void>;
183
+ clickContinueToPlay(): Promise<void>;
184
+ assertScenarioNameVisible(scenarioName: string): Promise<void>;
180
185
  fillStartEventVariablesForDocHandling(zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string): Promise<void>;
181
186
  fillZeebeClientId(clientId: string): Promise<void>;
182
187
  fillZeebeSecretValue(zeebeSecret: string): Promise<void>;
@@ -75,6 +75,7 @@ class ModelerCreatePage {
75
75
  additionalActionsButton;
76
76
  closeModalButton;
77
77
  deployErrorMessage;
78
+ implementTab;
78
79
  bpmnReplaceMenu;
79
80
  connectorsDocHandlingStartEventElement;
80
81
  startEventVariableInputWithThreeVariables;
@@ -216,6 +217,7 @@ class ModelerCreatePage {
216
217
  .getByRole('dialog')
217
218
  .getByRole('button', { name: 'Close' });
218
219
  this.deployErrorMessage = page.getByText('The diagram failed to deploy & run');
220
+ this.implementTab = page.getByRole('tab', { name: 'Implement' });
219
221
  this.bpmnReplaceMenu = page.getByTestId('bpmn-replace');
220
222
  this.connectorsDocHandlingStartEventElement = page.locator('g:nth-child(5) > .djs-element > .djs-hit');
221
223
  this.startEventVariableInputWithThreeVariables =
@@ -729,7 +731,12 @@ class ModelerCreatePage {
729
731
  (0, test_1.expect)(await this.implementationOptions.inputValue()).toEqual(implementationType);
730
732
  }
731
733
  async chooseImplementationOption(implementationType) {
732
- await this.implementationSection.click();
734
+ // Wait for implementation section to be attached and stable after task type change
735
+ await this.implementationSection.waitFor({
736
+ state: 'attached',
737
+ timeout: 10000,
738
+ });
739
+ await this.implementationSection.click({ timeout: 30000 });
733
740
  if ((await this.implementationOptions.inputValue()) == implementationType) {
734
741
  console.log(`${implementationType} is already selected.`);
735
742
  }
@@ -941,6 +948,18 @@ class ModelerCreatePage {
941
948
  await (0, test_1.expect)(this.nameInput).toHaveValue(processName);
942
949
  }
943
950
  }
951
+ async switchToImplementTab() {
952
+ await this.implementTab.click({ timeout: 30000 });
953
+ }
954
+ async clickStartEvent() {
955
+ await this.startEventElement.click({ timeout: 30000 });
956
+ }
957
+ async clickContinueToPlay() {
958
+ await this.continueToPlayButton.click({ timeout: 30000 });
959
+ }
960
+ async assertScenarioNameVisible(scenarioName) {
961
+ await (0, test_1.expect)(this.page.getByTestId('instance-header').getByText(scenarioName)).toBeVisible();
962
+ }
944
963
  async fillStartEventVariablesForDocHandling(zeebeUrl, zeebeClientId, zeebeClientSecret) {
945
964
  console.log(`URL: ${zeebeUrl}, ClientId: ${zeebeClientId}, Secret: ${zeebeClientSecret}`);
946
965
  (0, test_1.expect)(this.connectorsDocHandlingStartEventElement).toBeVisible({
@@ -2,13 +2,40 @@ import { Page, Locator } from '@playwright/test';
2
2
  declare class PlayPage {
3
3
  private page;
4
4
  readonly completeJobButton: Locator;
5
+ readonly saveScenarioButton: Locator;
6
+ readonly viewScenarioButton: Locator;
7
+ readonly runAllScenariosButton: Locator;
8
+ readonly confirmSaveScenarioButton: Locator;
9
+ readonly enterScenarioNameInput: Locator;
10
+ readonly confirmDeleteScenarioButton: Locator;
11
+ readonly viewAllScenariosButton: Locator;
12
+ readonly getScenarioRowByName: (scenarioName: string) => Locator;
13
+ readonly getScenarioRow: (scenarioName: string) => Locator;
14
+ readonly diagram: Locator;
15
+ readonly startInstanceButton: Locator;
16
+ readonly startInstanceWithCachedButton: Locator;
17
+ readonly notifications: Locator;
18
+ readonly saveScenarioModal: Locator;
5
19
  constructor(page: Page);
6
20
  waitForCompleteJobButtonToBeAvailable(): Promise<void>;
7
21
  clickCompleteJobButton(): Promise<void>;
8
22
  clickStartInstanceButton(): Promise<void>;
9
23
  dismissStartModal(): Promise<void>;
24
+ clickStartInstanceWithCachedButton(): Promise<void>;
10
25
  waitForInstanceDetailsToBeLoaded(): Promise<void>;
11
26
  waitForNextElementToBeActive(historyItem: string): Promise<void>;
12
27
  waitForProcessToBeCompleted(): Promise<void>;
28
+ clickSaveScenarioButton(): Promise<void>;
29
+ clickViewScenarioButton(): Promise<void>;
30
+ enterScenarioName(scenarioName: string): Promise<void>;
31
+ updateScenarioName(newScenarioName: string): Promise<void>;
32
+ clickViewAllScenariosButton(): Promise<void>;
33
+ confirmSaveScenario(): Promise<void>;
34
+ getDeleteIconForScenario(scenarioName: string): Promise<Locator>;
35
+ deleteScenario(scenarioName: string): Promise<void>;
36
+ confirmDeleteScenario(): Promise<void>;
37
+ clickRunAllScenariosButton(): Promise<void>;
38
+ clickmessagePublishButton(): Promise<void>;
39
+ assertScenarioCompleted(scenarioName: string): Promise<void>;
13
40
  }
14
41
  export { PlayPage };
@@ -2,15 +2,57 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PlayPage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
+ const sleep_1 = require("../../utils/sleep");
5
6
  const maxWaitTimeSeconds = 180000;
6
7
  class PlayPage {
7
8
  page;
8
9
  completeJobButton;
10
+ saveScenarioButton;
11
+ viewScenarioButton;
12
+ runAllScenariosButton;
13
+ confirmSaveScenarioButton;
14
+ enterScenarioNameInput;
15
+ confirmDeleteScenarioButton;
16
+ viewAllScenariosButton;
17
+ getScenarioRowByName;
18
+ getScenarioRow;
19
+ diagram;
20
+ startInstanceButton;
21
+ startInstanceWithCachedButton;
22
+ notifications;
23
+ saveScenarioModal;
9
24
  constructor(page) {
10
25
  this.page = page;
11
26
  this.completeJobButton = page
12
27
  .getByTestId('diagram')
13
28
  .getByLabel('Complete job');
29
+ this.saveScenarioButton = page.getByRole('button', { name: 'Save scenario' });
30
+ this.viewScenarioButton = page.getByRole('button', { name: 'View scenario' });
31
+ this.runAllScenariosButton = page.getByRole('button', {
32
+ name: 'Run all scenarios',
33
+ });
34
+ this.confirmSaveScenarioButton = page
35
+ .getByTestId('save-scenario-modal')
36
+ .getByRole('button', { name: 'Save' });
37
+ this.enterScenarioNameInput = page
38
+ .getByTestId('save-scenario-modal')
39
+ .locator('input#scenario-name')
40
+ .first();
41
+ this.confirmDeleteScenarioButton = page.getByRole('button', {
42
+ name: 'danger Delete',
43
+ });
44
+ this.viewAllScenariosButton = page.getByRole('button', {
45
+ name: '(View all)',
46
+ });
47
+ this.getScenarioRowByName = (scenarioName) => page.locator('tr', { hasText: scenarioName });
48
+ this.getScenarioRow = (scenarioName) => page.locator('tr', { hasText: scenarioName });
49
+ this.diagram = page.getByTestId('diagram');
50
+ this.startInstanceButton = this.diagram.getByLabel('Start instance', {
51
+ exact: true,
52
+ });
53
+ this.startInstanceWithCachedButton = page.getByLabel('Start instance with cached');
54
+ this.notifications = page.locator('.cds--toast-notification');
55
+ this.saveScenarioModal = page.getByTestId('save-scenario-modal');
14
56
  }
15
57
  async waitForCompleteJobButtonToBeAvailable() {
16
58
  await (0, test_1.expect)(this.completeJobButton).toBeVisible({
@@ -21,17 +63,43 @@ class PlayPage {
21
63
  await this.completeJobButton.click();
22
64
  }
23
65
  async clickStartInstanceButton() {
24
- await this.page
25
- .getByTestId('diagram')
26
- .getByLabel('Start instance', { exact: true })
27
- .click();
66
+ await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
67
+ const maxRetries = 3;
68
+ let attempts = 0;
69
+ while (attempts < maxRetries) {
70
+ try {
71
+ await this.startInstanceButton.click({ timeout: 30000 });
72
+ return;
73
+ }
74
+ catch (error) {
75
+ if (attempts >= maxRetries - 1)
76
+ throw error;
77
+ await this.page.reload();
78
+ await (0, sleep_1.sleep)(2000);
79
+ attempts++;
80
+ }
81
+ }
28
82
  }
29
83
  async dismissStartModal() {
30
- await this.page
31
- .getByRole('button', {
32
- name: 'Start a process instance',
33
- })
34
- .click();
84
+ const buttonVariations = [
85
+ 'Start a process instance',
86
+ 'Start another instance',
87
+ 'Start new instance',
88
+ 'Start instance',
89
+ ];
90
+ for (const buttonName of buttonVariations) {
91
+ const button = this.page.getByRole('button', { name: buttonName });
92
+ const count = await button.count();
93
+ if (count > 0) {
94
+ await button.click();
95
+ return;
96
+ }
97
+ }
98
+ throw new Error('Could not find start instance button with any expected variation');
99
+ }
100
+ async clickStartInstanceWithCachedButton() {
101
+ await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
102
+ await this.startInstanceWithCachedButton.click({ timeout: 30000 });
35
103
  }
36
104
  async waitForInstanceDetailsToBeLoaded() {
37
105
  const maxRetries = 2;
@@ -64,5 +132,65 @@ class PlayPage {
64
132
  timeout: maxWaitTimeSeconds,
65
133
  });
66
134
  }
135
+ async clickSaveScenarioButton() {
136
+ await this.notifications
137
+ .first()
138
+ .waitFor({ state: 'hidden', timeout: 15000 })
139
+ .catch(() => { });
140
+ const isModalVisible = await this.saveScenarioModal
141
+ .isVisible()
142
+ .catch(() => false);
143
+ if (!isModalVisible) {
144
+ await this.saveScenarioButton.click({ force: true, timeout: 30000 });
145
+ }
146
+ }
147
+ async clickViewScenarioButton() {
148
+ await this.viewScenarioButton.click();
149
+ }
150
+ async enterScenarioName(scenarioName) {
151
+ const modal = this.page.locator('[data-testid="save-scenario-modal"].is-visible');
152
+ await modal.waitFor({ state: 'visible', timeout: 10000 });
153
+ const input = modal.locator('input#scenario-name');
154
+ await input.waitFor({ state: 'visible', timeout: 10000 });
155
+ await input.clear();
156
+ await input.fill(scenarioName);
157
+ }
158
+ async updateScenarioName(newScenarioName) {
159
+ await this.enterScenarioNameInput.fill(newScenarioName);
160
+ }
161
+ async clickViewAllScenariosButton() {
162
+ await this.viewAllScenariosButton.click();
163
+ }
164
+ async confirmSaveScenario() {
165
+ await this.confirmSaveScenarioButton.click();
166
+ }
167
+ async getDeleteIconForScenario(scenarioName) {
168
+ const scenarioRow = this.page
169
+ .locator('tr')
170
+ .filter({ has: this.page.getByText(scenarioName, { exact: true }) });
171
+ return scenarioRow.getByLabel('Delete scenario');
172
+ }
173
+ async deleteScenario(scenarioName) {
174
+ const deleteIcon = await this.getDeleteIconForScenario(scenarioName);
175
+ await deleteIcon.click();
176
+ }
177
+ async confirmDeleteScenario() {
178
+ await this.confirmDeleteScenarioButton.click();
179
+ }
180
+ async clickRunAllScenariosButton() {
181
+ await this.runAllScenariosButton.click();
182
+ }
183
+ async clickmessagePublishButton() {
184
+ await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
185
+ const publishIcon = this.diagram
186
+ .locator('div.djs-overlays')
187
+ .getByLabel('Publish message', { exact: true });
188
+ await publishIcon.click({ timeout: 30000 });
189
+ }
190
+ async assertScenarioCompleted(scenarioName) {
191
+ await (0, test_1.expect)(this.page
192
+ .locator('tr', { hasText: scenarioName })
193
+ .locator('text=Completed')).toBeVisible({ timeout: 30000 });
194
+ }
67
195
  }
68
196
  exports.PlayPage = PlayPage;
@@ -29,7 +29,7 @@ SM_8_9_1.test.describe('Deploy and run a process in Play', () => {
29
29
  timeout: 120000,
30
30
  });
31
31
  await modelerCreatePage.enterDiagramName(processName);
32
- await (0, sleep_1.sleep)(10000);
32
+ await (0, sleep_1.sleep)(2000);
33
33
  // Add a user task with Zeebe user task implementation
34
34
  await modelerCreatePage.clickAppendElementButton();
35
35
  await modelerCreatePage.clickAppendTaskButton();
@@ -55,7 +55,7 @@ SM_8_9_1.test.describe('Deploy and run a process in Play', () => {
55
55
  // Add end event
56
56
  await modelerCreatePage.clickAppendElementButton();
57
57
  await modelerCreatePage.clickAppendEndEventButton();
58
- await (0, sleep_1.sleep)(30000);
58
+ await (0, sleep_1.sleep)(2000);
59
59
  });
60
60
  await SM_8_9_1.test.step('Open Play', async () => {
61
61
  await modelerCreatePage.switchToPlay();
@@ -74,4 +74,79 @@ SM_8_9_1.test.describe('Deploy and run a process in Play', () => {
74
74
  await playPage.waitForProcessToBeCompleted();
75
75
  });
76
76
  });
77
+ (0, SM_8_9_1.test)('Create,update and delete test scenarios in play', async ({ modelerHomePage, modelerCreatePage, playPage, }) => {
78
+ SM_8_9_1.test.slow();
79
+ const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
80
+ const processName = 'Play_Test_Process' + randomString;
81
+ await SM_8_9_1.test.step('Open Cross Component Test Project', async () => {
82
+ await modelerHomePage.clickCrossComponentProjectFolder();
83
+ });
84
+ await SM_8_9_1.test.step('Add A BPMN Template To The Project', async () => {
85
+ await modelerHomePage.clickDiagramTypeDropdown();
86
+ await modelerHomePage.clickBpmnTemplateOption();
87
+ });
88
+ await SM_8_9_1.test.step('Create a BPMN Diagram with simple start and end event', async () => {
89
+ await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
90
+ timeout: 120000,
91
+ });
92
+ await modelerCreatePage.enterDiagramName(processName);
93
+ await (0, sleep_1.sleep)(2000);
94
+ await modelerCreatePage.clickAppendElementButton();
95
+ await modelerCreatePage.clickAppendEndEventButton();
96
+ await (0, sleep_1.sleep)(2000);
97
+ });
98
+ await SM_8_9_1.test.step('Open Play', async () => {
99
+ await modelerCreatePage.switchToPlay();
100
+ await modelerCreatePage.completePlayConfiguration();
101
+ });
102
+ await SM_8_9_1.test.step('Start and complete the process instance in Play and save scenario', async () => {
103
+ await playPage.dismissStartModal();
104
+ await playPage.clickStartInstanceButton();
105
+ await playPage.waitForInstanceDetailsToBeLoaded();
106
+ await playPage.waitForProcessToBeCompleted();
107
+ await playPage.clickSaveScenarioButton();
108
+ await playPage.enterScenarioName('My first scenario');
109
+ await playPage.confirmSaveScenario();
110
+ await (0, sleep_1.sleep)(2000);
111
+ });
112
+ await SM_8_9_1.test.step('Update the saved scenario', async () => {
113
+ await modelerCreatePage.switchToImplementTab();
114
+ await (0, sleep_1.sleep)(2000);
115
+ await modelerCreatePage.clickStartEvent();
116
+ await modelerCreatePage.hoverOnStartEvent();
117
+ await modelerCreatePage.clickAppendTaskButton();
118
+ await modelerCreatePage.clickChangeTypeButton();
119
+ await modelerCreatePage.clickUserTaskOption();
120
+ await modelerCreatePage.chooseImplementationOption('zeebeUserTask');
121
+ await modelerCreatePage.clickGeneralPropertiesPanel();
122
+ await modelerCreatePage.clickElemendIdInput();
123
+ await modelerCreatePage.fillElementIdInput('zeebe-user-task' + randomString);
124
+ await (0, sleep_1.sleep)(2000);
125
+ await modelerCreatePage.clickAppendElementButton();
126
+ await modelerCreatePage.clickAppendEndEventButton();
127
+ await modelerCreatePage.switchToPlay();
128
+ await modelerCreatePage.clickContinueToPlay();
129
+ await (0, sleep_1.sleep)(2000);
130
+ await playPage.clickStartInstanceWithCachedButton();
131
+ await playPage.waitForNextElementToBeActive('zeebe-user-task' + randomString);
132
+ await playPage.waitForCompleteJobButtonToBeAvailable();
133
+ await playPage.clickCompleteJobButton();
134
+ await playPage.waitForProcessToBeCompleted();
135
+ await playPage.clickSaveScenarioButton();
136
+ await playPage.enterScenarioName('My first scenario-updated');
137
+ await playPage.confirmSaveScenario();
138
+ await modelerCreatePage.assertScenarioNameVisible('My first scenario-updated');
139
+ });
140
+ await SM_8_9_1.test.step('Run all scenarios', async () => {
141
+ await playPage.clickViewAllScenariosButton();
142
+ await playPage.clickRunAllScenariosButton();
143
+ await playPage.assertScenarioCompleted('My first scenario');
144
+ await playPage.assertScenarioCompleted('My first scenario-updated');
145
+ });
146
+ await SM_8_9_1.test.step('Delete test scenario', async () => {
147
+ await playPage.deleteScenario('My first scenario');
148
+ await playPage.confirmDeleteScenario();
149
+ await (0, test_1.expect)(playPage.getScenarioRow('My first scenario')).toHaveCount(0);
150
+ });
151
+ });
77
152
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.148",
3
+ "version": "0.0.150",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",