Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/sim/app/extension/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function PanelSignIn({ expectedUserId }: ExtensionSignInProps) {
>
Sign in
</ChipLink>
{failed && <Chip onClick={() => window.location.reload()}>Try again</Chip>}
<Chip onClick={() => window.location.reload()}>{failed ? 'Try again' : 'Refresh'}</Chip>
</main>
)
}
Expand Down
87 changes: 84 additions & 3 deletions apps/sim/scripts/test-browser-extension-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const checks: {
const screenshots: string[] = []
const browserErrors: string[] = []
const voiceDiagnostics: Record<string, unknown>[] = []
const signInRecoveryReceipts: Record<string, unknown>[] = []
const httpErrors: { path: string; status: number; injected: boolean }[] = []
const injectedRequests = new WeakSet<Request>()
const pendingRequests = new Set<Request>()
Expand Down Expand Up @@ -534,10 +535,89 @@ try {
userId = String(id)
await seed()
}
let login: Page | null = null
await checkNavigation(
'Manual refresh recovers sign-in without focus or visibility changes',
async () => {
login = await openPage()
await login.goto(`${base.origin}/login`)
const recovery = await openPanel()
try {
const signedOutSession = recovery.waitForResponse(
(response) => new URL(response.url()).pathname === '/api/auth/get-session'
)
await recovery.goto(`chrome-extension://${extensionId}/sidepanel.html`)
const app = recovery.frames().find((candidate) => candidate.url().startsWith(base.origin))
assert(app, 'Recovery panel must load the real app')
await app.getByRole('heading', { name: 'Sign in to Sim', exact: true }).click()
assert.equal(await (await signedOutSession).json(), null)
await expect
.poll(
() =>
[...pendingRequests].filter(
(request) =>
request.frame().page() === recovery &&
new URL(request.url()).pathname === '/api/auth/get-session'
).length
)
.toBe(0)
const events = await app.evaluateHandle(() => {
let focus = 0
let visibility = 0
const focused = () => focus++
const visible = () => visibility++
window.addEventListener('focus', focused)
document.addEventListener('visibilitychange', visible)
return {
snapshot: () => ({
focus,
visibility,
focused: document.hasFocus(),
visibilityState: document.visibilityState,
}),
dispose: () => {
window.removeEventListener('focus', focused)
document.removeEventListener('visibilitychange', visible)
},
}
})
try {
await signInAndSeed()
const beforeRefresh = await events.evaluate((observer) => observer.snapshot())
signInRecoveryReceipts.push({ phase: 'before-refresh', ...beforeRefresh })
assert.deepEqual(beforeRefresh, {
focus: 0,
visibility: 0,
focused: true,
visibilityState: 'visible',
})
await expect(
app.getByRole('heading', { name: 'Sign in to Sim', exact: true })
).toBeVisible()
await screenshot('sign-in-manual-refresh', recovery)
const [response] = await Promise.all([
app.waitForNavigation({ waitUntil: 'load' }),
app.getByRole('button', { name: 'Refresh', exact: true }).click(),
])
assert(response, 'Refresh must return a document response')
assert.equal(response.status(), 200)
assert(response.request().isNavigationRequest(), 'Refresh must reload the app document')
await expect(
app.getByRole('link', { name: 'Extension QA alpha', exact: true })
).toBeVisible()
signInRecoveryReceipts.push({ phase: 'recovered', documentStatus: response.status() })
await screenshot('sign-in-manual-recovered', recovery)
} finally {
await events.evaluate((observer) => observer.dispose()).catch(() => {})
await events.dispose()
}
} finally {
await recovery.close()
}
}
)
await checkNavigation('A real Better Auth session reaches the extension iframe', async () => {
const login = await openPage()
await login.goto(`${base.origin}/login`)
await signInAndSeed()
assert(login, 'The sign-in tab must remain open until returning to the original panel')
await login.close()
await shell.bringToFront()
await expect(
Expand Down Expand Up @@ -3343,6 +3423,7 @@ try {
screenshots,
browserErrors,
voiceDiagnostics,
signInRecoveryReceipts,
failedRequests,
pendingRequests: pendingAtFailure,
failureState,
Expand Down
Loading