@camunda/e2e-test-suite 0.0.1612 → 0.0.1613
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.
|
@@ -9,6 +9,7 @@ declare class ProcessApplicationPage {
|
|
|
9
9
|
readonly cancelButton: Locator;
|
|
10
10
|
readonly breadcrumb: Locator;
|
|
11
11
|
readonly folderExplorer: Locator;
|
|
12
|
+
readonly loadErrorState: Locator;
|
|
12
13
|
readonly createNewDropdown: Locator;
|
|
13
14
|
readonly inlineNameInput: Locator;
|
|
14
15
|
readonly defineStagesDialog: Locator;
|
|
@@ -33,6 +33,7 @@ class ProcessApplicationPage {
|
|
|
33
33
|
cancelButton;
|
|
34
34
|
breadcrumb;
|
|
35
35
|
folderExplorer;
|
|
36
|
+
loadErrorState;
|
|
36
37
|
createNewDropdown;
|
|
37
38
|
inlineNameInput;
|
|
38
39
|
// "Define stages" dialog, reached from the process application's "Connected
|
|
@@ -85,6 +86,11 @@ class ProcessApplicationPage {
|
|
|
85
86
|
});
|
|
86
87
|
this.breadcrumb = page.locator('[data-test="breadcrumb-process-application-menu"]');
|
|
87
88
|
this.folderExplorer = page.getByRole('region', { name: 'Folder explorer' });
|
|
89
|
+
// camunda-hub app/components/page/Page.tsx ErrorState: the design-system
|
|
90
|
+
// EmptyState that replaces the page body when its fetches fail.
|
|
91
|
+
this.loadErrorState = page.getByRole('heading', {
|
|
92
|
+
name: /^(Something went wrong|Not found)$/,
|
|
93
|
+
});
|
|
88
94
|
// The process application page renders more than one diagram-dropdown
|
|
89
95
|
// (hub's own unit tests reach for it with getAllByTestId), so the dropdown
|
|
90
96
|
// has to be resolved inside the folder explorer rather than page-wide.
|
|
@@ -133,30 +139,50 @@ class ProcessApplicationPage {
|
|
|
133
139
|
// absolute deadline: reload() otherwise inherits the 120s navigationTimeout
|
|
134
140
|
// and two slow reloads would eat the test budget during an outage. The last
|
|
135
141
|
// attempt is a plain assertion so a persistent outage still fails loudly.
|
|
142
|
+
//
|
|
143
|
+
// Reload only when it can help: as soon as Hub has rendered its error view
|
|
144
|
+
// (Page.tsx ErrorState -- "Something went wrong" or a "Not found" that a
|
|
145
|
+
// just-created application can briefly answer), or when one load has sat
|
|
146
|
+
// on the spinner for `stallAfter`. A fixed per-attempt cut-off used to
|
|
147
|
+
// reload pages that were still loading, so under load a ~40s render was
|
|
148
|
+
// restarted twice and the last attempt got ~37s -- not enough for a third
|
|
149
|
+
// render from scratch.
|
|
136
150
|
async waitWithReload(target, timeout, attempts = 3) {
|
|
137
151
|
const deadline = Date.now() + timeout;
|
|
138
|
-
const
|
|
152
|
+
const stallAfter = Math.ceil(timeout / 2);
|
|
139
153
|
const remaining = () => Math.max(deadline - Date.now(), 1000);
|
|
140
|
-
|
|
154
|
+
const settled = target.or(this.loadErrorState).first();
|
|
155
|
+
let reloadsLeft = attempts - 1;
|
|
156
|
+
let loadStartedAt = Date.now();
|
|
157
|
+
while (reloadsLeft > 0 && deadline - Date.now() > 1000) {
|
|
141
158
|
// Hub can drop its session on a navigation and bounce through
|
|
142
159
|
// /login-callback to the identity provider, where neither reloading nor
|
|
143
160
|
// waiting renders the content -- re-authenticate first.
|
|
144
|
-
await (0, sessionRecovery_1.recoverStuckModelerLogin)(this.page);
|
|
145
|
-
await (0, sessionRecovery_1.restoreSessionIfLoggedOut)(this.page);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
const recoveredLogin = await (0, sessionRecovery_1.recoverStuckModelerLogin)(this.page);
|
|
162
|
+
const restoredSession = await (0, sessionRecovery_1.restoreSessionIfLoggedOut)(this.page);
|
|
163
|
+
if (recoveredLogin || restoredSession) {
|
|
164
|
+
loadStartedAt = Date.now();
|
|
165
|
+
}
|
|
166
|
+
// Short slices so a session dropped mid-wait is still recovered above.
|
|
167
|
+
await settled
|
|
168
|
+
.waitFor({ state: 'visible', timeout: Math.min(15000, remaining()) })
|
|
169
|
+
.catch(() => undefined);
|
|
170
|
+
if (await target.isVisible()) {
|
|
151
171
|
return;
|
|
152
172
|
}
|
|
153
|
-
|
|
173
|
+
const errored = await this.loadErrorState.isVisible();
|
|
174
|
+
if (!errored && Date.now() - loadStartedAt < stallAfter) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
reloadsLeft--;
|
|
178
|
+
console.warn(`Process application content did not render (${errored ? 'Hub showed its error view' : 'still loading'}); reloading, ${reloadsLeft} reload(s) left.`);
|
|
154
179
|
// 'domcontentloaded': a reload that bounces through /login-callback
|
|
155
180
|
// never reaches "load", and recovery above needs the page back.
|
|
156
181
|
await this.page.reload({
|
|
157
182
|
waitUntil: 'domcontentloaded',
|
|
158
183
|
timeout: remaining(),
|
|
159
184
|
});
|
|
185
|
+
loadStartedAt = Date.now();
|
|
160
186
|
}
|
|
161
187
|
await (0, sessionRecovery_1.recoverStuckModelerLogin)(this.page);
|
|
162
188
|
await (0, sessionRecovery_1.restoreSessionIfLoggedOut)(this.page);
|