Skip to content

Commit e3f84c2

Browse files
areinclaude
andauthored
chore(canary): increase OTP entry timeout to 20 seconds & add comprehensive logging (#5243)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent fbaaa96 commit e3f84c2

2 files changed

Lines changed: 113 additions & 12 deletions

File tree

apps/laboratory/tests/shared/pages/ModalPage.ts

Lines changed: 93 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,47 +263,78 @@ export class ModalPage {
263263
clickConnectButton?: boolean
264264
timingRecords?: TimingRecords
265265
}): Promise<void> {
266+
const flowStart = Date.now()
267+
// eslint-disable-next-line no-console
268+
console.log(`[emailFlow] ========== Starting email flow for ${emailAddress} ==========`)
269+
266270
this.emailAddress = emailAddress
267271

268272
const email = new Email(mailsacApiKey)
269273

274+
// eslint-disable-next-line no-console
275+
console.log(`[emailFlow] Deleting all existing messages`)
270276
await email.deleteAllMessages(emailAddress)
271277

272278
const loginWithEmail = new Date()
279+
// eslint-disable-next-line no-console
280+
console.log(`[emailFlow] Calling loginWithEmail at ${Date.now() - flowStart}ms`)
273281
await this.loginWithEmail(emailAddress, undefined, clickConnectButton)
282+
const loginTime = new Date().getTime() - loginWithEmail.getTime()
283+
// eslint-disable-next-line no-console
284+
console.log(`[emailFlow] loginWithEmail completed in ${loginTime}ms`)
274285
if (timingRecords) {
275286
timingRecords.push({
276287
item: 'loginWithEmail',
277-
timeMs: new Date().getTime() - loginWithEmail.getTime()
288+
timeMs: loginTime
278289
})
279290
}
280291

281292
const getLatestMessageId1 = new Date()
293+
// eslint-disable-next-line no-console
294+
console.log(`[emailFlow] Waiting for first email at ${Date.now() - flowStart}ms`)
282295
const firstMessageId = await email.getLatestMessageId(emailAddress)
296+
const getMessageId1Time = new Date().getTime() - getLatestMessageId1.getTime()
297+
// eslint-disable-next-line no-console
298+
console.log(`[emailFlow] Got first messageId in ${getMessageId1Time}ms`)
283299
if (timingRecords) {
284300
timingRecords.push({
285301
item: 'getLatestMessageId1',
286-
timeMs: new Date().getTime() - getLatestMessageId1.getTime()
302+
timeMs: getMessageId1Time
287303
})
288304
}
289305
if (!firstMessageId) {
290306
throw new Error('No messageId found')
291307
}
292308

293309
const getEmailBody1 = new Date()
310+
// eslint-disable-next-line no-console
311+
console.log(`[emailFlow] Fetching first email body at ${Date.now() - flowStart}ms`)
294312
const firstEmailBody = await email.getEmailBody(emailAddress, firstMessageId)
313+
const getEmailBody1Time = new Date().getTime() - getEmailBody1.getTime()
314+
// eslint-disable-next-line no-console
315+
console.log(`[emailFlow] Got first email body in ${getEmailBody1Time}ms`)
295316
if (timingRecords) {
296317
timingRecords.push({
297318
item: 'getEmailBody1',
298-
timeMs: new Date().getTime() - getEmailBody1.getTime()
319+
timeMs: getEmailBody1Time
299320
})
300321
}
301322

302323
let otp = ''
303-
if (email.isApproveEmail(firstEmailBody)) {
324+
const isApprove = email.isApproveEmail(firstEmailBody)
325+
// eslint-disable-next-line no-console
326+
console.log(`[emailFlow] First email is ${isApprove ? 'APPROVAL' : 'OTP'} email`)
327+
328+
if (isApprove) {
304329
const url = email.getApproveUrlFromBody(firstEmailBody)
330+
// eslint-disable-next-line no-console
331+
console.log(`[emailFlow] Processing device approval flow at ${Date.now() - flowStart}ms`)
305332

306333
const deleteAllMessages = new Date()
334+
// eslint-disable-next-line no-console
335+
console.log(
336+
`[emailFlow] Deleting messages before device approval at ${Date.now() - flowStart}ms`
337+
)
307338
await email.deleteAllMessages(emailAddress)
308339
if (timingRecords) {
309340
timingRecords.push({
@@ -313,74 +344,126 @@ export class ModalPage {
313344
}
314345

315346
const loadDeviceRegistrationPage = new Date()
347+
// eslint-disable-next-line no-console
348+
console.log(`[emailFlow] Loading device registration page with URL: ${url}`)
316349
const drp = new DeviceRegistrationPage(await context.newPage(), url)
317350
drp.load()
351+
// eslint-disable-next-line no-console
352+
console.log(`[emailFlow] Approving device at ${Date.now() - flowStart}ms`)
318353
await drp.approveDevice()
319354
await drp.close()
355+
const approvalTime = new Date().getTime() - loadDeviceRegistrationPage.getTime()
356+
// eslint-disable-next-line no-console
357+
console.log(`[emailFlow] Device approval completed in ${approvalTime}ms`)
320358
if (timingRecords) {
321359
timingRecords.push({
322360
item: 'loadDeviceRegistrationPage',
323-
timeMs: new Date().getTime() - loadDeviceRegistrationPage.getTime()
361+
timeMs: approvalTime
324362
})
325363
}
326364

327365
const getLatestMessageId2 = new Date()
366+
// eslint-disable-next-line no-console
367+
console.log(`[emailFlow] Waiting for second email (OTP) at ${Date.now() - flowStart}ms`)
328368
const secondMessageId = await email.getLatestMessageId(emailAddress)
329369
if (!secondMessageId) {
330370
throw new Error('No messageId found')
331371
}
372+
const getMessageId2Time = new Date().getTime() - getLatestMessageId2.getTime()
373+
// eslint-disable-next-line no-console
374+
console.log(`[emailFlow] Got second messageId in ${getMessageId2Time}ms`)
332375
if (timingRecords) {
333376
timingRecords.push({
334377
item: 'getLatestMessageId2',
335-
timeMs: new Date().getTime() - getLatestMessageId2.getTime()
378+
timeMs: getMessageId2Time
336379
})
337380
}
338381

339382
const getEmailBody2 = new Date()
383+
// eslint-disable-next-line no-console
384+
console.log(`[emailFlow] Fetching second email body at ${Date.now() - flowStart}ms`)
340385
const secondEmailBody = await email.getEmailBody(emailAddress, secondMessageId)
386+
const getEmailBody2Time = new Date().getTime() - getEmailBody2.getTime()
387+
// eslint-disable-next-line no-console
388+
console.log(`[emailFlow] Got second email body in ${getEmailBody2Time}ms`)
341389
if (timingRecords) {
342390
timingRecords.push({
343391
item: 'getEmailBody2',
344-
timeMs: new Date().getTime() - getEmailBody2.getTime()
392+
timeMs: getEmailBody2Time
345393
})
346394
}
347395
if (email.isApproveEmail(secondEmailBody)) {
348396
throw new Error('Unexpected approve email after already approved')
349397
}
350398
otp = email.getOtpCodeFromBody(secondEmailBody)
399+
// eslint-disable-next-line no-console
400+
console.log(`[emailFlow] Extracted OTP from second email`)
351401
} else {
352402
otp = email.getOtpCodeFromBody(firstEmailBody)
403+
// eslint-disable-next-line no-console
404+
console.log(`[emailFlow] Extracted OTP from first email (no approval needed)`)
353405
}
354406

355407
const enterOTP = new Date()
408+
// eslint-disable-next-line no-console
409+
console.log(`[emailFlow] Entering OTP at ${Date.now() - flowStart}ms`)
356410
await this.enterOTP(otp)
411+
const enterOTPTime = new Date().getTime() - enterOTP.getTime()
412+
// eslint-disable-next-line no-console
413+
console.log(`[emailFlow] enterOTP completed in ${enterOTPTime}ms`)
357414
if (timingRecords) {
358415
timingRecords.push({
359416
item: 'enterOTP',
360-
timeMs: new Date().getTime() - enterOTP.getTime()
417+
timeMs: enterOTPTime
361418
})
362419
}
420+
421+
const totalFlowTime = Date.now() - flowStart
422+
// eslint-disable-next-line no-console
423+
console.log(`[emailFlow] ========== Email flow completed in ${totalFlowTime}ms ==========`)
363424
}
364425

365426
async loginWithEmail(email: string, validate = true, clickConnectButton = true) {
427+
// eslint-disable-next-line no-console
428+
console.log(`[loginWithEmail] Starting login with email: ${email}`)
429+
366430
if (clickConnectButton) {
431+
// eslint-disable-next-line no-console
432+
console.log(`[loginWithEmail] Clicking connect button`)
367433
// Connect Button doesn't have a proper `disabled` attribute so we need to wait for the button to change the text
368434
await this.page
369435
.getByTestId('connect-button')
370436
.getByRole('button', { name: 'Connect Wallet' })
371437
.click()
372438
}
439+
440+
// eslint-disable-next-line no-console
441+
console.log(`[loginWithEmail] Filling email input`)
373442
await this.page.getByTestId('wui-email-input').locator('input').focus()
374443
await this.page.getByTestId('wui-email-input').locator('input').fill(email)
375444
await this.page.getByTestId('wui-email-input').locator('input').press('Enter')
445+
376446
if (validate) {
447+
// eslint-disable-next-line no-console
448+
console.log(
449+
`[loginWithEmail] Waiting for email to be visible on notification screen (20s timeout)`
450+
)
451+
const validationStart = Date.now()
452+
377453
await expect(
378454
this.page.getByText(email),
379455
`Expected current email: ${email} to be visible on the notification screen`
380456
).toBeVisible({
381457
timeout: 20_000
382458
})
459+
460+
const validationTime = Date.now() - validationStart
461+
// eslint-disable-next-line no-console
462+
console.log(`[loginWithEmail] Email visible on screen after ${validationTime}ms`)
383463
}
464+
465+
// eslint-disable-next-line no-console
466+
console.log(`[loginWithEmail] Completed successfully`)
384467
}
385468

386469
async loginWithSocial(socialOption: 'github', socialMail: string, socialPass: string) {
@@ -419,10 +502,10 @@ export class ModalPage {
419502

420503
async enterOTP(otp: string, headerTitle = 'Confirm Email') {
421504
await expect(this.page.getByText(headerTitle)).toBeVisible({
422-
timeout: 10_000
505+
timeout: 20_000
423506
})
424507
await expect(this.page.getByText('Enter the code we sent')).toBeVisible({
425-
timeout: 10_000
508+
timeout: 20_000
426509
})
427510

428511
const splitted = otp.split('')

apps/laboratory/tests/shared/utils/email.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export class Email {
2929
}
3030

3131
async getLatestMessageId(email: string): Promise<string> {
32+
const startTime = Date.now()
33+
// eslint-disable-next-line no-console
34+
console.log(`[getLatestMessageId] Starting to poll for email at ${email}`)
35+
3236
let checks = 0
3337
/* eslint-disable no-await-in-loop */
3438
while (checks < MAX_EMAIL_CHECK) {
@@ -43,12 +47,26 @@ export class Email {
4347
throw new Error(`Message id not present for address ${email}`)
4448
}
4549

50+
const elapsedTime = Date.now() - startTime
51+
// eslint-disable-next-line no-console
52+
console.log(
53+
`[getLatestMessageId] Found message after ${checks + 1} attempt(s) in ${elapsedTime}ms for ${email}`
54+
)
55+
4656
return id
4757
}
48-
await this.timeout(EMAIL_CHECK_INTERVAL)
4958
checks += 1
59+
// eslint-disable-next-line no-console
60+
console.log(
61+
`[getLatestMessageId] Attempt ${checks}/${MAX_EMAIL_CHECK}: No messages yet, waiting ${EMAIL_CHECK_INTERVAL}ms...`
62+
)
63+
await this.timeout(EMAIL_CHECK_INTERVAL)
5064
}
51-
throw new Error(`No email found for address ${email}`)
65+
66+
const elapsedTime = Date.now() - startTime
67+
throw new Error(
68+
`No email found for address ${email} after ${MAX_EMAIL_CHECK} attempts (${elapsedTime}ms)`
69+
)
5270
}
5371

5472
async getEmailBody(email: string, messageId: string): Promise<string> {

0 commit comments

Comments
 (0)