@camunda/e2e-test-suite 0.0.1239 → 0.0.1241

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.
@@ -14,11 +14,12 @@ declare class NavigationPage {
14
14
  goTo(url: string, banner: Locator, sleepTimeout?: number, { username, password, }?: {
15
15
  username?: string;
16
16
  password?: string;
17
- }, maxRetries?: number): Promise<void>;
17
+ }, maxRetries?: number, beforeBannerCheck?: () => Promise<void>): Promise<void>;
18
18
  goToModeler(sleepTimeout?: number, credentials?: {
19
19
  username: string;
20
20
  password: string;
21
21
  }): Promise<void>;
22
+ private dismissOnboardingDialog;
22
23
  goToTasklist(sleepTimeout?: number, credentials?: {
23
24
  username: string;
24
25
  password: string;
@@ -112,12 +112,15 @@ class NavigationPage {
112
112
  // that is exactly the reported "Login (/modeler) failed after 8 attempts".
113
113
  // The 60s budget is unchanged: a genuinely slow shell still gets all of it,
114
114
  // and a sustained outage still fails.
115
- async waitForBanner(url, banner, submitted) {
115
+ async waitForBanner(url, banner, submitted, beforeBannerCheck) {
116
116
  const totalTimeout = constants_1._1_SECOND_IN_MS * 60;
117
117
  const deadline = Date.now() + totalTimeout;
118
118
  let lastState = 'no banner';
119
119
  while (Date.now() < deadline) {
120
120
  const round = Math.min(constants_1._1_SECOND_IN_MS * 20, deadline - Date.now());
121
+ if (beforeBannerCheck) {
122
+ await beforeBannerCheck();
123
+ }
121
124
  try {
122
125
  await (0, test_1.expect)(banner).toBeVisible({ timeout: round });
123
126
  return;
@@ -145,7 +148,7 @@ class NavigationPage {
145
148
  }
146
149
  throw new Error(`${url} did not render its banner within ${totalTimeout}ms: ${lastState}`);
147
150
  }
148
- async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 8) {
151
+ async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 8, beforeBannerCheck) {
149
152
  const startTime = Date.now();
150
153
  let timeout = constants_1._1_SECOND_IN_MS * 10;
151
154
  if (url === '/modeler') {
@@ -214,7 +217,7 @@ class NavigationPage {
214
217
  else {
215
218
  submitted = await loginPage.login(username, password);
216
219
  }
217
- await this.waitForBanner(url, banner, submitted);
220
+ await this.waitForBanner(url, banner, submitted, beforeBannerCheck);
218
221
  return;
219
222
  }
220
223
  catch (error) {
@@ -261,7 +264,35 @@ class NavigationPage {
261
264
  }
262
265
  }
263
266
  async goToModeler(sleepTimeout, credentials) {
264
- await this.goTo(MODELER_CONTEXT_PATH, this.modelerPageBanner, sleepTimeout, credentials);
267
+ await this.goTo(MODELER_CONTEXT_PATH, this.modelerPageBanner, sleepTimeout, credentials, 8, () => this.dismissOnboardingDialog());
268
+ }
269
+ // After the Camunda Hub rebrand a first visit to Modeler home greets the user
270
+ // with a multi-step "Welcome to Camunda Hub" onboarding dialog. It mounts over
271
+ // the home and marks the app shell inert, so the "Camunda Modeler home" banner
272
+ // link leaves the accessibility tree until the dialog is dismissed -- gating on
273
+ // the banner alone then loops until the whole login budget is spent. Close it
274
+ // through the dialog's own control before each banner check so the banner can
275
+ // resolve; only unambiguous dismissals are matched (never "Cancel", which is a
276
+ // form action on the dialogs other flows open on purpose).
277
+ async dismissOnboardingDialog() {
278
+ // On the Design System shell the onboarding is a multi-step wizard: its
279
+ // footer button reads "Next" (an advance, not a dismissal) and its only
280
+ // single-click close is the header control -- a ghost icon button
281
+ // (data-slot="dialog-close") wrapping an aria-hidden "x" svg, so it exposes
282
+ // no accessible name and getByRole({name}) cannot reach it. Target that
283
+ // control by its stable data-slot; keep the named-button fallback for the
284
+ // Carbon announcement modals other flows meet ("Got it"/"Close"/"Dismiss",
285
+ // never "Cancel", which is a form action). Scope to the visible dialog: the
286
+ // home keeps several hidden role="dialog" containers mounted.
287
+ const dialog = this.page.locator('[role="dialog"]:visible').first();
288
+ const dismiss = dialog
289
+ .locator('[data-slot="dialog-close"]')
290
+ .or(dialog.getByRole('button', { name: /^(Got it|Close|Dismiss)/i }))
291
+ .first();
292
+ await dismiss
293
+ .waitFor({ state: 'visible', timeout: 3000 })
294
+ .then(() => dismiss.click())
295
+ .catch(() => { });
265
296
  }
266
297
  async goToTasklist(sleepTimeout, credentials) {
267
298
  await this.goTo(`${NORMALIZED_ORCHESTRATION_CONTEXT_PATH}/tasklist`, this.tasklistPageBanner, sleepTimeout, credentials);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1239",
3
+ "version": "0.0.1241",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",