@camunda/e2e-test-suite 0.0.1273 → 0.0.1274
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.8/AppsPage.d.ts +2 -0
- package/dist/pages/8.8/AppsPage.js +122 -0
- package/dist/pages/8.8/ClusterDetailsPage.d.ts +1 -0
- package/dist/pages/8.8/ClusterDetailsPage.js +29 -10
- package/dist/pages/8.8/ClusterPage.js +35 -2
- package/dist/pages/8.8/ClusterSecretsPage.d.ts +1 -0
- package/dist/pages/8.8/ClusterSecretsPage.js +62 -2
- package/dist/pages/8.8/FormJsPage.js +55 -24
- package/dist/pages/8.8/HomePage.d.ts +3 -0
- package/dist/pages/8.8/HomePage.js +62 -7
- package/dist/pages/8.8/LoginPage.js +32 -1
- package/dist/pages/8.8/ModelerCreatePage.d.ts +1 -0
- package/dist/pages/8.8/ModelerCreatePage.js +78 -16
- package/dist/pages/8.8/ModelerHomePage.d.ts +10 -0
- package/dist/pages/8.8/ModelerHomePage.js +339 -14
- package/dist/pages/8.8/UtilitiesPage.js +47 -2
- package/dist/tests/8.8/test-setup.spec.js +29 -4
- package/dist/utils/consoleApiHelpers.d.ts +5 -0
- package/dist/utils/consoleApiHelpers.js +177 -2
- package/dist/utils/hubDeployDialog.d.ts +3 -0
- package/dist/utils/hubDeployDialog.js +74 -0
- package/dist/utils/hubResourceRename.d.ts +4 -0
- package/dist/utils/hubResourceRename.js +74 -0
- package/package.json +1 -1
|
@@ -15,16 +15,35 @@ class HomePage {
|
|
|
15
15
|
appSwitcher;
|
|
16
16
|
openOrganizationButton;
|
|
17
17
|
consoleBanner;
|
|
18
|
+
hubHeader;
|
|
19
|
+
hubSidebar;
|
|
18
20
|
modelerBanner;
|
|
19
21
|
gettingStartedHeading;
|
|
20
22
|
buttonSkipCustomization;
|
|
21
23
|
constructor(page) {
|
|
22
24
|
this.page = page;
|
|
25
|
+
// Camunda Hub replaces Console on SaaS: an app header (only carrying the
|
|
26
|
+
// user menu once authenticated) plus a sidebar whose Console section
|
|
27
|
+
// links to /org/<id>/clusters and /org/<id>/management.
|
|
28
|
+
this.hubHeader = page
|
|
29
|
+
.locator('header[data-slot="app-header"]')
|
|
30
|
+
.filter({ has: page.locator('[data-slot="user-menu-trigger"]') });
|
|
31
|
+
this.hubSidebar = page.locator('nav[data-slot="app-sidebar"]');
|
|
23
32
|
this.dashboardTab = page.getByRole('link', { name: 'Dashboard' });
|
|
33
|
+
// Once an org has environmentsEnabled, camunda-hub's
|
|
34
|
+
// use-ds-sidebar-items.tsx replaces the sidebar's Clusters link with one
|
|
35
|
+
// labelled "Environments" whose href is '/environments', not
|
|
36
|
+
// '/clusters' -- accept both hrefs so this resolves either way.
|
|
24
37
|
this.clusterTab = page
|
|
25
38
|
.getByRole('banner')
|
|
26
|
-
.getByRole('link', { name: 'Clusters' })
|
|
27
|
-
|
|
39
|
+
.getByRole('link', { name: 'Clusters' })
|
|
40
|
+
.or(this.hubSidebar.locator('a[href$="/clusters"]'))
|
|
41
|
+
.or(this.hubSidebar.locator('a[href$="/environments"]'))
|
|
42
|
+
.first();
|
|
43
|
+
this.organizationTab = page
|
|
44
|
+
.getByRole('link', { name: 'Organization' })
|
|
45
|
+
.or(this.hubSidebar.locator('a[href$="/management"]'))
|
|
46
|
+
.first();
|
|
28
47
|
this.organizationViewTitle = page.getByText('Organization Management');
|
|
29
48
|
this.welcomeMessage = page.getByText('Welcome to Camunda!').first();
|
|
30
49
|
this.informationDialog = page.getByRole('button', {
|
|
@@ -32,14 +51,23 @@ class HomePage {
|
|
|
32
51
|
});
|
|
33
52
|
this.camundaAppsButton = page.getByLabel('Camunda apps');
|
|
34
53
|
this.appSwitcher = page.getByLabel('App Switcher');
|
|
54
|
+
// Specs assert this as "the authenticated app shell has rendered" before
|
|
55
|
+
// navigating. Camunda Hub has no app-switcher button at all (apps are
|
|
56
|
+
// reached from the sidebar), so on Hub its authenticated header is the
|
|
57
|
+
// equivalent readiness signal.
|
|
35
58
|
this.camundaComponentsButton = page
|
|
36
59
|
.getByLabel('Camunda components')
|
|
37
60
|
.or(this.camundaAppsButton)
|
|
38
|
-
.or(this.appSwitcher)
|
|
61
|
+
.or(this.appSwitcher)
|
|
62
|
+
.or(this.hubHeader);
|
|
39
63
|
this.openOrganizationButton = page.getByLabel('Open Organizations');
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
// "Camunda logo Console" was the old Carbon header's logo link. Camunda
|
|
65
|
+
// Hub has no equivalent link -- its post-login landing is `hubHeader`
|
|
66
|
+
// (see above) -- so callers that assert this banner as a login/Console
|
|
67
|
+
// arrival signal need the Hub fallback too.
|
|
68
|
+
this.consoleBanner = page
|
|
69
|
+
.getByRole('link', { name: 'Camunda logo Console' })
|
|
70
|
+
.or(this.hubHeader);
|
|
43
71
|
this.gettingStartedHeading = page.getByText('start by creating a project');
|
|
44
72
|
this.buttonSkipCustomization = page.getByRole('button', {
|
|
45
73
|
name: 'Skip customization',
|
|
@@ -49,8 +77,35 @@ class HomePage {
|
|
|
49
77
|
});
|
|
50
78
|
}
|
|
51
79
|
async clickClusters() {
|
|
52
|
-
await (0, test_1.expect)(this.clusterTab).toBeVisible({ timeout:
|
|
80
|
+
await (0, test_1.expect)(this.clusterTab).toBeVisible({ timeout: 30000 });
|
|
53
81
|
await this.clusterTab.click({ timeout: 15000 });
|
|
82
|
+
await this.clickClustersPageTabIfPresent();
|
|
83
|
+
}
|
|
84
|
+
// Landing on Hub's Environments overview (see clusterTab above) doesn't put
|
|
85
|
+
// us on the classic row-based cluster list ClusterPage.ts expects -- that
|
|
86
|
+
// page renders clusters as cards. Its own header renders a separate
|
|
87
|
+
// "Clusters" tab (camunda-hub EnvironmentsPageHeader.tsx, href /clusters)
|
|
88
|
+
// that does.
|
|
89
|
+
async clickClustersPageTabIfPresent() {
|
|
90
|
+
const clustersPageTab = this.page
|
|
91
|
+
.getByRole('navigation', { name: 'Environments views' })
|
|
92
|
+
.getByRole('link', { name: 'Clusters', exact: true });
|
|
93
|
+
// Required on Hub, not optional: this page's row-based cluster locators
|
|
94
|
+
// cannot be satisfied by the card-based Environments overview we just
|
|
95
|
+
// landed on. isVisible() does not wait, so a slow tab render used to be
|
|
96
|
+
// read as "no tab here" and the flow continued on the wrong route.
|
|
97
|
+
const onHub = new URL(this.page.url()).hostname.startsWith('hub.');
|
|
98
|
+
const tabShown = await clustersPageTab
|
|
99
|
+
.waitFor({ state: 'visible', timeout: onHub ? 30000 : 5000 })
|
|
100
|
+
.then(() => true)
|
|
101
|
+
.catch(() => false);
|
|
102
|
+
if (tabShown) {
|
|
103
|
+
await clustersPageTab.click({ timeout: 15000 });
|
|
104
|
+
}
|
|
105
|
+
else if (onHub) {
|
|
106
|
+
throw new Error('Hub Environments view did not render its "Clusters" tab; the ' +
|
|
107
|
+
'row-based cluster list this page needs is unreachable without it');
|
|
108
|
+
}
|
|
54
109
|
}
|
|
55
110
|
async clickDashboard() {
|
|
56
111
|
await this.dashboardTab.click({ timeout: 90000 });
|
|
@@ -5,6 +5,7 @@ const test_1 = require("@playwright/test");
|
|
|
5
5
|
const authErrorClassification_1 = require("../../utils/authErrorClassification");
|
|
6
6
|
const UtilitiesPage_1 = require("./UtilitiesPage");
|
|
7
7
|
const sessionRecovery_1 = require("../../utils/sessionRecovery");
|
|
8
|
+
const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
|
|
8
9
|
class LoginPage {
|
|
9
10
|
page;
|
|
10
11
|
usernameInput;
|
|
@@ -50,7 +51,34 @@ class LoginPage {
|
|
|
50
51
|
}
|
|
51
52
|
async fillPassword(password) {
|
|
52
53
|
await this.passwordInput.waitFor({ state: 'visible', timeout: 60000 });
|
|
53
|
-
|
|
54
|
+
// Auth0's password screen becomes visible before its own scripts finish
|
|
55
|
+
// wiring up the field, and that initialisation wipes whatever is already
|
|
56
|
+
// in it. A discarded value makes Continue post an empty password, Auth0
|
|
57
|
+
// re-renders the same screen with "Password is required", and a login can
|
|
58
|
+
// burn all five retries without ever reaching the app.
|
|
59
|
+
//
|
|
60
|
+
// Typed, not filled: a live trace of that failure shows six fill +
|
|
61
|
+
// read-back cycles in a row all coming back empty, so re-filling cannot
|
|
62
|
+
// help -- `fill()` sets the value in one shot and Auth0's own handlers
|
|
63
|
+
// never see it, leaving their state empty and the field cleared on the
|
|
64
|
+
// next render. pressSequentially dispatches real key events, which those
|
|
65
|
+
// handlers do process.
|
|
66
|
+
//
|
|
67
|
+
// Polled rather than slept on: the check settles as soon as the value is
|
|
68
|
+
// there, so a healthy login pays nothing.
|
|
69
|
+
//
|
|
70
|
+
// Only the LENGTH is ever read back or asserted on, so the secret cannot
|
|
71
|
+
// reach a log, a trace entry or an assertion-failure message.
|
|
72
|
+
await (0, test_1.expect)(async () => {
|
|
73
|
+
await this.passwordInput.click();
|
|
74
|
+
await this.passwordInput.fill('');
|
|
75
|
+
await this.passwordInput.pressSequentially(password, { delay: 20 });
|
|
76
|
+
await test_1.expect
|
|
77
|
+
.poll(async () => this.passwordInput
|
|
78
|
+
.evaluate((el) => el.value.length)
|
|
79
|
+
.catch(() => 0), { timeout: 5000, intervals: [200, 400, 800] })
|
|
80
|
+
.toBe(password.length);
|
|
81
|
+
}).toPass({ timeout: 60000, intervals: [500, 1000, 2000] });
|
|
54
82
|
}
|
|
55
83
|
async clickLoginButton() {
|
|
56
84
|
await this.loginButton.click({ timeout: 60000 });
|
|
@@ -58,6 +86,7 @@ class LoginPage {
|
|
|
58
86
|
async login(credentials = {}) {
|
|
59
87
|
const { username = process.env.C8_USERNAME, password = process.env.C8_PASSWORD, } = credentials;
|
|
60
88
|
(0, sessionRecovery_1.trackSignedInUser)(this.page, username);
|
|
89
|
+
(0, consoleApiHelpers_1.resetHubBearerToken)(this.page);
|
|
61
90
|
await (0, test_1.expect)(this.usernameInput).toBeVisible({ timeout: 200000 });
|
|
62
91
|
await this.fillUsername(username);
|
|
63
92
|
await this.clickContinueButton();
|
|
@@ -69,6 +98,7 @@ class LoginPage {
|
|
|
69
98
|
async loginWithTestUser(credentials = {}) {
|
|
70
99
|
const { username = process.env.C8_USERNAME_TEST, password = process.env.C8_PASSWORD_TEST, } = credentials;
|
|
71
100
|
(0, sessionRecovery_1.trackSignedInUser)(this.page, username);
|
|
101
|
+
(0, consoleApiHelpers_1.resetHubBearerToken)(this.page);
|
|
72
102
|
// SSO re-auth may silently log us back in as the previous user after logout.
|
|
73
103
|
// Detect Console (settings button visible) and retry logout until Auth0 form appears.
|
|
74
104
|
const settingsBtn = this.page.getByLabel('Open Settings');
|
|
@@ -119,6 +149,7 @@ class LoginPage {
|
|
|
119
149
|
async loginWithoutOrgAssertion(credentials = {}) {
|
|
120
150
|
const { username = process.env.C8_USERNAME, password = process.env.C8_PASSWORD, } = credentials;
|
|
121
151
|
(0, sessionRecovery_1.trackSignedInUser)(this.page, username);
|
|
152
|
+
(0, consoleApiHelpers_1.resetHubBearerToken)(this.page);
|
|
122
153
|
await (0, test_1.expect)(this.usernameInput).toBeVisible({ timeout: 180000 });
|
|
123
154
|
await this.fillUsername(username);
|
|
124
155
|
await this.clickContinueButton();
|
|
@@ -145,6 +145,7 @@ declare class ModelerCreatePage {
|
|
|
145
145
|
runProcessInstance(clusterName: string, variables?: string, formVariables?: {
|
|
146
146
|
[key: string]: string;
|
|
147
147
|
}, textToVisible?: string, expectRejection?: boolean): Promise<void>;
|
|
148
|
+
selectOnlyThisResource(): Promise<void>;
|
|
148
149
|
selectCluster(clusterName: string): Promise<void>;
|
|
149
150
|
clickViewProcessInstanceLink(): Promise<void>;
|
|
150
151
|
clickNameInput(): Promise<void>;
|
|
@@ -7,6 +7,9 @@ const clickLocatorWithRetry_1 = require("../../utils/assertionHelpers/clickLocat
|
|
|
7
7
|
const ConnectorMarketplacePage_1 = require("./ConnectorMarketplacePage");
|
|
8
8
|
const ProcessApplicationPage_1 = require("./ProcessApplicationPage");
|
|
9
9
|
const sessionRecovery_1 = require("../../utils/sessionRecovery");
|
|
10
|
+
const hubResourceRename_1 = require("../../utils/hubResourceRename");
|
|
11
|
+
const hubDeployDialog_1 = require("../../utils/hubDeployDialog");
|
|
12
|
+
const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
|
|
10
13
|
class ModelerCreatePage {
|
|
11
14
|
page;
|
|
12
15
|
processApplicationPage;
|
|
@@ -172,14 +175,38 @@ class ModelerCreatePage {
|
|
|
172
175
|
this.nameInput = page.getByLabel('Name', { exact: true });
|
|
173
176
|
this.diagramBreadcrumb = page.locator('[data-test="breadcrumb-diagram"]');
|
|
174
177
|
this.renameDiagramNameButton = page.getByText('Rename');
|
|
175
|
-
|
|
178
|
+
// Hub's rename dialog field, with the legacy inline editable kept for
|
|
179
|
+
// shells where the design-system migration has not shipped.
|
|
180
|
+
this.diagramNameInput = page
|
|
181
|
+
.locator('[data-test="rename-input"]')
|
|
182
|
+
.or(page.locator('[data-test="editable-input"]'))
|
|
183
|
+
.first();
|
|
176
184
|
this.variableInput = page.locator('[id="variables-json"]');
|
|
177
185
|
this.embedFormButton = page.getByRole('button', { name: 'Link form' });
|
|
178
|
-
|
|
186
|
+
// Hub's link picker confirms with `link-target-confirm` ("Link");
|
|
187
|
+
// `confirm-move` was the old move/link dialog's id and exists only in
|
|
188
|
+
// hub's older cypress specs now. Keep it as a fallback.
|
|
189
|
+
this.embedButton = page
|
|
190
|
+
.locator('[data-test="link-target-confirm"]')
|
|
191
|
+
.or(page.locator('[data-test="confirm-move"]'))
|
|
192
|
+
.first();
|
|
193
|
+
// Same picker as clickForm(): entries are buttons labelled
|
|
194
|
+
// "Select <name>" inside `link-target-list`, not `item-<name>` nodes.
|
|
179
195
|
this.newForm = page
|
|
180
|
-
.locator('[data-test="
|
|
181
|
-
.
|
|
182
|
-
|
|
196
|
+
.locator('[data-test="link-target-list"]')
|
|
197
|
+
.getByRole('button', { name: /^Select New form/ })
|
|
198
|
+
.first()
|
|
199
|
+
.or(page.locator('[data-test="item-New form"]').getByText('New form'))
|
|
200
|
+
.first();
|
|
201
|
+
// `deploy-action` is absent from Hub's shell (a DOM audit of a live run
|
|
202
|
+
// found no such id); its deploy dialog confirms with a plain button named
|
|
203
|
+
// "Deploy" in the dialog footer.
|
|
204
|
+
this.deploySubButton = page
|
|
205
|
+
.locator('[data-test="deploy-action"]')
|
|
206
|
+
.or(page
|
|
207
|
+
.getByRole('dialog')
|
|
208
|
+
.getByRole('button', { name: 'Deploy', exact: true }))
|
|
209
|
+
.first();
|
|
183
210
|
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
|
|
184
211
|
this.restConnectorOption = page.locator('[data-id="replace.template-io.camunda.connectors.HttpJson.v2"]');
|
|
185
212
|
this.changeElementSearchInput = page.locator('.djs-popup-search input');
|
|
@@ -337,12 +364,25 @@ class ModelerCreatePage {
|
|
|
337
364
|
this.backupDeployButton = page.getByRole('button', {
|
|
338
365
|
name: 'Deploy',
|
|
339
366
|
});
|
|
367
|
+
// Hub's design-system shell emits no Carbon markup, so the `cds--toast-*`
|
|
368
|
+
// scope matched nothing and this assertion read as "not linked" even on a
|
|
369
|
+
// successful link. Assert the message itself and keep the Carbon scope for
|
|
370
|
+
// shells that still render it.
|
|
340
371
|
this.formLinkedSuccessMessage = page
|
|
372
|
+
.getByText('Form has been successfully linked.')
|
|
373
|
+
.or(page
|
|
341
374
|
.locator('.cds--toast-notification__subtitle')
|
|
342
|
-
.getByText('Form has been successfully linked.')
|
|
343
|
-
|
|
375
|
+
.getByText('Form has been successfully linked.'))
|
|
376
|
+
.first();
|
|
377
|
+
// Hub's breadcrumbs carry no data-test (DOM audit of a live run found none
|
|
378
|
+
// of the breadcrumb-* ids present), so address the diagram by its own name
|
|
379
|
+
// in the breadcrumb navigation and keep the legacy id as a fallback.
|
|
380
|
+
this.diagramNameBreadcrumb = (diagramName) => page
|
|
381
|
+
.locator('button[data-test="breadcrumb-diagram"]', {
|
|
344
382
|
hasText: diagramName,
|
|
345
|
-
})
|
|
383
|
+
})
|
|
384
|
+
.or((0, hubResourceRename_1.hubBreadcrumbs)(page).getByText(diagramName, { exact: true }))
|
|
385
|
+
.first();
|
|
346
386
|
this.webhookActiveMessage = page.getByText('Webhook is active');
|
|
347
387
|
}
|
|
348
388
|
async clickSecondDeployButton() {
|
|
@@ -500,10 +540,16 @@ class ModelerCreatePage {
|
|
|
500
540
|
// a form with the same name and the picker then lists two identical entries.
|
|
501
541
|
// Scope to the first matching item so the link step stays deterministic on retry
|
|
502
542
|
// instead of failing with a strict-mode violation.
|
|
543
|
+
// Hub's link picker is `ul[data-test="link-target-list"]` whose entries are
|
|
544
|
+
// buttons labelled "Select <name>" with a per-file
|
|
545
|
+
// `data-test="link-target-file-<uuid>"`; the old `item-<name>` id does not
|
|
546
|
+
// exist on it (a DOM audit of a live run found no `item-*` at all). Keep
|
|
547
|
+
// the legacy id as a fallback for pre-design-system shells.
|
|
503
548
|
await this.page
|
|
504
|
-
.locator(
|
|
549
|
+
.locator('[data-test="link-target-list"]')
|
|
550
|
+
.getByRole('button', { name: `Select ${name}`, exact: true })
|
|
551
|
+
.or(this.page.locator(`[data-test="item-${name}"]`).first().getByText(name))
|
|
505
552
|
.first()
|
|
506
|
-
.getByText(name)
|
|
507
553
|
.click({ timeout: 90000 });
|
|
508
554
|
}
|
|
509
555
|
async clickUserTask(id) {
|
|
@@ -620,6 +666,12 @@ class ModelerCreatePage {
|
|
|
620
666
|
const retryDelayMs = 20000;
|
|
621
667
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
622
668
|
try {
|
|
669
|
+
// Hub lists only the ENVIRONMENTS assigned to the workspace in this
|
|
670
|
+
// dialog, so a cluster the workspace does not carry is simply absent
|
|
671
|
+
// from the picker. deployForm() ensures that link for the form path;
|
|
672
|
+
// a spec that runs a diagram without deploying a form first would
|
|
673
|
+
// otherwise reach this dialog with nothing to select.
|
|
674
|
+
await (0, consoleApiHelpers_1.ensureClusterLinkedToSharedWorkspace)(this.page, clusterName);
|
|
623
675
|
// Inside the loop, not before it: a no-op once bound, but selectCluster
|
|
624
676
|
// clears the binding when the dialog does not offer the cluster, so the
|
|
625
677
|
// next attempt rebinds rather than reopening an unchanged dialog.
|
|
@@ -677,8 +729,18 @@ class ModelerCreatePage {
|
|
|
677
729
|
}
|
|
678
730
|
}
|
|
679
731
|
}
|
|
732
|
+
// Scopes Hub's deploy/run dialog to the single resource being deployed.
|
|
733
|
+
// Mirrors FormJsPage.selectOnlyThisResource(): the select trigger carries no
|
|
734
|
+
// aria-labelledby, so it is addressed by its id (`deployment-scope-selection`)
|
|
735
|
+
// -- a name-based lookup silently matches nothing -- and its options render
|
|
736
|
+
// in a portal attached to <body>, outside the dialog, so they are looked up
|
|
737
|
+
// page-scoped. A no-op on dialogs that offer no scope choice.
|
|
738
|
+
async selectOnlyThisResource() {
|
|
739
|
+
await (0, hubDeployDialog_1.selectOnlyThisResourceInDialog)(this.page, this.dialog);
|
|
740
|
+
}
|
|
680
741
|
async selectCluster(clusterName) {
|
|
681
742
|
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 30000 });
|
|
743
|
+
await this.selectOnlyThisResource();
|
|
682
744
|
const healthCheckTimeout = 30000;
|
|
683
745
|
// Inside a process application the deploy dialog renders
|
|
684
746
|
// ProcessAppClusterSelection, not the per-deploy ClusterSelection toggle
|
|
@@ -720,15 +782,13 @@ class ModelerCreatePage {
|
|
|
720
782
|
}
|
|
721
783
|
return;
|
|
722
784
|
}
|
|
723
|
-
const healthyRegex = new RegExp(`${clusterName}.*?
|
|
785
|
+
const healthyRegex = new RegExp(`${clusterName}.*?Healthy`);
|
|
724
786
|
const clusterLabel = this.dialog
|
|
725
787
|
.locator('label')
|
|
726
788
|
.filter({ hasText: new RegExp(`^${clusterName}`) });
|
|
727
789
|
await (0, test_1.expect)(clusterLabel).toBeVisible({ timeout: 30000 });
|
|
728
790
|
await clusterLabel.click();
|
|
729
|
-
await (0,
|
|
730
|
-
timeout: 30000,
|
|
731
|
-
});
|
|
791
|
+
await (0, hubDeployDialog_1.assertClusterSelectedInDialog)(this.dialog, clusterName);
|
|
732
792
|
await (0, test_1.expect)(this.dialog).toHaveText(healthyRegex, {
|
|
733
793
|
timeout: healthCheckTimeout,
|
|
734
794
|
});
|
|
@@ -809,8 +869,10 @@ class ModelerCreatePage {
|
|
|
809
869
|
}).toPass({ timeout: 60000, intervals: [1000, 2000, 5000] });
|
|
810
870
|
}
|
|
811
871
|
async enterDiagramName(name) {
|
|
812
|
-
|
|
813
|
-
|
|
872
|
+
// Hub renames through the current crumb's actions menu into a shared
|
|
873
|
+
// dialog; the inline editable this used to fill never mounts on its own.
|
|
874
|
+
// "New BPMN diagram" is the server default the diagram still carries here.
|
|
875
|
+
await (0, hubResourceRename_1.renameHubResource)(this.page, 'New BPMN diagram', name);
|
|
814
876
|
}
|
|
815
877
|
async clickVariableInput() {
|
|
816
878
|
await this.variableInput.click({ timeout: 60000 });
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { Page, Locator } from '@playwright/test';
|
|
2
2
|
declare class ModelerHomePage {
|
|
3
3
|
private defaultFolderName;
|
|
4
|
+
private defaultClusterName;
|
|
4
5
|
private page;
|
|
5
6
|
private processApplicationPage;
|
|
6
7
|
private processApplicationUrl?;
|
|
7
8
|
private processApplicationName?;
|
|
8
9
|
readonly modelerPageBanner: Locator;
|
|
9
10
|
readonly createNewProjectButton: Locator;
|
|
11
|
+
readonly createWorkspaceButton: Locator;
|
|
12
|
+
readonly workspaceWizardNameInput: Locator;
|
|
13
|
+
readonly workspaceWizardSubmitButton: Locator;
|
|
14
|
+
readonly workspaceWizardMembersStep: Locator;
|
|
15
|
+
readonly workspaceWizardEnvironmentsHeading: Locator;
|
|
10
16
|
readonly projectNameInput: Locator;
|
|
11
17
|
readonly formNameInput: Locator;
|
|
12
18
|
readonly chooseBpmnTemplateButton: Locator;
|
|
@@ -49,6 +55,7 @@ declare class ModelerHomePage {
|
|
|
49
55
|
reload(): Promise<void>;
|
|
50
56
|
getProjectNames(name: string): Promise<string[]>;
|
|
51
57
|
clickProcessDiagram(name: string): Promise<void>;
|
|
58
|
+
private openProjectCreateMenuWithResources;
|
|
52
59
|
clickDiagramTypeDropdown(): Promise<void>;
|
|
53
60
|
clickWorkspaceDiagramTypeDropdown(): Promise<void>;
|
|
54
61
|
clickBpmnTemplateOption(): Promise<void>;
|
|
@@ -61,7 +68,9 @@ declare class ModelerHomePage {
|
|
|
61
68
|
private ensureInResourceContainer;
|
|
62
69
|
returnToResourceContainer(): Promise<void>;
|
|
63
70
|
startBlankBpmnDiagram(): Promise<void>;
|
|
71
|
+
showAllWorkspaces(probeTimeout: number): Promise<void>;
|
|
64
72
|
private becameVisible;
|
|
73
|
+
private createWorkspaceViaWizard;
|
|
65
74
|
clickHomeBreadcrumb(): Promise<void>;
|
|
66
75
|
private dismissBlockingDialogs;
|
|
67
76
|
clickOpenOrganizationsButton(): Promise<void>;
|
|
@@ -70,6 +79,7 @@ declare class ModelerHomePage {
|
|
|
70
79
|
clickCrossComponentProjectFolder(): Promise<void>;
|
|
71
80
|
private clickCrossComponentProjectFolderWithRetry;
|
|
72
81
|
createCrossComponentProjectFolder(): Promise<void>;
|
|
82
|
+
private enterProjectInsideWorkspace;
|
|
73
83
|
clickManageButton(retries?: number): Promise<void>;
|
|
74
84
|
clickUploadFilesButton(): Promise<void>;
|
|
75
85
|
clickMessageBanner(): Promise<void>;
|