@camunda/e2e-test-suite 0.0.1287 → 0.0.1288
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.
- package/dist/pages/8.9/AppsPage.d.ts +9 -3
- package/dist/pages/8.9/AppsPage.js +262 -47
- package/dist/pages/8.9/ClusterDetailsPage.d.ts +5 -0
- package/dist/pages/8.9/ClusterDetailsPage.js +92 -9
- package/dist/pages/8.9/ClusterSecretsPage.js +5 -1
- package/dist/pages/8.9/ConnectorMarketplacePage.d.ts +1 -0
- package/dist/pages/8.9/ConnectorMarketplacePage.js +46 -3
- package/dist/pages/8.9/ConsoleOrganizationPage.d.ts +3 -2
- package/dist/pages/8.9/ConsoleOrganizationPage.js +47 -22
- package/dist/pages/8.9/FormJsPage.d.ts +4 -0
- package/dist/pages/8.9/FormJsPage.js +53 -19
- package/dist/pages/8.9/IdpCreatePage.js +5 -0
- package/dist/pages/8.9/ModelerCreatePage.d.ts +5 -0
- package/dist/pages/8.9/ModelerCreatePage.js +153 -21
- package/dist/pages/8.9/ModelerHomePage.d.ts +1 -0
- package/dist/pages/8.9/ModelerHomePage.js +29 -4
- package/dist/pages/8.9/PlayPage.js +11 -1
- package/dist/pages/8.9/ProcessApplicationPage.js +48 -4
- package/dist/pages/8.9/UtilitiesPage.js +57 -17
- package/dist/pages/8.9/WorkspaceMembersPage.d.ts +21 -0
- package/dist/pages/8.9/WorkspaceMembersPage.js +264 -0
- package/dist/tests/8.9/access-user-role-management.spec.js +111 -26
- package/dist/tests/8.9/console-user-flows.spec.js +4 -4
- package/dist/tests/8.9/idp-user-flows.spec.js +2 -1
- package/dist/tests/8.9/rba-enabled-v1-user-flows.spec.js +13 -4
- package/dist/tests/8.9/rba-enabled-v2-user-flows.spec.js +13 -4
- package/dist/tests/8.9/test-setup.spec.js +57 -4
- package/dist/tests/8.9/utr-enabled-user-flows.spec.js +18 -0
- package/dist/tests/8.9/web-modeler-user-flows.spec.js +6 -2
- package/dist/utils/consoleApiHelpers.d.ts +2 -0
- package/dist/utils/consoleApiHelpers.js +50 -4
- package/dist/utils/resetSession.js +6 -1
- package/package.json +1 -1
|
@@ -301,7 +301,11 @@ class ClusterSecretsPage {
|
|
|
301
301
|
timeout: 60000,
|
|
302
302
|
});
|
|
303
303
|
await this.page.reload();
|
|
304
|
-
|
|
304
|
+
// Hub keeps the selected cluster tab out of the URL, so the reload lands
|
|
305
|
+
// on Overview, where assertSecretsOrCreate finds no search box and tries
|
|
306
|
+
// to create every secret. Re-select the tab, as pages/8.8 does (45eae7b).
|
|
307
|
+
await this.clusterSecretTab.first().click({ timeout: 60000 });
|
|
308
|
+
await (0, test_1.expect)(this.createNewSecretButton).toBeVisible({ timeout: 60000 });
|
|
305
309
|
}
|
|
306
310
|
}
|
|
307
311
|
exports.ClusterSecretsPage = ClusterSecretsPage;
|
|
@@ -8,6 +8,7 @@ declare class ConnectorMarketplacePage {
|
|
|
8
8
|
readonly replaceResourceButton: Locator;
|
|
9
9
|
readonly addToProjectButton: Locator;
|
|
10
10
|
readonly cancelButton: Locator;
|
|
11
|
+
readonly browseAllMarketplaceDetailsButton: Locator;
|
|
11
12
|
constructor(page: Page);
|
|
12
13
|
clickSearchForConnectorTextbox(): Promise<void>;
|
|
13
14
|
fillSearchForConnectorTextbox(connectorName: string): Promise<void>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConnectorMarketplacePage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
4
5
|
class ConnectorMarketplacePage {
|
|
5
6
|
page;
|
|
6
7
|
searchForConnectorTextbox;
|
|
@@ -10,9 +11,25 @@ class ConnectorMarketplacePage {
|
|
|
10
11
|
replaceResourceButton;
|
|
11
12
|
addToProjectButton;
|
|
12
13
|
cancelButton;
|
|
14
|
+
browseAllMarketplaceDetailsButton;
|
|
13
15
|
constructor(page) {
|
|
14
16
|
this.page = page;
|
|
15
|
-
|
|
17
|
+
// The legacy marketplace modal, or camunda-hub's "Browse all" dialog
|
|
18
|
+
// (BrowseAllDialog.tsx), which lists Marketplace connectors alongside the
|
|
19
|
+
// diagram's own elements and reusable assets. Same shape as pages/8.8.
|
|
20
|
+
this.searchForConnectorTextbox = page
|
|
21
|
+
.getByPlaceholder('Search for a connector')
|
|
22
|
+
.or(page.locator('#browse-all-search'))
|
|
23
|
+
.or(page.getByRole('searchbox', {
|
|
24
|
+
name: 'Search elements and reusable assets',
|
|
25
|
+
}))
|
|
26
|
+
.first();
|
|
27
|
+
// A Browse all Marketplace card opens its review step ("Add to project")
|
|
28
|
+
// through this button; self-hosted connectors only link to setup docs.
|
|
29
|
+
this.browseAllMarketplaceDetailsButton = page
|
|
30
|
+
.getByRole('list', { name: 'Marketplace connectors' })
|
|
31
|
+
.getByRole('button', { name: /^View details for .+ from Marketplace$/ })
|
|
32
|
+
.first();
|
|
16
33
|
this.downloadToProjectButton = page
|
|
17
34
|
.getByRole('button', { name: 'Download to project' })
|
|
18
35
|
.first();
|
|
@@ -45,7 +62,26 @@ class ConnectorMarketplacePage {
|
|
|
45
62
|
await this.replaceResourceButton.click({ timeout: 60000 });
|
|
46
63
|
}
|
|
47
64
|
async downloadConnectorToProject() {
|
|
48
|
-
|
|
65
|
+
// Browse all has no "Download to project": a result is a card that opens
|
|
66
|
+
// its own review step, which is where the import action lives. Wait for
|
|
67
|
+
// whichever entry point this shell renders before deciding.
|
|
68
|
+
await (0, test_1.expect)(this.downloadToProjectButton
|
|
69
|
+
.or(this.browseAllMarketplaceDetailsButton)
|
|
70
|
+
.first()).toBeVisible({ timeout: 60000 });
|
|
71
|
+
if (await this.downloadToProjectButton.isVisible()) {
|
|
72
|
+
await this.clickDownloadToProjectButton();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
await this.browseAllMarketplaceDetailsButton.click({ timeout: 30000 });
|
|
76
|
+
}
|
|
77
|
+
// The Browse all review step fetches the connector's details before it
|
|
78
|
+
// renders "Add to project"; let an outcome render before the 20s race.
|
|
79
|
+
await this.addToProjectButton
|
|
80
|
+
.or(this.replaceResourceButton)
|
|
81
|
+
.or(this.cancelButton)
|
|
82
|
+
.first()
|
|
83
|
+
.waitFor({ state: 'visible', timeout: 60000 })
|
|
84
|
+
.catch(() => { });
|
|
49
85
|
let imported = false;
|
|
50
86
|
try {
|
|
51
87
|
await Promise.race([
|
|
@@ -67,7 +103,14 @@ class ConnectorMarketplacePage {
|
|
|
67
103
|
await this.snackbar
|
|
68
104
|
.waitFor({ state: 'visible', timeout: 60000 })
|
|
69
105
|
.catch(() => { });
|
|
70
|
-
if
|
|
106
|
+
// Only close the marketplace if it is still open: a bare "Close"
|
|
107
|
+
// button otherwise matches the properties panel's own close (x) and
|
|
108
|
+
// collapses it, hiding the connector's "Input" tab (see pages/8.8).
|
|
109
|
+
const marketplaceStillOpen = await this.searchForConnectorTextbox
|
|
110
|
+
.isVisible()
|
|
111
|
+
.catch(() => false);
|
|
112
|
+
if (marketplaceStillOpen &&
|
|
113
|
+
(await this.closeButton.isVisible({ timeout: 5000 }).catch(() => false))) {
|
|
71
114
|
await this.closeButton.click({ timeout: 10000 });
|
|
72
115
|
}
|
|
73
116
|
}
|
|
@@ -45,8 +45,9 @@ declare class ConsoleOrganizationPage {
|
|
|
45
45
|
selectAnalystRole(username: string): Promise<void>;
|
|
46
46
|
selectModelerRole(username: string): Promise<void>;
|
|
47
47
|
selectAdminRole(username: string): Promise<void>;
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
private userOptionsButton;
|
|
49
|
+
clickOptionsButton(username: string): Promise<void>;
|
|
50
|
+
clickEditUserMenuItem(username: string): Promise<void>;
|
|
50
51
|
checkModelerCheckbox(): Promise<void>;
|
|
51
52
|
checkAdminCheckbox(): Promise<void>;
|
|
52
53
|
checkAnalystCheckbox(): Promise<void>;
|
|
@@ -64,18 +64,22 @@ class ConsoleOrganizationPage {
|
|
|
64
64
|
// (confirmed live: the name-scoped version timed out the same as the
|
|
65
65
|
// original role="group" one).
|
|
66
66
|
const openDialog = page.getByRole('dialog');
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
// Hub renamed the platform roles, and the "Edit user" dialog states each
|
|
68
|
+
// mapping in the role's own description (8.9 nightly trace DOM, checkbox
|
|
69
|
+
// ids c4-management-change-org-roles-*): "Member ... Formerly the Modeler
|
|
70
|
+
// role.", "Organization Admin ... Formerly the Admin role.", "DevOps ...
|
|
71
|
+
// Formerly the Operations Engineer role."; Analyst is unchanged. There is
|
|
72
|
+
// no "Modeler" checkbox at all any more, which is why the exact-name
|
|
73
|
+
// lookup resolved to nothing. Anchored regex rather than `exact`, since
|
|
74
|
+
// the accessible name can carry the description after the label. Same
|
|
75
|
+
// locators as pages/8.8.
|
|
76
|
+
const roleCheckbox = (current, legacy) => openDialog
|
|
77
|
+
.getByRole('checkbox', { name: current })
|
|
78
|
+
.or(openDialog.getByRole('checkbox', { name: legacy, exact: true }))
|
|
79
|
+
.first();
|
|
80
|
+
this.modelerCheckbox = roleCheckbox(/^Member\b/, 'Modeler');
|
|
81
|
+
this.adminCheckbox = roleCheckbox(/^Organization Admin\b/, 'Admin');
|
|
82
|
+
this.analystCheckbox = roleCheckbox(/^Analyst\b/, 'Analyst');
|
|
79
83
|
this.confirmButton = page.getByRole('button', { name: 'Confirm' });
|
|
80
84
|
this.settingsTab = page.getByRole('tab', { name: 'Settings' });
|
|
81
85
|
this.optInButton = page.getByRole('button', { name: 'Opt-in', exact: true });
|
|
@@ -184,8 +188,8 @@ class ConsoleOrganizationPage {
|
|
|
184
188
|
}
|
|
185
189
|
async selectAnalystRole(username) {
|
|
186
190
|
await this.filterTable([username]);
|
|
187
|
-
await this.clickOptionsButton();
|
|
188
|
-
await this.clickEditUserMenuItem();
|
|
191
|
+
await this.clickOptionsButton(username);
|
|
192
|
+
await this.clickEditUserMenuItem(username);
|
|
189
193
|
await this.checkAnalystCheckbox();
|
|
190
194
|
await this.uncheckModelerCheckbox();
|
|
191
195
|
await this.uncheckAdminCheckbox();
|
|
@@ -196,8 +200,8 @@ class ConsoleOrganizationPage {
|
|
|
196
200
|
}
|
|
197
201
|
async selectModelerRole(username) {
|
|
198
202
|
await this.filterTable([username]);
|
|
199
|
-
await this.clickOptionsButton();
|
|
200
|
-
await this.clickEditUserMenuItem();
|
|
203
|
+
await this.clickOptionsButton(username);
|
|
204
|
+
await this.clickEditUserMenuItem(username);
|
|
201
205
|
await this.uncheckAnalystCheckbox();
|
|
202
206
|
await this.uncheckAdminCheckbox();
|
|
203
207
|
await this.checkModelerCheckbox();
|
|
@@ -208,8 +212,8 @@ class ConsoleOrganizationPage {
|
|
|
208
212
|
}
|
|
209
213
|
async selectAdminRole(username) {
|
|
210
214
|
await this.filterTable([username]);
|
|
211
|
-
await this.clickOptionsButton();
|
|
212
|
-
await this.clickEditUserMenuItem();
|
|
215
|
+
await this.clickOptionsButton(username);
|
|
216
|
+
await this.clickEditUserMenuItem(username);
|
|
213
217
|
await this.uncheckAnalystCheckbox();
|
|
214
218
|
await this.uncheckModelerCheckbox();
|
|
215
219
|
await this.checkAdminCheckbox();
|
|
@@ -218,11 +222,32 @@ class ConsoleOrganizationPage {
|
|
|
218
222
|
timeout: 90000,
|
|
219
223
|
});
|
|
220
224
|
}
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
// Scoped to the user's own row: the table can still list other users when
|
|
226
|
+
// the menu opens, and a page-wide `.first()` would edit their roles.
|
|
227
|
+
userOptionsButton(username) {
|
|
228
|
+
const row = this.page.getByRole('row').filter({ hasText: username });
|
|
229
|
+
return row
|
|
230
|
+
.getByRole('button', { name: 'Options' })
|
|
231
|
+
.or(row.getByRole('button', { name: 'Row actions' }))
|
|
232
|
+
.first();
|
|
223
233
|
}
|
|
224
|
-
async
|
|
225
|
-
await this.
|
|
234
|
+
async clickOptionsButton(username) {
|
|
235
|
+
await this.userOptionsButton(username).click({ timeout: 60000 });
|
|
236
|
+
}
|
|
237
|
+
// The row menu can close under the click when the Users table re-renders
|
|
238
|
+
// (nightly: "element was detached from the DOM", after which the item never
|
|
239
|
+
// returns), so reopen it and retry rather than wait on a closed menu.
|
|
240
|
+
async clickEditUserMenuItem(username) {
|
|
241
|
+
await (0, test_1.expect)(async () => {
|
|
242
|
+
const menuOpen = await this.editUserMenuItem
|
|
243
|
+
.waitFor({ state: 'visible', timeout: 5000 })
|
|
244
|
+
.then(() => true)
|
|
245
|
+
.catch(() => false);
|
|
246
|
+
if (!menuOpen) {
|
|
247
|
+
await this.userOptionsButton(username).click({ timeout: 10000 });
|
|
248
|
+
}
|
|
249
|
+
await this.editUserMenuItem.click({ timeout: 10000 });
|
|
250
|
+
}).toPass({ timeout: 90000, intervals: [1000, 2000, 5000] });
|
|
226
251
|
}
|
|
227
252
|
async checkModelerCheckbox() {
|
|
228
253
|
if (!(await this.modelerCheckbox.isChecked({ timeout: 60000 }))) {
|
|
@@ -3,6 +3,9 @@ declare class FormJsPage {
|
|
|
3
3
|
private page;
|
|
4
4
|
private processApplicationPage;
|
|
5
5
|
readonly aiFormGeneratorButton: Locator;
|
|
6
|
+
readonly copilotCtaButton: Locator;
|
|
7
|
+
readonly copilotChatInput: Locator;
|
|
8
|
+
readonly copilotSendButton: Locator;
|
|
6
9
|
readonly formRequestInput: Locator;
|
|
7
10
|
readonly generateFormButton: Locator;
|
|
8
11
|
readonly formEditor: Locator;
|
|
@@ -22,6 +25,7 @@ declare class FormJsPage {
|
|
|
22
25
|
readonly deploySuccessNotification: Locator;
|
|
23
26
|
constructor(page: Page);
|
|
24
27
|
generateAIForm(request?: string): Promise<void>;
|
|
28
|
+
private generateFormWithCopilot;
|
|
25
29
|
clickAIFormGeneratorButton(): Promise<void>;
|
|
26
30
|
clickFormRequestInput(): Promise<void>;
|
|
27
31
|
fillFormRequestInput(formRequest: string): Promise<void>;
|
|
@@ -5,10 +5,14 @@ const test_1 = require("@playwright/test");
|
|
|
5
5
|
const sleep_1 = require("../../utils/sleep");
|
|
6
6
|
const ProcessApplicationPage_1 = require("./ProcessApplicationPage");
|
|
7
7
|
const modelerCluster_1 = require("../../utils/modelerCluster");
|
|
8
|
+
const hubDeployDialog_1 = require("../../utils/hubDeployDialog");
|
|
8
9
|
class FormJsPage {
|
|
9
10
|
page;
|
|
10
11
|
processApplicationPage;
|
|
11
12
|
aiFormGeneratorButton;
|
|
13
|
+
copilotCtaButton;
|
|
14
|
+
copilotChatInput;
|
|
15
|
+
copilotSendButton;
|
|
12
16
|
formRequestInput;
|
|
13
17
|
generateFormButton;
|
|
14
18
|
formEditor;
|
|
@@ -32,6 +36,16 @@ class FormJsPage {
|
|
|
32
36
|
this.aiFormGeneratorButton = page.getByRole('button', {
|
|
33
37
|
name: 'AI Form Generator',
|
|
34
38
|
});
|
|
39
|
+
// camunda-hub #21398 retired the form page's AI Form Generator in favour
|
|
40
|
+
// of the Camunda Copilot sidecar: with One Copilot on, the empty form
|
|
41
|
+
// offers "Try Camunda Copilot" instead (FormDs.tsx / CopilotCTA.tsx), and
|
|
42
|
+
// the sidecar's chat input and send button come from
|
|
43
|
+
// camunda-copilot-client's ChatInput. Same shape as pages/8.7.
|
|
44
|
+
this.copilotCtaButton = page.getByRole('button', {
|
|
45
|
+
name: 'Try Camunda Copilot',
|
|
46
|
+
});
|
|
47
|
+
this.copilotChatInput = page.getByPlaceholder('Type a message...');
|
|
48
|
+
this.copilotSendButton = page.getByRole('button', { name: 'Send message' });
|
|
35
49
|
this.formRequestInput = page.getByPlaceholder('A form for an american standard loan request');
|
|
36
50
|
this.generateFormButton = page.getByRole('button', { name: 'Generate form' });
|
|
37
51
|
this.formEditor = page.getByLabel('Form Definition');
|
|
@@ -57,21 +71,40 @@ class FormJsPage {
|
|
|
57
71
|
// Inside a process application hub titles this modal for the application
|
|
58
72
|
// rather than for the form, so 'Deploy form' never matches and the dialog
|
|
59
73
|
// reads as absent. pages/SM-8.10 filters on 'Deploy' for the same reason.
|
|
74
|
+
// Camunda Hub's design-system shell renders no Carbon markup: the nightly
|
|
75
|
+
// trace shows the "Deploy project" dialog open with no `cds--*` classes,
|
|
76
|
+
// so the Carbon container selector matched nothing and the dialog read as
|
|
77
|
+
// absent. Same locator pages/8.8 uses.
|
|
60
78
|
this.dialog = page
|
|
79
|
+
.getByRole('dialog')
|
|
80
|
+
.filter({ hasText: 'Deploy' })
|
|
81
|
+
.or(page
|
|
61
82
|
.locator('.cds--modal-container[role="dialog"]')
|
|
62
|
-
.filter({ hasText: 'Deploy' })
|
|
83
|
+
.filter({ hasText: 'Deploy' }))
|
|
84
|
+
.first();
|
|
63
85
|
this.deploySubButton = this.dialog.getByRole('button', {
|
|
64
86
|
name: 'Deploy',
|
|
65
87
|
exact: true,
|
|
66
88
|
});
|
|
89
|
+
// Same Carbon-to-design-system move as the dialog above: Hub's success
|
|
90
|
+
// toast is not a `cds--toast-*` node. With the scope narrowed to "Only
|
|
91
|
+
// this resource" Hub still titles it "Form deployed!" (camunda-hub
|
|
92
|
+
// deploy/get-success-message.ts), so match that text anywhere.
|
|
67
93
|
this.deploySuccessNotification = page
|
|
94
|
+
.getByText('Form deployed!')
|
|
95
|
+
.or(page
|
|
68
96
|
.locator('.cds--toast-notification--success')
|
|
69
|
-
.filter({ hasText: 'Form deployed!' })
|
|
97
|
+
.filter({ hasText: 'Form deployed!' }))
|
|
98
|
+
.first();
|
|
70
99
|
}
|
|
71
100
|
async generateAIForm(request = 'Create a form with the following fields: 1. A text field with the label "Full Name" 2. A number with the label "Count" 3. A date input with the label "Date of birth"4. A Checkbox with the label "Agree"') {
|
|
72
|
-
await (0, test_1.expect)(this.aiFormGeneratorButton).toBeVisible({
|
|
101
|
+
await (0, test_1.expect)(this.aiFormGeneratorButton.or(this.copilotCtaButton).first()).toBeVisible({
|
|
73
102
|
timeout: 90000,
|
|
74
103
|
});
|
|
104
|
+
if (!(await this.aiFormGeneratorButton.isVisible())) {
|
|
105
|
+
await this.generateFormWithCopilot(request);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
75
108
|
await this.clickAIFormGeneratorButton();
|
|
76
109
|
await this.clickFormRequestInput();
|
|
77
110
|
await this.fillFormRequestInput(request);
|
|
@@ -80,6 +113,19 @@ class FormJsPage {
|
|
|
80
113
|
await (0, test_1.expect)(this.page.getByText('Successfully generated smart form.')).toBeVisible({ timeout: 300000 });
|
|
81
114
|
await (0, sleep_1.sleep)(60000);
|
|
82
115
|
}
|
|
116
|
+
async generateFormWithCopilot(request) {
|
|
117
|
+
await this.copilotCtaButton.click({ timeout: 30000 });
|
|
118
|
+
await (0, test_1.expect)(this.copilotChatInput).toBeVisible({ timeout: 60000 });
|
|
119
|
+
await this.copilotChatInput.fill(request);
|
|
120
|
+
await this.copilotSendButton.click({ timeout: 30000 });
|
|
121
|
+
// Copilot edits the open form in place; the generated form is ready once
|
|
122
|
+
// every requested field shows up on the canvas.
|
|
123
|
+
for (const label of ['Full Name', 'Count', 'Date of birth', 'Agree']) {
|
|
124
|
+
await (0, test_1.expect)(this.formEditor.getByText(label).first()).toBeVisible({
|
|
125
|
+
timeout: 300000,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
83
129
|
async clickAIFormGeneratorButton() {
|
|
84
130
|
await this.aiFormGeneratorButton.click();
|
|
85
131
|
}
|
|
@@ -219,22 +265,10 @@ class FormJsPage {
|
|
|
219
265
|
// silently turning it into a process-application deploy. The combobox only
|
|
220
266
|
// exists inside a container, hence the boolean probe.
|
|
221
267
|
async selectOnlyThisResource() {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
.waitFor({ state: 'visible', timeout: 10000 })
|
|
227
|
-
.then(() => true)
|
|
228
|
-
.catch(() => false);
|
|
229
|
-
if (!hasScopeSelect) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
await scopeSelect.click();
|
|
233
|
-
await this.dialog
|
|
234
|
-
.getByRole('option', { name: 'Only this resource' })
|
|
235
|
-
.or(this.dialog.getByText('Only this resource', { exact: true }))
|
|
236
|
-
.first()
|
|
237
|
-
.click({ timeout: 30000 });
|
|
268
|
+
// Hub's scope select is named by its value ("All resources"), not by the
|
|
269
|
+
// "Resources to deploy" label, so the name lookup this used matched
|
|
270
|
+
// nothing. The shared helper addresses it by id, as pages/8.8 does.
|
|
271
|
+
await (0, hubDeployDialog_1.selectOnlyThisResourceInDialog)(this.page, this.dialog);
|
|
238
272
|
}
|
|
239
273
|
async deployForm(clusterName) {
|
|
240
274
|
await this.processApplicationPage.ensureStageCluster(clusterName);
|
|
@@ -74,8 +74,13 @@ class IdpCreatePage {
|
|
|
74
74
|
this.idpExtractionDescriptionField = page
|
|
75
75
|
.getByRole('region', { name: 'Create extraction template' })
|
|
76
76
|
.locator('#idp-project-description');
|
|
77
|
+
// Hub now renders "Create classification template" as a design-system
|
|
78
|
+
// dialog (role="dialog", data-slot="dialog-content") rather than a
|
|
79
|
+
// labelled region -- the 8.9 nightly trace shows the field inside it, so
|
|
80
|
+
// the region-scoped lookup timed out. Accept either container.
|
|
77
81
|
this.idpClassificationDescriptionField = page
|
|
78
82
|
.getByRole('region', { name: 'Create classification template' })
|
|
83
|
+
.or(page.getByRole('dialog', { name: 'Create classification template' }))
|
|
79
84
|
.locator('#idp-project-description');
|
|
80
85
|
this.createIdpExtractationTemplateButton = page.getByRole('button', {
|
|
81
86
|
name: 'Create template',
|
|
@@ -105,6 +105,8 @@ declare class ModelerCreatePage {
|
|
|
105
105
|
readonly eighthPlacedElement: Locator;
|
|
106
106
|
readonly deployAndRunMainButton: Locator;
|
|
107
107
|
readonly deployAndRunSubButton: Locator;
|
|
108
|
+
readonly deployRunActions: Locator;
|
|
109
|
+
readonly deployAndRunMenuItem: Locator;
|
|
108
110
|
readonly dialog: Locator;
|
|
109
111
|
readonly backupDeployButton: Locator;
|
|
110
112
|
readonly globalConnectToolButton: Locator;
|
|
@@ -143,6 +145,7 @@ declare class ModelerCreatePage {
|
|
|
143
145
|
clickAdditionalActionsButton(): Promise<void>;
|
|
144
146
|
clickDeployMenuItem(): Promise<void>;
|
|
145
147
|
deployDiagram(clusterName: string): Promise<void>;
|
|
148
|
+
assertDeployAndRunNotPermitted(): Promise<void>;
|
|
146
149
|
clickStartInstanceMainButton(): Promise<void>;
|
|
147
150
|
clickStartInstanceSubButton(): Promise<void>;
|
|
148
151
|
runProcessInstance(clusterName: string, variables?: string, formVariables?: {
|
|
@@ -216,9 +219,11 @@ declare class ModelerCreatePage {
|
|
|
216
219
|
fillJobTypeInput(name: string): Promise<void>;
|
|
217
220
|
private suppressTestModeAnnouncement;
|
|
218
221
|
switchToPlay(): Promise<void>;
|
|
222
|
+
private selectPlayDeploySingleResource;
|
|
219
223
|
completePlayConfiguration(clusterName: string): Promise<void>;
|
|
220
224
|
embedForm(formName: string): Promise<void>;
|
|
221
225
|
fillStartEventVariablesForDocHandling(zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string): Promise<void>;
|
|
226
|
+
private openOutputMappingEntry;
|
|
222
227
|
fillZeebeClientId(clientId: string): Promise<void>;
|
|
223
228
|
fillZeebeSecretValue(zeebeSecret: string): Promise<void>;
|
|
224
229
|
fillZeebeRestValue(zeebeUrl: string): Promise<void>;
|