@camunda/e2e-test-suite 0.0.864 → 0.0.866

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.
@@ -50,6 +50,7 @@ declare class ClusterDetailsPage {
50
50
  readonly tasklistV2RadioButton: Locator;
51
51
  constructor(page: Page);
52
52
  clickAPITab(): Promise<void>;
53
+ dismissOopsIfPresent(): Promise<void>;
53
54
  clickCreateClientButton(): Promise<void>;
54
55
  clickClientNameTextbox(): Promise<void>;
55
56
  fillClientNameTextbox(name: string): Promise<void>;
@@ -177,8 +177,33 @@ class ClusterDetailsPage {
177
177
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 60000 });
178
178
  await this.apiTab.click({ timeout: 60000 });
179
179
  }
180
+ async dismissOopsIfPresent() {
181
+ // The clients list panel sometimes lands in a Carbon "Oops ... something
182
+ // went wrong." state when a background ClustersService request fails on
183
+ // SaaS INT. The panel replaces the create-client button, so any click
184
+ // attempt will time out until the user clicks the inline Reload button.
185
+ const oopsHeading = this.page.getByRole('heading', { name: /Oops/i });
186
+ if (!(await oopsHeading.isVisible({ timeout: 1000 }).catch(() => false))) {
187
+ return;
188
+ }
189
+ const reloadButton = this.page.getByRole('button', {
190
+ name: 'Reload',
191
+ exact: true,
192
+ });
193
+ if (await reloadButton.isVisible({ timeout: 1000 }).catch(() => false)) {
194
+ await reloadButton.click({ timeout: 15000 }).catch(() => { });
195
+ }
196
+ else {
197
+ await this.page.reload();
198
+ }
199
+ await this.page.waitForLoadState('domcontentloaded');
200
+ }
180
201
  async clickCreateClientButton() {
181
- await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.createFirstClientButton.or(this.createNewClientButton));
202
+ await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.createFirstClientButton.or(this.createNewClientButton), {
203
+ preAction: async () => {
204
+ await this.dismissOopsIfPresent();
205
+ },
206
+ });
182
207
  }
183
208
  async clickClientNameTextbox() {
184
209
  await this.clientNameTextbox.click({ timeout: 60000 });
@@ -216,9 +216,18 @@ class ClusterSecretsPage {
216
216
  });
217
217
  }
218
218
  catch {
219
- // Import dialog didn't close - press Escape and let assertSecretsOrCreate handle creation
219
+ // Import dialog didn't close - press Escape and let assertSecretsOrCreate handle creation.
220
+ // The dialog getting stuck like this is usually a transient "Oops ...
221
+ // something went wrong" error panel replacing its normal content after
222
+ // the import submission (observed in run 30063427178: the panel
223
+ // rendered inside the dialog with its own Reload button). Escape only
224
+ // force-dismisses the dialog chrome - the page behind it is left in
225
+ // the same broken state, so createNewSecretButton below never renders
226
+ // without a reload first.
220
227
  await this.page.keyboard.press('Escape');
221
228
  await (0, test_1.expect)(this.dialog).not.toBeVisible({ timeout: 10000 });
229
+ await this.page.reload();
230
+ await (0, sleep_1.sleep)(5000);
222
231
  }
223
232
  await (0, test_1.expect)(this.createNewSecretButton).toBeVisible({
224
233
  timeout: 60000,
@@ -85,6 +85,35 @@ class LoginPage {
85
85
  await this.page
86
86
  .waitForURL((url) => !url.hostname.includes('console'), { timeout: 60000 })
87
87
  .catch(() => { });
88
+ // SSO re-auth may silently log us back in as the previous user instead
89
+ // of showing the Auth0 form (observed in nightly run 30065651822: landed
90
+ // on the authenticated Console dashboard, so none of the login-step
91
+ // checks below ever matched and authStep stayed 'unknown' for the full
92
+ // 120s). Detect that authenticated state via the Console's Settings
93
+ // button and force a logout, retrying until the Auth0 form appears.
94
+ const settingsBtn = this.page.getByLabel('Open Settings');
95
+ const logoutBtn = this.page.getByRole('button', { name: 'Log out' });
96
+ for (let i = 0; i < 3; i++) {
97
+ const onAuthPage = (await this.usernameInput.locator
98
+ .isVisible({ timeout: 5000 })
99
+ .catch(() => false)) ||
100
+ (await this.passwordHeading
101
+ .isVisible({ timeout: 2000 })
102
+ .catch(() => false)) ||
103
+ (await this.passwordInput
104
+ .isVisible({ timeout: 2000 })
105
+ .catch(() => false));
106
+ if (onAuthPage)
107
+ break;
108
+ if (await settingsBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
109
+ await settingsBtn.click({ timeout: 30000 });
110
+ await logoutBtn.click({ timeout: 30000 });
111
+ await this.page.waitForLoadState('domcontentloaded', { timeout: 30000 });
112
+ }
113
+ else {
114
+ break;
115
+ }
116
+ }
88
117
  let authStep = 'unknown';
89
118
  const deadline = Date.now() + 120000;
90
119
  while (Date.now() < deadline) {
@@ -58,7 +58,7 @@ class NavigationPage {
58
58
  .isVisible()
59
59
  .catch(() => false);
60
60
  }
61
- async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 5) {
61
+ async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 8) {
62
62
  const startTime = Date.now();
63
63
  let timeout = constants_1._1_SECOND_IN_MS * 10;
64
64
  if (url === '/modeler') {
@@ -118,10 +118,17 @@ class NavigationPage {
118
118
  const elapsed = Date.now() - startTime;
119
119
  if (attempt < maxRetries - 1) {
120
120
  // Progressive backoff: a transient Keycloak 5xx during the OAuth
121
- // login (the "We are sorry... internal server error" page) can
122
- // persist for several seconds. Widening the gap between attempts
123
- // (2s, 4s, 6s, 8s) lets the auth server recover instead of burning
124
- // every retry inside one short outage window.
121
+ // login (the "We are sorry... internal server error" /
122
+ // "Unexpected error when handling authentication request to
123
+ // identity provider" pages) can persist for several seconds.
124
+ // Widening the gap between attempts (2s, 4s, 6s, ...) lets the
125
+ // auth server recover instead of burning every retry inside one
126
+ // short outage window. Bumped from 5 to 8 retries after run
127
+ // 30080472743's "Basic Login" failed all 5 attempts against a
128
+ // freshly-installed cluster, each with a genuine 400/500 from
129
+ // Keycloak's own login-actions/authenticate endpoint -- the prior
130
+ // budget (~20s of backoff) wasn't consistently enough to outlast
131
+ // Keycloak's post-install warm-up window.
125
132
  await (0, sleep_1.sleep)(2000 * (attempt + 1));
126
133
  if (!this.page.isClosed()) {
127
134
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.864",
3
+ "version": "0.0.866",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",