@camunda/e2e-test-suite 0.0.1017 → 0.0.1018

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.
@@ -20,6 +20,7 @@ declare class LoginPage {
20
20
  readonly loginMessage: Locator;
21
21
  readonly errorMessage: Locator;
22
22
  readonly passwordHeading: Locator;
23
+ readonly rateLimitError: Locator;
23
24
  constructor(page: Page);
24
25
  fillUsername(username: string): Promise<void>;
25
26
  clickContinueButton(): Promise<void>;
@@ -19,6 +19,7 @@ class LoginPage {
19
19
  loginMessage;
20
20
  errorMessage;
21
21
  passwordHeading;
22
+ rateLimitError;
22
23
  constructor(page) {
23
24
  this.page = page;
24
25
  this.usernameInput = {
@@ -39,6 +40,16 @@ class LoginPage {
39
40
  this.passwordHeading = page.getByRole('heading', {
40
41
  name: 'Enter Your Password',
41
42
  });
43
+ // The identity provider occasionally returns a generic error / rate
44
+ // limit page under load ("...rate limit has been reached") that has
45
+ // none of the usual auth controls. Ported from 8.9's LoginPage.ts
46
+ // (fix(8.9): back off when Auth0 returns rate-limit page) -- 8.10 was
47
+ // missing this detection entirely, so a rate-limited login here fell
48
+ // through to the generic 10-20s retry backoff instead of the 60-90s
49
+ // needed to outlast a typical rate-limit window.
50
+ this.rateLimitError = page
51
+ .getByText(/rate limit has been reached/i)
52
+ .or(page.getByText(/We are sorry, an error occurred/i));
42
53
  this.loginButton = page.getByRole('button', {
43
54
  name: 'Continue',
44
55
  exact: true,
@@ -45,6 +45,19 @@ async function waitForLoginForm(page, loginPage, totalTimeout = 90000, roundTime
45
45
  let lastState = 'no login form';
46
46
  while (Date.now() < deadline) {
47
47
  const round = Math.min(roundTimeout, deadline - Date.now());
48
+ // The identity provider occasionally returns a generic error / rate
49
+ // limit page that has none of the usual auth controls. Checked once per
50
+ // iteration, outside expect.poll: a throw inside a poll predicate is
51
+ // swallowed and retried by design, which would burn this function's
52
+ // whole budget waiting for a login form that will never appear. Bailing
53
+ // out immediately with a typed marker lets loginWithRetry's caller back
54
+ // off long enough to actually outlast the rate-limit window instead.
55
+ if (await loginPage.rateLimitError
56
+ .first()
57
+ .isVisible()
58
+ .catch(() => false)) {
59
+ throw new Error('AUTH0_RATE_LIMIT: identity provider returned an error page');
60
+ }
48
61
  try {
49
62
  // Confirm we reached the login page before filling credentials.
50
63
  // Without this check the locator for 'Email address' can match a hidden
@@ -87,7 +100,7 @@ async function waitForLoginForm(page, loginPage, totalTimeout = 90000, roundTime
87
100
  }
88
101
  throw new Error(`Auth0 login form did not render within ${totalTimeout}ms: ${lastState}`);
89
102
  }
90
- async function loginWithRetry(page, loginPage, testUser, timeout, maxRetries = 3) {
103
+ async function loginWithRetry(page, loginPage, testUser, timeout, maxRetries = 5) {
91
104
  let lastError;
92
105
  for (let attempt = 0; attempt < maxRetries; attempt++) {
93
106
  try {
@@ -145,8 +158,17 @@ async function loginWithRetry(page, loginPage, testUser, timeout, maxRetries = 3
145
158
  catch (error) {
146
159
  lastError = error;
147
160
  if (attempt < maxRetries - 1) {
161
+ const rateLimited = String(error).includes('AUTH0_RATE_LIMIT');
148
162
  console.warn(`Attempt ${attempt + 1} failed for logging in. Retrying with clean session...`, error);
149
- await (0, randomSleep_1.randomSleep)(10000, 20000);
163
+ if (rateLimited) {
164
+ // Auth0 rate-limit windows commonly last 30-90s. Back off long
165
+ // enough to outlast the window before the next attempt, rather
166
+ // than retrying inside it and burning another attempt for free.
167
+ await (0, randomSleep_1.randomSleep)(60000, 90000);
168
+ }
169
+ else {
170
+ await (0, randomSleep_1.randomSleep)(10000, 20000);
171
+ }
150
172
  }
151
173
  else {
152
174
  console.error(lastError);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1017",
3
+ "version": "0.0.1018",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",