-
Notifications
You must be signed in to change notification settings - Fork 440
test(e2e): confirm Next.js 16.2.0 breaks cache-components tests #8122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a3499a0
6b7cf6a
c2f2542
e9dfc01
879aaad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,12 +42,150 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes], withPattern: | |
| test('auth() in server component works when signed in', async ({ page, context }) => { | ||
| const u = createTestUtils({ app, page, context }); | ||
|
|
||
| // Collect console errors and network failures | ||
| const consoleErrors: string[] = []; | ||
| const networkErrors: string[] = []; | ||
| page.on('console', msg => { | ||
| if (msg.type() === 'error') consoleErrors.push(msg.text()); | ||
| }); | ||
| page.on('requestfailed', req => { | ||
| networkErrors.push(`${req.method()} ${req.url()} - ${req.failure()?.errorText}`); | ||
| }); | ||
|
|
||
| // Sign in first | ||
| await u.po.signIn.goTo(); | ||
| await u.po.signIn.signInWithEmailAndInstantPassword({ | ||
| email: fakeUser.email, | ||
| password: fakeUser.password, | ||
| console.log(`[DIAG] URL after goTo sign-in: ${page.url()}`); | ||
|
|
||
| // Check form state before interaction | ||
| const identifierInput = page.locator('input[name=identifier]'); | ||
| const isIdentifierVisible = await identifierInput.isVisible(); | ||
| const isIdentifierEnabled = await identifierInput.isEnabled(); | ||
| console.log(`[DIAG] identifier visible: ${isIdentifierVisible}, enabled: ${isIdentifierEnabled}`); | ||
|
|
||
| // Fill identifier and check if password field appears | ||
| await identifierInput.fill(fakeUser.email); | ||
| const passwordInput = page.locator('input[name=password]'); | ||
| try { | ||
| await passwordInput.waitFor({ state: 'visible', timeout: 5000 }); | ||
| console.log('[DIAG] password field appeared after filling identifier'); | ||
| } catch { | ||
| console.log('[DIAG] password field did NOT appear after 5s'); | ||
| const formHTML = await page.locator('.cl-signIn-root').innerHTML(); | ||
| console.log('[DIAG] sign-in form HTML:', formHTML.substring(0, 3000)); | ||
|
Comment on lines
+73
to
+74
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redact auth diagnostics before writing them to CI logs.
Suggested fix- const formHTML = await page.locator('.cl-signIn-root').innerHTML();
- console.log('[DIAG] sign-in form HTML:', formHTML.substring(0, 3000));
+ const formShape = await page.locator('.cl-signIn-root').evaluate(root => ({
+ inputNames: Array.from(root.querySelectorAll('input')).map(input => input.getAttribute('name')),
+ buttonLabels: Array.from(root.querySelectorAll('button')).map(
+ button => button.textContent?.trim() ?? '',
+ ),
+ }));
+ console.log('[DIAG] sign-in form shape:', JSON.stringify(formShape));
const diagAfterWait = await page.evaluate(() => {
return {
url: window.location.href,
clerkLoaded: !!(window as any).Clerk?.loaded,
hasSession: !!(window as any).Clerk?.session,
hasUser: !!(window as any).Clerk?.user,
- cookies: document.cookie,
+ cookieNames: document.cookie
+ .split(';')
+ .map(cookie => cookie.trim().split('=')[0])
+ .filter(Boolean),
signInCardClass: document.querySelector('.cl-cardBox')?.className ?? 'NOT_FOUND',
};
});
@@
const finalState = await page.evaluate(() => ({
url: window.location.href,
hasSession: !!(window as any).Clerk?.session,
- cookies: document.cookie,
+ cookieNames: document.cookie
+ .split(';')
+ .map(cookie => cookie.trim().split('=')[0])
+ .filter(Boolean),
}));Also applies to: 104-117, 123-128 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| // Install event listeners on password input BEFORE filling | ||
| await page.evaluate(() => { | ||
| const pwInput = document.querySelector('input[name=password]') as HTMLInputElement; | ||
| if (pwInput) { | ||
| (window as any).__pwEvents = []; | ||
| ['input', 'change', 'focus', 'blur', 'keydown', 'keyup'].forEach(evt => { | ||
| pwInput.addEventListener(evt, (e: Event) => { | ||
| (window as any).__pwEvents.push({ | ||
| type: e.type, | ||
| value: (e.target as HTMLInputElement).value.length, | ||
| isTrusted: e.isTrusted, | ||
| }); | ||
| }); | ||
| }); | ||
| // Also track React's synthetic event by monkey-patching the value setter | ||
| const origDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); | ||
| (window as any).__valueSetCount = 0; | ||
| if (origDescriptor?.set) { | ||
| Object.defineProperty(pwInput, 'value', { | ||
| set(val: string) { | ||
| (window as any).__valueSetCount++; | ||
| origDescriptor.set!.call(this, val); | ||
| }, | ||
| get() { | ||
| return origDescriptor.get!.call(this); | ||
| }, | ||
| }); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| // Fill password | ||
| const isPasswordVisible = await passwordInput.isVisible(); | ||
| console.log(`[DIAG] password visible: ${isPasswordVisible}`); | ||
| if (isPasswordVisible) { | ||
| await passwordInput.fill(fakeUser.password, { force: true }); | ||
| } | ||
|
|
||
| // Check what events fired and the password field state | ||
| const pwDiag = await page.evaluate(() => { | ||
| const pwInput = document.querySelector('input[name=password]') as HTMLInputElement; | ||
| return { | ||
| domValue: pwInput?.value ?? 'NOT_FOUND', | ||
| domValueLength: pwInput?.value?.length ?? 0, | ||
| events: (window as any).__pwEvents ?? [], | ||
| valueSetCount: (window as any).__valueSetCount ?? 0, | ||
| // Check password field's computed styles (Activity hiding?) | ||
| computedDisplay: pwInput ? getComputedStyle(pwInput).display : 'N/A', | ||
| computedOpacity: pwInput ? getComputedStyle(pwInput).opacity : 'N/A', | ||
| computedPointerEvents: pwInput ? getComputedStyle(pwInput).pointerEvents : 'N/A', | ||
| // Check parent container styles | ||
| parentOpacity: pwInput?.closest('[class*="instant"]') | ||
| ? getComputedStyle(pwInput.closest('[class*="instant"]')!).opacity | ||
| : pwInput?.parentElement | ||
| ? getComputedStyle(pwInput.parentElement).opacity | ||
| : 'N/A', | ||
| }; | ||
| }); | ||
| console.log('[DIAG] Password field after fill:', JSON.stringify(pwDiag, null, 2)); | ||
|
|
||
| const continueBtn = page.getByRole('button', { name: 'Continue', exact: true }); | ||
| const isContinueVisible = await continueBtn.isVisible(); | ||
| const isContinueEnabled = await continueBtn.isEnabled(); | ||
| console.log(`[DIAG] continue button visible: ${isContinueVisible}, enabled: ${isContinueEnabled}`); | ||
|
|
||
| // Track API calls with response bodies for sign-in calls | ||
| const apiCalls: string[] = []; | ||
| page.on('response', async res => { | ||
| const url = res.url(); | ||
| if (url.includes('sign_in')) { | ||
| try { | ||
| const body = await res.json(); | ||
| const status = body?.response?.status || body?.status || 'unknown'; | ||
| apiCalls.push(`${res.status()} ${url.split('?')[0].split('/').slice(-2).join('/')} signInStatus=${status}`); | ||
| } catch { | ||
| apiCalls.push(`${res.status()} ${url.split('?')[0].split('/').slice(-2).join('/')}`); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| // Click continue | ||
| await continueBtn.click(); | ||
|
|
||
| // Wait for the sign-in to process | ||
| await page.waitForTimeout(5000); | ||
|
|
||
| const diagAfterWait = await page.evaluate(() => { | ||
| return { | ||
| url: window.location.href, | ||
| hasSession: !!(window as any).Clerk?.session, | ||
| signInCardClass: document.querySelector('.cl-cardBox')?.className ?? 'NOT_FOUND', | ||
| signInStatus: (window as any).Clerk?.client?.signIn?.status ?? 'N/A', | ||
| }; | ||
| }); | ||
| console.log('[DIAG] State 5s after click:', JSON.stringify(diagAfterWait, null, 2)); | ||
| console.log('[DIAG] API calls:', JSON.stringify(apiCalls)); | ||
| console.log('[DIAG] Console errors:', JSON.stringify(consoleErrors)); | ||
| console.log('[DIAG] Network errors:', JSON.stringify(networkErrors)); | ||
|
|
||
| // Now wait for session | ||
| try { | ||
| await page.waitForFunction(() => !!window.Clerk?.session, { timeout: 10_000 }); | ||
| } catch { | ||
| const finalState = await page.evaluate(() => ({ | ||
| url: window.location.href, | ||
| hasSession: !!(window as any).Clerk?.session, | ||
| cookies: document.cookie, | ||
| })); | ||
| console.log('[DIAG] FINAL state at timeout:', JSON.stringify(finalState)); | ||
| throw new Error('waitForSession timed out'); | ||
| } | ||
|
|
||
| await u.po.expect.toBeSignedIn(); | ||
|
|
||
| // Navigate to server component page | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t let a pre-sign-in failure masquerade as the target regression.
If the password step never renders, this test still clicks Continue and can later throw
waitForSession timed out. That makes an upstream form/rendering failure indistinguishable from the specific post-sign-inwindow.Clerk?.sessionregression this PR is supposed to isolate.Suggested fix
try { await passwordInput.waitFor({ state: 'visible', timeout: 5000 }); console.log('[DIAG] password field appeared after filling identifier'); } catch { console.log('[DIAG] password field did NOT appear after 5s'); // Capture what the form looks like const formHTML = await page.locator('.cl-signIn-root').innerHTML(); console.log('[DIAG] sign-in form HTML:', formHTML.substring(0, 3000)); + throw new Error('Password step never rendered; aborting before session diagnostics'); } - const isPasswordVisible = await passwordInput.isVisible(); - console.log(`[DIAG] password visible: ${isPasswordVisible}`); - if (isPasswordVisible) { - await passwordInput.fill(fakeUser.password, { force: true }); - } + await passwordInput.fill(fakeUser.password, { force: true });Also applies to: 79-99, 119-129
🤖 Prompt for AI Agents