@commercetools-frontend/cypress 24.4.0 → 24.6.0

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.
@@ -47,6 +47,14 @@ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _
47
47
 
48
48
  // Alias for backwards compatibility
49
49
 
50
+ const defaultTimeouts = {
51
+ waitForEmailInput: 4000,
52
+ waitForPasswordInput: 8000,
53
+ waitForElement: 15000,
54
+ waitForUrl: 15000,
55
+ waitForRedirect: 3000,
56
+ waitForIdentityRedirect: 8000
57
+ };
50
58
  function isFeatureSupported(expectedVersion) {
51
59
  return semver__default["default"].gte(Cypress.version, expectedVersion);
52
60
  }
@@ -177,18 +185,26 @@ function loginByForm(commandOptions) {
177
185
  cy.origin(identityUrl, {
178
186
  args: {
179
187
  userCredentials,
180
- identityUrl
188
+ identityUrl,
189
+ timeouts: commandOptions.timeouts,
190
+ defaultTimeouts
181
191
  }
182
192
  }, _ref => {
183
193
  let userCredentials = _ref.userCredentials,
184
- identityUrl = _ref.identityUrl;
194
+ identityUrl = _ref.identityUrl,
195
+ timeouts = _ref.timeouts,
196
+ defaultTimeouts = _ref.defaultTimeouts;
185
197
  cy.url().should('include', `${identityUrl}/login`);
186
198
  // Fill in the email and click Next
187
- cy.get('input[name="identifier"]').type(userCredentials.email);
199
+ cy.get('input[name="identifier"]', {
200
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
201
+ }).type(userCredentials.email);
188
202
  cy.get('button').contains('Next').click();
189
203
 
190
204
  // Wait for the password form to appear
191
- cy.get('input[name="password"]').should('be.visible');
205
+ cy.get('input[name="password"]', {
206
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
207
+ }).should('be.visible');
192
208
  // Fill in the password and submit
193
209
  cy.get('input[name="password"]').type(userCredentials.password, {
194
210
  log: false
@@ -197,8 +213,14 @@ function loginByForm(commandOptions) {
197
213
  });
198
214
 
199
215
  // Wait for the flow to redirect back to the application.
200
- cy.get('[role="main"]').should('exist');
201
- cy.url().should('include', url);
216
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
217
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
218
+ cy.get('[role="main"]', {
219
+ timeout: commandOptions.timeouts?.waitForElement ?? defaultTimeouts.waitForElement
220
+ }).should('exist');
221
+ cy.url({
222
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
223
+ }).should('include', url);
202
224
  } else {
203
225
  const mcUrl = appConfig.mcApiUrl.replace('mc-api', 'mc');
204
226
  // See similar comment above regarding the usage of `cy.wait`.
@@ -207,16 +229,22 @@ function loginByForm(commandOptions) {
207
229
  cy.origin(mcUrl, {
208
230
  args: {
209
231
  userCredentials,
210
- mcUrl
232
+ mcUrl,
233
+ timeouts: commandOptions.timeouts,
234
+ defaultTimeouts
211
235
  }
212
236
  }, _ref2 => {
213
237
  let userCredentials = _ref2.userCredentials,
214
- mcUrl = _ref2.mcUrl;
238
+ mcUrl = _ref2.mcUrl,
239
+ timeouts = _ref2.timeouts,
240
+ defaultTimeouts = _ref2.defaultTimeouts;
215
241
  cy.url().should('include', `${mcUrl}/login`);
216
242
 
217
243
  // Same as `fillLegacyLoginFormWithRetry`.
218
244
  // eslint-disable-next-line cypress/unsafe-to-chain-command
219
- cy.get('input[name=email]')
245
+ cy.get('input[name=email]', {
246
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
247
+ })
220
248
  // We use `force` as the MC login UI (production) in tests renders the
221
249
  // cookie banner overlapping the input fields.
222
250
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -226,7 +254,9 @@ function loginByForm(commandOptions) {
226
254
  force: true
227
255
  });
228
256
  // eslint-disable-next-line cypress/unsafe-to-chain-command
229
- cy.get('input[name=password]')
257
+ cy.get('input[name=password]', {
258
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
259
+ })
230
260
  // We use `force` as the MC login UI (production) in tests renders the
231
261
  // cookie banner overlapping the input fields.
232
262
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -249,32 +279,56 @@ function loginByForm(commandOptions) {
249
279
  }
250
280
  } else {
251
281
  if (isGlobalIdentityEnabled) {
252
- cy.url().should('include', `${identityUrl}/login`);
282
+ // Wait for redirect to Identity to complete
283
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
284
+ cy.wait(commandOptions.timeouts?.waitForIdentityRedirect ?? defaultTimeouts.waitForIdentityRedirect);
285
+ cy.url({
286
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
287
+ }).should('include', `${identityUrl}/login`);
253
288
  // Fill in the email and click Next
254
- cy.get('input[name="identifier"]').type(userCredentials.email);
289
+ cy.get('input[name="identifier"]', {
290
+ timeout: commandOptions.timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
291
+ }).type(userCredentials.email);
255
292
  cy.get('button').contains('Next').click();
256
293
 
257
294
  // Wait for the password form to appear
258
- cy.get('input[name="password"]').should('be.visible');
295
+ cy.get('input[name="password"]', {
296
+ timeout: commandOptions.timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
297
+ }).should('be.visible');
259
298
  // Fill in the password and submit
260
299
  cy.get('input[name="password"]').type(userCredentials.password, {
261
300
  log: false
262
301
  });
263
- cy.get('button').contains('Submit').click();
302
+ cy.get('button').contains('Submit').click({
303
+ force: true
304
+ });
305
+
306
+ // Wait for redirect to start
307
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
308
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
264
309
 
265
310
  // Wait for the flow to redirect back to the application.
266
311
  cy.origin(Cypress.config('baseUrl'), {
267
312
  args: {
268
- url
313
+ url,
314
+ timeouts: commandOptions.timeouts,
315
+ defaultTimeouts
269
316
  }
270
317
  }, _ref3 => {
271
- let url = _ref3.url;
272
- cy.get('[role="main"]').should('exist');
273
- cy.url().should('include', url);
318
+ let url = _ref3.url,
319
+ timeouts = _ref3.timeouts,
320
+ defaultTimeouts = _ref3.defaultTimeouts;
321
+ // Wait for application to fully load
322
+ cy.get('[role="main"]', {
323
+ timeout: timeouts?.waitForElement ?? defaultTimeouts.waitForElement
324
+ }).should('exist');
325
+ cy.url({
326
+ timeout: timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
327
+ }).should('include', url);
274
328
  });
275
329
  } else {
276
330
  // Legacy login flow.
277
- fillLegacyLoginFormWithRetry(userCredentials);
331
+ fillLegacyLoginFormWithRetry(userCredentials, commandOptions.timeouts);
278
332
 
279
333
  // Wait for the flow to redirect back to the application.
280
334
  cy.get('[role="main"]').should('exist');
@@ -296,7 +350,9 @@ function loginByForm(commandOptions) {
296
350
  }
297
351
  if (commandOptions.initialRoute) {
298
352
  cy.visit(`${Cypress.config('baseUrl')}${commandOptions.initialRoute}`);
299
- cy.url().should('include', commandOptions.initialRoute);
353
+ cy.url({
354
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
355
+ }).should('include', commandOptions.initialRoute);
300
356
  }
301
357
  });
302
358
  }
@@ -304,7 +360,7 @@ function loginByForm(commandOptions) {
304
360
  /* Utilities */
305
361
 
306
362
  const legacyMaxLoginAttempts = Cypress.config('maxLoginAttempts') ?? 3;
307
- function fillLegacyLoginFormWithRetry(userCredentials) {
363
+ function fillLegacyLoginFormWithRetry(userCredentials, timeouts) {
308
364
  // Intercept the login request so we can retry it if we receive a TOO_MANY_REQUESTS status code
309
365
  cy.intercept('POST', '**/tokens').as('loginRequest');
310
366
  function getRandomDelayInSeconds() {
@@ -319,13 +375,17 @@ function fillLegacyLoginFormWithRetry(userCredentials) {
319
375
  cy.log(`Attempts left: ${attemptsLeft}`);
320
376
 
321
377
  // eslint-disable-next-line cypress/unsafe-to-chain-command
322
- cy.get('input[name=email]').clear({
378
+ cy.get('input[name=email]', {
379
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
380
+ }).clear({
323
381
  force: true
324
382
  }).type(userCredentials.email, {
325
383
  force: true
326
384
  });
327
385
  // eslint-disable-next-line cypress/unsafe-to-chain-command
328
- cy.get('input[name=password]').clear({
386
+ cy.get('input[name=password]', {
387
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
388
+ }).clear({
329
389
  force: true
330
390
  }).type(userCredentials.password, {
331
391
  log: false,
@@ -47,6 +47,14 @@ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _
47
47
 
48
48
  // Alias for backwards compatibility
49
49
 
50
+ const defaultTimeouts = {
51
+ waitForEmailInput: 4000,
52
+ waitForPasswordInput: 8000,
53
+ waitForElement: 15000,
54
+ waitForUrl: 15000,
55
+ waitForRedirect: 3000,
56
+ waitForIdentityRedirect: 8000
57
+ };
50
58
  function isFeatureSupported(expectedVersion) {
51
59
  return semver__default["default"].gte(Cypress.version, expectedVersion);
52
60
  }
@@ -177,18 +185,26 @@ function loginByForm(commandOptions) {
177
185
  cy.origin(identityUrl, {
178
186
  args: {
179
187
  userCredentials,
180
- identityUrl
188
+ identityUrl,
189
+ timeouts: commandOptions.timeouts,
190
+ defaultTimeouts
181
191
  }
182
192
  }, _ref => {
183
193
  let userCredentials = _ref.userCredentials,
184
- identityUrl = _ref.identityUrl;
194
+ identityUrl = _ref.identityUrl,
195
+ timeouts = _ref.timeouts,
196
+ defaultTimeouts = _ref.defaultTimeouts;
185
197
  cy.url().should('include', `${identityUrl}/login`);
186
198
  // Fill in the email and click Next
187
- cy.get('input[name="identifier"]').type(userCredentials.email);
199
+ cy.get('input[name="identifier"]', {
200
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
201
+ }).type(userCredentials.email);
188
202
  cy.get('button').contains('Next').click();
189
203
 
190
204
  // Wait for the password form to appear
191
- cy.get('input[name="password"]').should('be.visible');
205
+ cy.get('input[name="password"]', {
206
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
207
+ }).should('be.visible');
192
208
  // Fill in the password and submit
193
209
  cy.get('input[name="password"]').type(userCredentials.password, {
194
210
  log: false
@@ -197,8 +213,14 @@ function loginByForm(commandOptions) {
197
213
  });
198
214
 
199
215
  // Wait for the flow to redirect back to the application.
200
- cy.get('[role="main"]').should('exist');
201
- cy.url().should('include', url);
216
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
217
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
218
+ cy.get('[role="main"]', {
219
+ timeout: commandOptions.timeouts?.waitForElement ?? defaultTimeouts.waitForElement
220
+ }).should('exist');
221
+ cy.url({
222
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
223
+ }).should('include', url);
202
224
  } else {
203
225
  const mcUrl = appConfig.mcApiUrl.replace('mc-api', 'mc');
204
226
  // See similar comment above regarding the usage of `cy.wait`.
@@ -207,16 +229,22 @@ function loginByForm(commandOptions) {
207
229
  cy.origin(mcUrl, {
208
230
  args: {
209
231
  userCredentials,
210
- mcUrl
232
+ mcUrl,
233
+ timeouts: commandOptions.timeouts,
234
+ defaultTimeouts
211
235
  }
212
236
  }, _ref2 => {
213
237
  let userCredentials = _ref2.userCredentials,
214
- mcUrl = _ref2.mcUrl;
238
+ mcUrl = _ref2.mcUrl,
239
+ timeouts = _ref2.timeouts,
240
+ defaultTimeouts = _ref2.defaultTimeouts;
215
241
  cy.url().should('include', `${mcUrl}/login`);
216
242
 
217
243
  // Same as `fillLegacyLoginFormWithRetry`.
218
244
  // eslint-disable-next-line cypress/unsafe-to-chain-command
219
- cy.get('input[name=email]')
245
+ cy.get('input[name=email]', {
246
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
247
+ })
220
248
  // We use `force` as the MC login UI (production) in tests renders the
221
249
  // cookie banner overlapping the input fields.
222
250
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -226,7 +254,9 @@ function loginByForm(commandOptions) {
226
254
  force: true
227
255
  });
228
256
  // eslint-disable-next-line cypress/unsafe-to-chain-command
229
- cy.get('input[name=password]')
257
+ cy.get('input[name=password]', {
258
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
259
+ })
230
260
  // We use `force` as the MC login UI (production) in tests renders the
231
261
  // cookie banner overlapping the input fields.
232
262
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -249,32 +279,56 @@ function loginByForm(commandOptions) {
249
279
  }
250
280
  } else {
251
281
  if (isGlobalIdentityEnabled) {
252
- cy.url().should('include', `${identityUrl}/login`);
282
+ // Wait for redirect to Identity to complete
283
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
284
+ cy.wait(commandOptions.timeouts?.waitForIdentityRedirect ?? defaultTimeouts.waitForIdentityRedirect);
285
+ cy.url({
286
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
287
+ }).should('include', `${identityUrl}/login`);
253
288
  // Fill in the email and click Next
254
- cy.get('input[name="identifier"]').type(userCredentials.email);
289
+ cy.get('input[name="identifier"]', {
290
+ timeout: commandOptions.timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
291
+ }).type(userCredentials.email);
255
292
  cy.get('button').contains('Next').click();
256
293
 
257
294
  // Wait for the password form to appear
258
- cy.get('input[name="password"]').should('be.visible');
295
+ cy.get('input[name="password"]', {
296
+ timeout: commandOptions.timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
297
+ }).should('be.visible');
259
298
  // Fill in the password and submit
260
299
  cy.get('input[name="password"]').type(userCredentials.password, {
261
300
  log: false
262
301
  });
263
- cy.get('button').contains('Submit').click();
302
+ cy.get('button').contains('Submit').click({
303
+ force: true
304
+ });
305
+
306
+ // Wait for redirect to start
307
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
308
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
264
309
 
265
310
  // Wait for the flow to redirect back to the application.
266
311
  cy.origin(Cypress.config('baseUrl'), {
267
312
  args: {
268
- url
313
+ url,
314
+ timeouts: commandOptions.timeouts,
315
+ defaultTimeouts
269
316
  }
270
317
  }, _ref3 => {
271
- let url = _ref3.url;
272
- cy.get('[role="main"]').should('exist');
273
- cy.url().should('include', url);
318
+ let url = _ref3.url,
319
+ timeouts = _ref3.timeouts,
320
+ defaultTimeouts = _ref3.defaultTimeouts;
321
+ // Wait for application to fully load
322
+ cy.get('[role="main"]', {
323
+ timeout: timeouts?.waitForElement ?? defaultTimeouts.waitForElement
324
+ }).should('exist');
325
+ cy.url({
326
+ timeout: timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
327
+ }).should('include', url);
274
328
  });
275
329
  } else {
276
330
  // Legacy login flow.
277
- fillLegacyLoginFormWithRetry(userCredentials);
331
+ fillLegacyLoginFormWithRetry(userCredentials, commandOptions.timeouts);
278
332
 
279
333
  // Wait for the flow to redirect back to the application.
280
334
  cy.get('[role="main"]').should('exist');
@@ -296,7 +350,9 @@ function loginByForm(commandOptions) {
296
350
  }
297
351
  if (commandOptions.initialRoute) {
298
352
  cy.visit(`${Cypress.config('baseUrl')}${commandOptions.initialRoute}`);
299
- cy.url().should('include', commandOptions.initialRoute);
353
+ cy.url({
354
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
355
+ }).should('include', commandOptions.initialRoute);
300
356
  }
301
357
  });
302
358
  }
@@ -304,7 +360,7 @@ function loginByForm(commandOptions) {
304
360
  /* Utilities */
305
361
 
306
362
  const legacyMaxLoginAttempts = Cypress.config('maxLoginAttempts') ?? 3;
307
- function fillLegacyLoginFormWithRetry(userCredentials) {
363
+ function fillLegacyLoginFormWithRetry(userCredentials, timeouts) {
308
364
  // Intercept the login request so we can retry it if we receive a TOO_MANY_REQUESTS status code
309
365
  cy.intercept('POST', '**/tokens').as('loginRequest');
310
366
  function getRandomDelayInSeconds() {
@@ -319,13 +375,17 @@ function fillLegacyLoginFormWithRetry(userCredentials) {
319
375
  cy.log(`Attempts left: ${attemptsLeft}`);
320
376
 
321
377
  // eslint-disable-next-line cypress/unsafe-to-chain-command
322
- cy.get('input[name=email]').clear({
378
+ cy.get('input[name=email]', {
379
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
380
+ }).clear({
323
381
  force: true
324
382
  }).type(userCredentials.email, {
325
383
  force: true
326
384
  });
327
385
  // eslint-disable-next-line cypress/unsafe-to-chain-command
328
- cy.get('input[name=password]').clear({
386
+ cy.get('input[name=password]', {
387
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
388
+ }).clear({
329
389
  force: true
330
390
  }).type(userCredentials.password, {
331
391
  log: false,
@@ -27,6 +27,14 @@ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _
27
27
 
28
28
  // Alias for backwards compatibility
29
29
 
30
+ const defaultTimeouts = {
31
+ waitForEmailInput: 4000,
32
+ waitForPasswordInput: 8000,
33
+ waitForElement: 15000,
34
+ waitForUrl: 15000,
35
+ waitForRedirect: 3000,
36
+ waitForIdentityRedirect: 8000
37
+ };
30
38
  function isFeatureSupported(expectedVersion) {
31
39
  return semver.gte(Cypress.version, expectedVersion);
32
40
  }
@@ -157,18 +165,26 @@ function loginByForm(commandOptions) {
157
165
  cy.origin(identityUrl, {
158
166
  args: {
159
167
  userCredentials,
160
- identityUrl
168
+ identityUrl,
169
+ timeouts: commandOptions.timeouts,
170
+ defaultTimeouts
161
171
  }
162
172
  }, _ref => {
163
173
  let userCredentials = _ref.userCredentials,
164
- identityUrl = _ref.identityUrl;
174
+ identityUrl = _ref.identityUrl,
175
+ timeouts = _ref.timeouts,
176
+ defaultTimeouts = _ref.defaultTimeouts;
165
177
  cy.url().should('include', `${identityUrl}/login`);
166
178
  // Fill in the email and click Next
167
- cy.get('input[name="identifier"]').type(userCredentials.email);
179
+ cy.get('input[name="identifier"]', {
180
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
181
+ }).type(userCredentials.email);
168
182
  cy.get('button').contains('Next').click();
169
183
 
170
184
  // Wait for the password form to appear
171
- cy.get('input[name="password"]').should('be.visible');
185
+ cy.get('input[name="password"]', {
186
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
187
+ }).should('be.visible');
172
188
  // Fill in the password and submit
173
189
  cy.get('input[name="password"]').type(userCredentials.password, {
174
190
  log: false
@@ -177,8 +193,14 @@ function loginByForm(commandOptions) {
177
193
  });
178
194
 
179
195
  // Wait for the flow to redirect back to the application.
180
- cy.get('[role="main"]').should('exist');
181
- cy.url().should('include', url);
196
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
197
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
198
+ cy.get('[role="main"]', {
199
+ timeout: commandOptions.timeouts?.waitForElement ?? defaultTimeouts.waitForElement
200
+ }).should('exist');
201
+ cy.url({
202
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
203
+ }).should('include', url);
182
204
  } else {
183
205
  const mcUrl = appConfig.mcApiUrl.replace('mc-api', 'mc');
184
206
  // See similar comment above regarding the usage of `cy.wait`.
@@ -187,16 +209,22 @@ function loginByForm(commandOptions) {
187
209
  cy.origin(mcUrl, {
188
210
  args: {
189
211
  userCredentials,
190
- mcUrl
212
+ mcUrl,
213
+ timeouts: commandOptions.timeouts,
214
+ defaultTimeouts
191
215
  }
192
216
  }, _ref2 => {
193
217
  let userCredentials = _ref2.userCredentials,
194
- mcUrl = _ref2.mcUrl;
218
+ mcUrl = _ref2.mcUrl,
219
+ timeouts = _ref2.timeouts,
220
+ defaultTimeouts = _ref2.defaultTimeouts;
195
221
  cy.url().should('include', `${mcUrl}/login`);
196
222
 
197
223
  // Same as `fillLegacyLoginFormWithRetry`.
198
224
  // eslint-disable-next-line cypress/unsafe-to-chain-command
199
- cy.get('input[name=email]')
225
+ cy.get('input[name=email]', {
226
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
227
+ })
200
228
  // We use `force` as the MC login UI (production) in tests renders the
201
229
  // cookie banner overlapping the input fields.
202
230
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -206,7 +234,9 @@ function loginByForm(commandOptions) {
206
234
  force: true
207
235
  });
208
236
  // eslint-disable-next-line cypress/unsafe-to-chain-command
209
- cy.get('input[name=password]')
237
+ cy.get('input[name=password]', {
238
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
239
+ })
210
240
  // We use `force` as the MC login UI (production) in tests renders the
211
241
  // cookie banner overlapping the input fields.
212
242
  // To allow Cypress to interact with the input fields, we use `force`.
@@ -229,32 +259,56 @@ function loginByForm(commandOptions) {
229
259
  }
230
260
  } else {
231
261
  if (isGlobalIdentityEnabled) {
232
- cy.url().should('include', `${identityUrl}/login`);
262
+ // Wait for redirect to Identity to complete
263
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
264
+ cy.wait(commandOptions.timeouts?.waitForIdentityRedirect ?? defaultTimeouts.waitForIdentityRedirect);
265
+ cy.url({
266
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
267
+ }).should('include', `${identityUrl}/login`);
233
268
  // Fill in the email and click Next
234
- cy.get('input[name="identifier"]').type(userCredentials.email);
269
+ cy.get('input[name="identifier"]', {
270
+ timeout: commandOptions.timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
271
+ }).type(userCredentials.email);
235
272
  cy.get('button').contains('Next').click();
236
273
 
237
274
  // Wait for the password form to appear
238
- cy.get('input[name="password"]').should('be.visible');
275
+ cy.get('input[name="password"]', {
276
+ timeout: commandOptions.timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
277
+ }).should('be.visible');
239
278
  // Fill in the password and submit
240
279
  cy.get('input[name="password"]').type(userCredentials.password, {
241
280
  log: false
242
281
  });
243
- cy.get('button').contains('Submit').click();
282
+ cy.get('button').contains('Submit').click({
283
+ force: true
284
+ });
285
+
286
+ // Wait for redirect to start
287
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
288
+ cy.wait(commandOptions.timeouts?.waitForRedirect ?? defaultTimeouts.waitForRedirect);
244
289
 
245
290
  // Wait for the flow to redirect back to the application.
246
291
  cy.origin(Cypress.config('baseUrl'), {
247
292
  args: {
248
- url
293
+ url,
294
+ timeouts: commandOptions.timeouts,
295
+ defaultTimeouts
249
296
  }
250
297
  }, _ref3 => {
251
- let url = _ref3.url;
252
- cy.get('[role="main"]').should('exist');
253
- cy.url().should('include', url);
298
+ let url = _ref3.url,
299
+ timeouts = _ref3.timeouts,
300
+ defaultTimeouts = _ref3.defaultTimeouts;
301
+ // Wait for application to fully load
302
+ cy.get('[role="main"]', {
303
+ timeout: timeouts?.waitForElement ?? defaultTimeouts.waitForElement
304
+ }).should('exist');
305
+ cy.url({
306
+ timeout: timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
307
+ }).should('include', url);
254
308
  });
255
309
  } else {
256
310
  // Legacy login flow.
257
- fillLegacyLoginFormWithRetry(userCredentials);
311
+ fillLegacyLoginFormWithRetry(userCredentials, commandOptions.timeouts);
258
312
 
259
313
  // Wait for the flow to redirect back to the application.
260
314
  cy.get('[role="main"]').should('exist');
@@ -276,7 +330,9 @@ function loginByForm(commandOptions) {
276
330
  }
277
331
  if (commandOptions.initialRoute) {
278
332
  cy.visit(`${Cypress.config('baseUrl')}${commandOptions.initialRoute}`);
279
- cy.url().should('include', commandOptions.initialRoute);
333
+ cy.url({
334
+ timeout: commandOptions.timeouts?.waitForUrl ?? defaultTimeouts.waitForUrl
335
+ }).should('include', commandOptions.initialRoute);
280
336
  }
281
337
  });
282
338
  }
@@ -284,7 +340,7 @@ function loginByForm(commandOptions) {
284
340
  /* Utilities */
285
341
 
286
342
  const legacyMaxLoginAttempts = Cypress.config('maxLoginAttempts') ?? 3;
287
- function fillLegacyLoginFormWithRetry(userCredentials) {
343
+ function fillLegacyLoginFormWithRetry(userCredentials, timeouts) {
288
344
  // Intercept the login request so we can retry it if we receive a TOO_MANY_REQUESTS status code
289
345
  cy.intercept('POST', '**/tokens').as('loginRequest');
290
346
  function getRandomDelayInSeconds() {
@@ -299,13 +355,17 @@ function fillLegacyLoginFormWithRetry(userCredentials) {
299
355
  cy.log(`Attempts left: ${attemptsLeft}`);
300
356
 
301
357
  // eslint-disable-next-line cypress/unsafe-to-chain-command
302
- cy.get('input[name=email]').clear({
358
+ cy.get('input[name=email]', {
359
+ timeout: timeouts?.waitForEmailInput ?? defaultTimeouts.waitForEmailInput
360
+ }).clear({
303
361
  force: true
304
362
  }).type(userCredentials.email, {
305
363
  force: true
306
364
  });
307
365
  // eslint-disable-next-line cypress/unsafe-to-chain-command
308
- cy.get('input[name=password]').clear({
366
+ cy.get('input[name=password]', {
367
+ timeout: timeouts?.waitForPasswordInput ?? defaultTimeouts.waitForPasswordInput
368
+ }).clear({
309
369
  force: true
310
370
  }).type(userCredentials.password, {
311
371
  log: false,
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var constants = require('./constants-009cb682.cjs.dev.js');
6
6
 
7
7
  // NOTE: This string will be replaced on build time with the package version.
8
- var version = "24.4.0";
8
+ var version = "24.6.0";
9
9
 
10
10
  exports.HTTP_STATUS_CODES = constants.HTTP_STATUS_CODES;
11
11
  exports.OIDC_RESPONSE_TYPES = constants.OIDC_RESPONSE_TYPES;
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var constants = require('./constants-2f1475a6.cjs.prod.js');
6
6
 
7
7
  // NOTE: This string will be replaced on build time with the package version.
8
- var version = "24.4.0";
8
+ var version = "24.6.0";
9
9
 
10
10
  exports.HTTP_STATUS_CODES = constants.HTTP_STATUS_CODES;
11
11
  exports.OIDC_RESPONSE_TYPES = constants.OIDC_RESPONSE_TYPES;
@@ -1,6 +1,6 @@
1
1
  export { H as HTTP_STATUS_CODES, O as OIDC_RESPONSE_TYPES, S as STORAGE_KEYS } from './constants-13c76918.esm.js';
2
2
 
3
3
  // NOTE: This string will be replaced on build time with the package version.
4
- var version = "24.4.0";
4
+ var version = "24.6.0";
5
5
 
6
6
  export { version };
@@ -10,6 +10,38 @@ export type LoginCredentials = {
10
10
  */
11
11
  password: string;
12
12
  };
13
+ export type LoginCommandTimeouts = {
14
+ /**
15
+ * The number of milliseconds to wait for the email input to appear.
16
+ * Defaults to `4000` (4 seconds).
17
+ */
18
+ waitForEmailInput?: number;
19
+ /**
20
+ * The number of milliseconds to wait for the password input to appear.
21
+ * Defaults to `8000` (8 seconds).
22
+ */
23
+ waitForPasswordInput?: number;
24
+ /**
25
+ * The timeout in milliseconds for cy.get() operations on elements.
26
+ * Defaults to `15000` (15 seconds).
27
+ */
28
+ waitForElement?: number;
29
+ /**
30
+ * The timeout in milliseconds for cy.url() operations.
31
+ * Defaults to `15000` (15 seconds).
32
+ */
33
+ waitForUrl?: number;
34
+ /**
35
+ * The number of milliseconds to wait for redirects to complete.
36
+ * Defaults to `3000` (3 seconds).
37
+ */
38
+ waitForRedirect?: number;
39
+ /**
40
+ * The number of milliseconds to wait for Identity redirect to complete.
41
+ * Defaults to `8000` (8 seconds).
42
+ */
43
+ waitForIdentityRedirect?: number;
44
+ };
13
45
  export type CommandLoginOptions = {
14
46
  /**
15
47
  * The application entry point URI path. This value is used to identify
@@ -46,6 +78,10 @@ export type CommandLoginOptions = {
46
78
  * This is only relevant for Cypress version >= `10.9.0`.
47
79
  */
48
80
  disableCacheAcrossSpecs?: boolean;
81
+ /**
82
+ * Configure timeouts for some of the command interactions.
83
+ */
84
+ timeouts?: LoginCommandTimeouts;
49
85
  };
50
86
  export type LoginToMerchantCenterForCustomViewCommandLoginOptions = Omit<CommandLoginOptions, 'entryPointUriPath' | 'initialRoute'> & {
51
87
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend/cypress",
3
- "version": "24.4.0",
3
+ "version": "24.6.0",
4
4
  "description": "Cypress commands and utilities for Custom Applications",
5
5
  "bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
6
6
  "repository": {
@@ -41,9 +41,9 @@
41
41
  "dependencies": {
42
42
  "@babel/runtime": "^7.22.15",
43
43
  "@babel/runtime-corejs3": "^7.22.15",
44
- "@commercetools-frontend/application-config": "24.4.0",
45
- "@commercetools-frontend/application-shell": "24.4.0",
46
- "@commercetools-frontend/constants": "24.4.0",
44
+ "@commercetools-frontend/application-config": "24.6.0",
45
+ "@commercetools-frontend/application-shell": "24.6.0",
46
+ "@commercetools-frontend/constants": "24.6.0",
47
47
  "@manypkg/get-packages": "1.1.3",
48
48
  "@types/semver": "^7.5.1",
49
49
  "semver": "7.6.2",