Skip to content

Commit 232908b

Browse files
committed
chore(extension): cover composer focus while a dialog is open
1 parent d37ceb9 commit 232908b

1 file changed

Lines changed: 102 additions & 1 deletion

File tree

‎apps/sim/scripts/test-browser-extension-e2e.ts‎

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ try {
479479
)
480480
return
481481
document.body.dataset.captureReceipts = String(++receipts)
482+
if ('sessionId' in event.data && typeof event.data.sessionId === 'string')
483+
document.body.dataset.captureSession = event.data.sessionId
482484
})
483485
}, base.origin)
484486
await observeCaptureReceipts()
@@ -556,7 +558,106 @@ try {
556558
captureText.replace('QA_PRIVATE_PAGE_MARKER:', 'Delivery plan\nQA_PRIVATE_PAGE_MARKER:')
557559
)
558560
await screenshot('page-preview')
559-
await preview.getByRole('button', { name: 'Close', exact: true }).click()
561+
const focusSession = await shell.locator('body').getAttribute('data-capture-session')
562+
assert(focusSession, 'The real capture did not acknowledge its session')
563+
const focusObserver = await shell.evaluateHandle(
564+
({ origin, sessionId }) => {
565+
let focused = 0
566+
let processed = 0
567+
document.body.dataset.composerFocused = '0'
568+
document.body.dataset.focusProcessed = '0'
569+
const receive = (event: MessageEvent<unknown>) => {
570+
if (
571+
event.origin !== origin ||
572+
event.source !== document.querySelector('iframe')?.contentWindow ||
573+
typeof event.data !== 'object' ||
574+
event.data === null ||
575+
!('sessionId' in event.data) ||
576+
event.data.sessionId !== sessionId ||
577+
!('type' in event.data)
578+
)
579+
return
580+
if (event.data.type === 'composer-focused')
581+
document.body.dataset.composerFocused = String(++focused)
582+
if (event.data.type === 'e2e-focus-processed')
583+
document.body.dataset.focusProcessed = String(++processed)
584+
}
585+
window.addEventListener('message', receive)
586+
return () => window.removeEventListener('message', receive)
587+
},
588+
{ origin: base.origin, sessionId: focusSession }
589+
)
590+
const focusBarrier = await frame().evaluateHandle(
591+
({ origin, sessionId }) => {
592+
const receive = (event: MessageEvent<unknown>) => {
593+
if (
594+
event.origin !== origin ||
595+
event.source !== parent ||
596+
typeof event.data !== 'object' ||
597+
event.data === null ||
598+
!('sessionId' in event.data) ||
599+
event.data.sessionId !== sessionId ||
600+
!('type' in event.data) ||
601+
event.data.type !== 'focus-composer'
602+
)
603+
return
604+
parent.postMessage({ type: 'e2e-focus-processed', sessionId }, origin)
605+
}
606+
window.addEventListener('message', receive)
607+
return () => window.removeEventListener('message', receive)
608+
},
609+
{ origin: `chrome-extension://${extensionId}`, sessionId: focusSession }
610+
)
611+
const requestComposerFocus = async (processed: number) => {
612+
await shell.evaluate(
613+
({ origin, sessionId }) =>
614+
document
615+
.querySelector('iframe')
616+
?.contentWindow?.postMessage(
617+
{ channel: 'sim-extension', version: 1, type: 'focus-composer', sessionId },
618+
origin
619+
),
620+
{ origin: base.origin, sessionId: focusSession }
621+
)
622+
await expect(shell.locator('body')).toHaveAttribute(
623+
'data-focus-processed',
624+
String(processed)
625+
)
626+
}
627+
try {
628+
await shell.bringToFront()
629+
const close = preview.getByRole('button', { name: 'Close', exact: true })
630+
await close.focus()
631+
await expect(close).toBeFocused()
632+
assert(await frame().evaluate(() => document.hasFocus()))
633+
await requestComposerFocus(1)
634+
assert.equal(
635+
await shell.locator('body').getAttribute('data-composer-focused'),
636+
'0',
637+
'An app dialog must not acknowledge composer focus'
638+
)
639+
await expect(close).toBeFocused()
640+
await close.press('Tab')
641+
assert(await preview.evaluate((element) => element.contains(document.activeElement)))
642+
await requestComposerFocus(2)
643+
assert.equal(await shell.locator('body').getAttribute('data-composer-focused'), '0')
644+
await screenshot('focus-deferred-by-page-preview')
645+
await close.click()
646+
await expect(preview).toHaveCount(0)
647+
await requestComposerFocus(3)
648+
const editor = frame().getByRole('textbox', { name: 'Message', exact: true })
649+
await expect(editor).toBeFocused()
650+
await expect(shell.locator('body')).toHaveAttribute('data-composer-focused', '1')
651+
await shell.keyboard.type('Keyboard input belongs to the composer.')
652+
await expect(editor).toHaveValue('Keyboard input belongs to the composer.')
653+
await screenshot('focus-confirmed-in-composer')
654+
await editor.fill('')
655+
} finally {
656+
await focusBarrier.evaluate((stop) => stop())
657+
await focusObserver.evaluate((stop) => stop())
658+
await focusBarrier.dispose()
659+
await focusObserver.dispose()
660+
}
560661
await capture()
561662
await capture()
562663
await capture()

0 commit comments

Comments
 (0)