@camunda/e2e-test-suite 0.0.944 → 0.0.945
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.10/AppsPage.d.ts +5 -0
- package/dist/pages/8.10/AppsPage.js +152 -0
- package/dist/pages/8.10/ModelerHomePage.d.ts +1 -0
- package/dist/pages/8.10/ModelerHomePage.js +52 -5
- package/dist/pages/8.10/OperateHomePage.js +23 -2
- package/dist/pages/8.10/OperateProcessInstancePage.d.ts +17 -3
- package/dist/pages/8.10/OperateProcessInstancePage.js +718 -16
- package/dist/pages/8.10/OperateProcessesPage.d.ts +1 -0
- package/dist/pages/8.10/OperateProcessesPage.js +38 -2
- package/dist/pages/8.10/OptimizeHomePage.d.ts +5 -0
- package/dist/pages/8.10/OptimizeHomePage.js +138 -0
- package/dist/pages/8.10/OptimizeReportPage.d.ts +1 -0
- package/dist/pages/8.10/OptimizeReportPage.js +25 -0
- package/dist/pages/8.10/TaskPanelPage.d.ts +2 -1
- package/dist/pages/8.10/TaskPanelPage.js +37 -9
- package/dist/pages/8.10/UtilitiesPage.d.ts +2 -1
- package/dist/pages/8.10/UtilitiesPage.js +155 -23
- package/dist/pages/SM-8.10/KeycloakAdminPage.js +1 -1
- package/dist/pages/SM-8.10/KeycloakLoginPage.d.ts +1 -0
- package/dist/pages/SM-8.10/KeycloakLoginPage.js +8 -1
- package/dist/pages/SM-8.10/LoginPage.d.ts +1 -1
- package/dist/pages/SM-8.10/LoginPage.js +11 -2
- package/dist/pages/SM-8.10/NavigationPage.d.ts +1 -0
- package/dist/pages/SM-8.10/NavigationPage.js +86 -8
- package/dist/pages/SM-8.10/OCIdentityHomePage.js +12 -2
- package/dist/pages/SM-8.10/OCIdentityRolesPage.d.ts +3 -0
- package/dist/pages/SM-8.10/OCIdentityRolesPage.js +110 -4
- package/dist/pages/SM-8.10/OperateHomePage.js +13 -1
- package/dist/pages/SM-8.10/OperateProcessesPage.d.ts +1 -0
- package/dist/pages/SM-8.10/OperateProcessesPage.js +37 -18
- package/dist/pages/SM-8.10/OptimizeReportPage.js +21 -1
- package/dist/pages/SM-8.10/TaskDetailsPage.js +7 -0
- package/dist/pages/SM-8.10/UtilitiesPage.js +15 -4
- package/dist/pages/SM-8.10/optimizeReportUtils.js +30 -4
- package/dist/tests/8.10/smoke-tests.spec.js +182 -44
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.js +4 -0
- package/package.json +1 -1
|
@@ -21,7 +21,12 @@ declare class AppsPage {
|
|
|
21
21
|
constructor(page: Page);
|
|
22
22
|
clickCluster(component: Locator, name: string): Promise<void>;
|
|
23
23
|
clickModeler(): Promise<void>;
|
|
24
|
+
private isModelerAuthTransit;
|
|
25
|
+
openModelerWithRetry(banner: Locator, timeout?: number, maxRetries?: number): Promise<void>;
|
|
26
|
+
openOperateWithRetry(banner: Locator, clusterName: string, timeout?: number, maxRetries?: number): Promise<void>;
|
|
24
27
|
clickTasklist(clusterName: string): Promise<void>;
|
|
28
|
+
openTasklistWithRetry(banner: Locator, clusterName: string, timeout?: number, maxRetries?: number): Promise<void>;
|
|
29
|
+
openOptimizeWithRetry(banner: Locator, clusterName: string, timeout?: number, maxRetries?: number): Promise<void>;
|
|
25
30
|
clickAdmin(clusterName: string): Promise<void>;
|
|
26
31
|
private doClickClusterInOperate;
|
|
27
32
|
private doClickClusterInTasklist;
|
|
@@ -113,6 +113,99 @@ class AppsPage {
|
|
|
113
113
|
}
|
|
114
114
|
throw new Error(`Failed to click the modeler link after ${maxRetries} attempts.`);
|
|
115
115
|
}
|
|
116
|
+
// True while the tab is still inside the Modeler's OAuth hand-off rather
|
|
117
|
+
// than on a Modeler page: `modeler.<host>/login` bounces through the IdP and
|
|
118
|
+
// commits `/login-callback?code=...` before the app itself renders.
|
|
119
|
+
isModelerAuthTransit() {
|
|
120
|
+
try {
|
|
121
|
+
const { hostname, pathname } = new URL(this.page.url());
|
|
122
|
+
return (hostname.startsWith('modeler.') &&
|
|
123
|
+
/^\/login(-callback)?\/?$/.test(pathname));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Not a parsable URL yet (e.g. a tab still on about:blank).
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// The Modeler OAuth handshake occasionally stalls on
|
|
131
|
+
// `modeler.<host>/login-callback?code=...`: the tab stays on the callback
|
|
132
|
+
// URL and the Modeler banner never renders. Reloading cannot recover it —
|
|
133
|
+
// the `code` is single use — so re-enter through the Camunda apps menu,
|
|
134
|
+
// which starts a fresh handshake.
|
|
135
|
+
async openModelerWithRetry(banner, timeout = 60000, maxRetries = 3) {
|
|
136
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
137
|
+
await this.clickCamundaApps();
|
|
138
|
+
await this.clickModeler();
|
|
139
|
+
try {
|
|
140
|
+
await (0, test_1.expect)(banner).toBeVisible({ timeout });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// Never tear down a hand-off that is still in flight. `modeler
|
|
145
|
+
// .<host>/login` runs an invisible reCAPTCHA before it even reaches
|
|
146
|
+
// the IdP, so on SaaS the tab routinely leaves `/login` for
|
|
147
|
+
// `/login-callback?code=...` only just AFTER this window lapses.
|
|
148
|
+
// Re-entering through the apps menu at that moment aborts an exchange
|
|
149
|
+
// that was about to finish and starts an identical one, which is then
|
|
150
|
+
// cut at the very same mark — three attempts, three restarts, and the
|
|
151
|
+
// banner never renders even though nothing was actually wrong. The
|
|
152
|
+
// trace of such a run shows `/login` committing `/login-callback`
|
|
153
|
+
// 60.3s into a 60s wait, three times over. Give a hand-off that is
|
|
154
|
+
// still in transit one more window to settle before treating the
|
|
155
|
+
// attempt as failed; a tab that is genuinely wedged spends it and
|
|
156
|
+
// falls through to the re-entry below exactly as before.
|
|
157
|
+
if (this.isModelerAuthTransit()) {
|
|
158
|
+
try {
|
|
159
|
+
await (0, test_1.expect)(banner).toBeVisible({ timeout });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
catch (settleError) {
|
|
163
|
+
console.warn(`Modeler hand-off did not settle within the extra window: ` +
|
|
164
|
+
`${settleError}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (attempt === maxRetries - 1) {
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
console.warn(`Modeler banner not visible on attempt ${attempt + 1}; ` +
|
|
171
|
+
're-entering through the apps menu.');
|
|
172
|
+
await this.page.goto('/', { waitUntil: 'domcontentloaded' });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// The hand-off into Operate can resolve without the app ever coming up:
|
|
177
|
+
// `clickOperate` returns as soon as its click resolves, so a click that
|
|
178
|
+
// landed while the apps menu was being torn down — or a cluster hand-off
|
|
179
|
+
// that stalls on the proxy — leaves the tab on whatever app it started from.
|
|
180
|
+
// The caller then looks for Operate's nav on a page that is not Operate, and
|
|
181
|
+
// because Tasklist ships a "Processes" link of its own that lookup can even
|
|
182
|
+
// SUCCEED: the click goes to Tasklist's Processes tab, and the wait for
|
|
183
|
+
// Operate's own Processes view (`expanded-panel` > "Process") afterwards can
|
|
184
|
+
// never resolve. That is what reported "Failed to click locator
|
|
185
|
+
// getByRole('link', { name: 'Processes', exact: true })" on one hand and
|
|
186
|
+
// "Failed to assert visibility locator getByTestId('expanded-panel')
|
|
187
|
+
// .getByText('Process', { exact: true })" on the other. Gate on Operate's
|
|
188
|
+
// banner and re-enter through the apps menu when it never renders — the same
|
|
189
|
+
// recovery `openModelerWithRetry` uses for the identical Modeler
|
|
190
|
+
// `login-callback` stall.
|
|
191
|
+
async openOperateWithRetry(banner, clusterName, timeout = 60000, maxRetries = 3) {
|
|
192
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
193
|
+
await this.clickCamundaApps();
|
|
194
|
+
await this.clickOperate(clusterName);
|
|
195
|
+
try {
|
|
196
|
+
await (0, test_1.expect)(banner).toBeVisible({ timeout });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
if (attempt === maxRetries - 1) {
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
console.warn(`Operate banner not visible on attempt ${attempt + 1}; ` +
|
|
204
|
+
're-entering through the apps menu.');
|
|
205
|
+
await this.page.goto('/', { waitUntil: 'domcontentloaded' });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
116
209
|
async clickTasklist(clusterName) {
|
|
117
210
|
const maxRetries = 3;
|
|
118
211
|
for (let retries = 0; retries < maxRetries; retries++) {
|
|
@@ -157,6 +250,65 @@ class AppsPage {
|
|
|
157
250
|
}
|
|
158
251
|
throw new Error(`Failed to click the tasklist link after ${maxRetries} attempts.`);
|
|
159
252
|
}
|
|
253
|
+
// Same hand-off failure `openOperateWithRetry` above exists to catch, on the
|
|
254
|
+
// other app: `clickTasklist` returns as soon as its click resolves, so a
|
|
255
|
+
// click that landed while the apps menu was being torn down — or a cluster
|
|
256
|
+
// hand-off that stalls on the proxy — leaves the tab on the app it started
|
|
257
|
+
// from. The caller then polls THAT page for a task row which can never be
|
|
258
|
+
// there, and the reload each polling round performs cannot recover a
|
|
259
|
+
// hand-off that never happened — it re-renders the same wrong app. That is
|
|
260
|
+
// what reported `Task <name> did not open from "Available tasks"` on a run
|
|
261
|
+
// whose instance was already confirmed ACTIVE in Operate one step earlier.
|
|
262
|
+
// Gate on Tasklist's own banner and re-enter through the apps menu when it
|
|
263
|
+
// never renders.
|
|
264
|
+
async openTasklistWithRetry(banner, clusterName, timeout = 60000, maxRetries = 3) {
|
|
265
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
266
|
+
await this.clickCamundaApps();
|
|
267
|
+
await this.clickTasklist(clusterName);
|
|
268
|
+
try {
|
|
269
|
+
await (0, test_1.expect)(banner).toBeVisible({ timeout });
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
if (attempt === maxRetries - 1) {
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
console.warn(`Tasklist banner not visible on attempt ${attempt + 1}; ` +
|
|
277
|
+
're-entering through the apps menu.');
|
|
278
|
+
await this.page.goto('/', { waitUntil: 'domcontentloaded' });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// The third instance of the hand-off failure `openOperateWithRetry` and
|
|
283
|
+
// `openTasklistWithRetry` above exist to catch — and the only app hop in the
|
|
284
|
+
// smoke flow that was still ungated. `clickOptimize` returns as soon as its
|
|
285
|
+
// click resolves, so a hand-off that stalled (or that landed on Optimize's
|
|
286
|
+
// `/login` SSO bounce rather than the app) leaves the tab somewhere that can
|
|
287
|
+
// never render a process definition. The caller's import poll then spends
|
|
288
|
+
// its ENTIRE budget — the longest single wait in the flow, 20 minutes —
|
|
289
|
+
// reloading that page, and a reload cannot recover a hand-off that never
|
|
290
|
+
// happened. Gating here fails in 3 x 60s with a diagnostic naming the hop
|
|
291
|
+
// instead. Every other 8.10 spec already asserts `optimizeBanner` right
|
|
292
|
+
// after `clickOptimize` for exactly this reason; only the smoke flow did
|
|
293
|
+
// not.
|
|
294
|
+
async openOptimizeWithRetry(banner, clusterName, timeout = 60000, maxRetries = 3) {
|
|
295
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
296
|
+
await this.clickCamundaApps();
|
|
297
|
+
await this.clickOptimize(clusterName);
|
|
298
|
+
try {
|
|
299
|
+
await (0, test_1.expect)(banner).toBeVisible({ timeout });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
if (attempt === maxRetries - 1) {
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
console.warn(`Optimize banner not visible on attempt ${attempt + 1}; ` +
|
|
307
|
+
're-entering through the apps menu.');
|
|
308
|
+
await this.page.goto('/', { waitUntil: 'domcontentloaded' });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
160
312
|
async clickAdmin(clusterName) {
|
|
161
313
|
const maxRetries = 5;
|
|
162
314
|
for (let retries = 0; retries < maxRetries; retries++) {
|
|
@@ -38,6 +38,7 @@ declare class ModelerHomePage {
|
|
|
38
38
|
clickBpmnTemplateOption(): Promise<void>;
|
|
39
39
|
clickFormOption(): Promise<void>;
|
|
40
40
|
enterFormName(name: string): Promise<void>;
|
|
41
|
+
enterFormNameWithRetry(name: string): Promise<void>;
|
|
41
42
|
clickProjectBreadcrumb(): Promise<void>;
|
|
42
43
|
clickHomeBreadcrumb(): Promise<void>;
|
|
43
44
|
clickOpenOrganizationsButton(): Promise<void>;
|
|
@@ -62,9 +62,15 @@ class ModelerHomePage {
|
|
|
62
62
|
this.homeBreadcrumb = page.locator('[data-test="breadcrumb-home"]');
|
|
63
63
|
this.openOrganizationsButton = page.getByLabel('Open Organizations');
|
|
64
64
|
this.manageButton = page.getByRole('menuitem', { name: 'Manage' });
|
|
65
|
-
|
|
65
|
+
// `.first()` keeps this usable in an org that already accumulated more
|
|
66
|
+
// than one project with this name — an unscoped by-title match throws a
|
|
67
|
+
// strict-mode violation the moment a duplicate exists, which fails every
|
|
68
|
+
// later run in that org rather than just the run that created it.
|
|
69
|
+
this.crossComponentProjectFolder = page
|
|
70
|
+
.getByTitle(this.defaultFolderName, {
|
|
66
71
|
exact: true,
|
|
67
|
-
})
|
|
72
|
+
})
|
|
73
|
+
.first();
|
|
68
74
|
this.rows = page.getByRole('row');
|
|
69
75
|
this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
|
|
70
76
|
this.messageBanner = page.locator('[data-test="close-top-banner"]');
|
|
@@ -157,8 +163,13 @@ class ModelerHomePage {
|
|
|
157
163
|
await process.click();
|
|
158
164
|
}
|
|
159
165
|
async clickDiagramTypeDropdown() {
|
|
166
|
+
// Navigation-class wait: this is the first control on the project page, so
|
|
167
|
+
// it is reached right after navigating into the project (or back via the
|
|
168
|
+
// breadcrumb) and its render waits on the project's resource list. 15s was
|
|
169
|
+
// short enough that a slow project load failed with
|
|
170
|
+
// `locator('[data-test="diagram-dropdown"]') ... element(s) not found`.
|
|
160
171
|
await (0, test_1.expect)(this.diagramTypeDropdown).toBeVisible({
|
|
161
|
-
timeout:
|
|
172
|
+
timeout: 60000,
|
|
162
173
|
});
|
|
163
174
|
await this.diagramTypeDropdown.click();
|
|
164
175
|
}
|
|
@@ -176,6 +187,33 @@ class ModelerHomePage {
|
|
|
176
187
|
await this.formNameInput.fill(name);
|
|
177
188
|
await this.formNameInput.press('Enter');
|
|
178
189
|
}
|
|
190
|
+
// Re-enters the name until the breadcrumb reflects it. Web Modeler mounts
|
|
191
|
+
// the inline name field as soon as the form editor opens, before it is wired
|
|
192
|
+
// to the rename mutation, so a fill that lands in that window is silently
|
|
193
|
+
// discarded: the form keeps its default "New form" name and the breadcrumb
|
|
194
|
+
// never shows the requested one. Nothing retried that, so a single lost
|
|
195
|
+
// keystroke made the caller's `assertFormBreadcrumbVisible` wait out its
|
|
196
|
+
// whole 120s on a form that was never going to be renamed
|
|
197
|
+
// (`button[data-test="breadcrumb-form"] ... element(s) not found`). Verifying
|
|
198
|
+
// with a short per-attempt budget turns that into one cheap retry. The
|
|
199
|
+
// caller's assertion stays the authority: this returns after the last
|
|
200
|
+
// attempt rather than throwing, so the failure is still reported by the
|
|
201
|
+
// assertion and not by a helper.
|
|
202
|
+
async enterFormNameWithRetry(name) {
|
|
203
|
+
const maxRetries = 3;
|
|
204
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
205
|
+
await this.enterFormName(name);
|
|
206
|
+
const renamed = await this.formNameBreadcrumb(name)
|
|
207
|
+
.waitFor({ state: 'visible', timeout: 30000 })
|
|
208
|
+
.then(() => true)
|
|
209
|
+
.catch(() => false);
|
|
210
|
+
if (renamed) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
console.warn(`Form rename to "${name}" has not reached the breadcrumb ` +
|
|
214
|
+
`(attempt ${attempt}/${maxRetries}). Re-entering the name.`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
179
217
|
async clickProjectBreadcrumb() {
|
|
180
218
|
await this.projectBreadcrumb.click({ timeout: 60000 });
|
|
181
219
|
}
|
|
@@ -233,9 +271,18 @@ class ModelerHomePage {
|
|
|
233
271
|
});
|
|
234
272
|
}
|
|
235
273
|
async createCrossComponentProjectFolder() {
|
|
236
|
-
await (0, sleep_1.sleep)(15000);
|
|
237
274
|
await this.dismissOverlays();
|
|
238
|
-
|
|
275
|
+
// The projects list renders asynchronously, so an instantaneous
|
|
276
|
+
// isVisible() reports "missing" whenever the list is still loading — and
|
|
277
|
+
// this method then creates a SECOND project with the same name. Those
|
|
278
|
+
// duplicates are permanent and break every subsequent run for that user,
|
|
279
|
+
// so wait for the folder to actually show up before concluding it is
|
|
280
|
+
// absent (this also replaces the blind 15s sleep the check relied on).
|
|
281
|
+
const folderExists = await this.crossComponentProjectFolder
|
|
282
|
+
.waitFor({ state: 'visible', timeout: 60000 })
|
|
283
|
+
.then(() => true)
|
|
284
|
+
.catch(() => false);
|
|
285
|
+
if (folderExists) {
|
|
239
286
|
console.log('Cross Component Project folder already exists. Clicking into it');
|
|
240
287
|
await this.clickCrossComponentProjectFolder();
|
|
241
288
|
return;
|
|
@@ -54,12 +54,20 @@ class OperateHomePage {
|
|
|
54
54
|
this.messageBanner = page.getByRole('button', { name: 'Close' });
|
|
55
55
|
}
|
|
56
56
|
async clickProcessesTab() {
|
|
57
|
+
// `clickLocatorWithRetry` stops at whichever of `maxRetries` and
|
|
58
|
+
// `totalTimeout` is reached first. One failing attempt here costs up to
|
|
59
|
+
// ~47s (the banner pre-action plus the 30s visibility waits), so a 120s
|
|
60
|
+
// budget cut the 5 configured retries down to 3 — this method is reached
|
|
61
|
+
// right after switching apps, while the cluster SSO hand-off into Operate
|
|
62
|
+
// is often still in flight, and it reported "Failed to click locator
|
|
63
|
+
// getByRole('link', { name: 'Processes', exact: true }) after 3 attempts"
|
|
64
|
+
// after barely two minutes. Give the configured retries room to run.
|
|
57
65
|
await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.processesTab, {
|
|
58
66
|
preAction: async () => {
|
|
59
67
|
await this.clickMessageBanner();
|
|
60
68
|
},
|
|
61
69
|
maxRetries: 5,
|
|
62
|
-
totalTimeout:
|
|
70
|
+
totalTimeout: 300000,
|
|
63
71
|
visibilityTimeout: 30000,
|
|
64
72
|
});
|
|
65
73
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.processPageHeading, {
|
|
@@ -67,8 +75,21 @@ class OperateHomePage {
|
|
|
67
75
|
await (0, test_1.expect)(this.processesTab).toBeVisible({ timeout: 10000 });
|
|
68
76
|
await this.processesTab.click({ timeout: 10000 });
|
|
69
77
|
},
|
|
78
|
+
// The Processes view routinely needs longer than this helper's default
|
|
79
|
+
// 10s per attempt to render on a loaded cluster — the same 30s the tab
|
|
80
|
+
// click above already assumes for this nav, and what SM-8.10 uses for
|
|
81
|
+
// this very assertion. With the default, all 5 attempts could expire
|
|
82
|
+
// inside ~1 min of the 5 min budget and report "Failed to assert
|
|
83
|
+
// visibility locator getByTestId('expanded-panel').getByText('Process',
|
|
84
|
+
// { exact: true }) after 5 attempts" while the view was still on its way.
|
|
85
|
+
visibilityTimeout: 30000,
|
|
86
|
+
// Re-clicking the tab cannot help a view that never rendered, so reload
|
|
87
|
+
// between attempts and let each one re-ask Operate for the page.
|
|
88
|
+
postAction: async () => {
|
|
89
|
+
await this.page.reload();
|
|
90
|
+
},
|
|
70
91
|
maxRetries: 5,
|
|
71
|
-
totalTimeout:
|
|
92
|
+
totalTimeout: 300000,
|
|
72
93
|
});
|
|
73
94
|
}
|
|
74
95
|
async closeInformationDialog() {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { Page, Locator } from '@playwright/test';
|
|
1
|
+
import { Page, Locator, BrowserContext } from '@playwright/test';
|
|
2
|
+
type InstanceUrlWatcher = () => string | undefined;
|
|
3
|
+
declare function watchOperateInstanceUrl(context: BrowserContext): InstanceUrlWatcher;
|
|
2
4
|
declare class OperateProcessInstancePage {
|
|
3
5
|
private page;
|
|
6
|
+
private instanceUrl;
|
|
4
7
|
readonly diagram: Locator;
|
|
5
8
|
readonly completedIcon: Locator;
|
|
6
9
|
readonly diagramSpinner: Locator;
|
|
7
10
|
readonly activeIcon: Locator;
|
|
8
11
|
readonly incidentIcon: Locator;
|
|
12
|
+
readonly incidentsBanner: Locator;
|
|
9
13
|
readonly userTaskOpenTasklistLink: Locator;
|
|
10
14
|
readonly taskDetailsPopOver: Locator;
|
|
11
15
|
readonly connectorResultVariableName: (name: string) => Locator;
|
|
@@ -15,8 +19,18 @@ declare class OperateProcessInstancePage {
|
|
|
15
19
|
readonly gotItButton: Locator;
|
|
16
20
|
constructor(page: Page);
|
|
17
21
|
connectorResultVariableValue(variableName: string): Promise<Locator>;
|
|
22
|
+
rememberInstanceUrl(timeout?: number, watchedUrl?: InstanceUrlWatcher): Promise<void>;
|
|
23
|
+
private hasBouncedToList;
|
|
24
|
+
private waitForAuthToSettle;
|
|
25
|
+
private isStateIconWait;
|
|
26
|
+
private describeIncident;
|
|
27
|
+
private describeRenderedState;
|
|
28
|
+
waitForInstanceLocator(locator: Locator, description: string, totalTimeout?: number, pollTimeout?: number): Promise<void>;
|
|
29
|
+
dismissWhatsNewIfVisible(): Promise<void>;
|
|
18
30
|
closePopOverIfVisible(): Promise<void>;
|
|
19
|
-
|
|
31
|
+
private clusterHost;
|
|
32
|
+
private reenterViaConsole;
|
|
33
|
+
reload(): Promise<boolean>;
|
|
20
34
|
assertProcessCompleteStatusWithRetry(timeout?: number, maxRetries?: number): Promise<void>;
|
|
21
35
|
assertProcessVariableContainsText(variableName: string, text: string): Promise<void>;
|
|
22
36
|
assertProcessVariableHasDocumentCount(variableName: string, count: number, softFail?: boolean): Promise<void>;
|
|
@@ -25,4 +39,4 @@ declare class OperateProcessInstancePage {
|
|
|
25
39
|
assertDetailsPopoverIsVisible(): Promise<void>;
|
|
26
40
|
assertBusinessIdVisible(businessId: string): Promise<void>;
|
|
27
41
|
}
|
|
28
|
-
export { OperateProcessInstancePage };
|
|
42
|
+
export { OperateProcessInstancePage, watchOperateInstanceUrl };
|