fix(web): make share image previews interactive (#1229)

* fix(web): make share preview controls interactive

* fix(web): preserve lightbox modal focus
This commit is contained in:
Ananovo
2026-07-30 23:20:23 +08:00
committed by GitHub
parent f8934d81ee
commit 99814e9668
7 changed files with 305 additions and 97 deletions
+55 -2
View File
@@ -37,7 +37,7 @@ for (const viewport of [
await expect(page.getByRole('dialog').getByText('Excluded tool output')).toHaveCount(0)
await expect(page.getByRole('dialog').locator('.happy-message-actions')).toHaveCount(0)
await expect(page.getByRole('dialog').locator('.hapi-share-hidden-content-spacer')).toHaveCount(1)
await expect(page.getByRole('dialog').locator('[title="Click to zoom"]')).toHaveCount(0)
await expect(page.getByRole('dialog').locator('[title="Click to zoom"]')).toHaveCount(2)
if (viewport.name === 'desktop') {
const styles = await page.evaluate(() => {
const source = document.querySelector<HTMLElement>('[data-testid="source-turn"]')
@@ -134,11 +134,64 @@ test('localizes the share dialog actions in Chinese', async ({ page }) => {
await expect(dialog.getByText('分享会话', { exact: true })).toHaveCount(0)
await expect(dialog.getByText('Generated by HAPI', { exact: true })).toBeVisible()
await expect(dialog.getByRole('button', { name: '取消' })).toHaveCount(0)
await expect(dialog.getByRole('button', { name: '复制' })).toBeVisible()
await expect(dialog.getByRole('button', { name: '复制' }).last()).toBeVisible()
await expect(dialog.getByRole('button', { name: '分享' })).toBeVisible()
await expect(dialog.getByRole('button', { name: '下载' })).toBeVisible()
})
test('keeps code and image controls interactive in preview', async ({ page }, testInfo) => {
await page.context().grantPermissions(['clipboard-read', 'clipboard-write'])
await page.goto('/e2e-fixtures/share-turn-fixture.html')
await page.getByRole('button', { name: 'Open share preview' }).click()
const dialog = page.getByRole('dialog', { name: 'Share turn as image' })
const wrapButton = dialog.locator('[data-hapi-code-wrap-toggle="true"]').first()
await expect(wrapButton).toHaveAttribute('aria-pressed', 'false')
const unwrappedDownloadPromise = page.waitForEvent('download')
await dialog.getByRole('button', { name: 'Download' }).click()
const unwrappedDownload = await unwrappedDownloadPromise
const unwrappedPath = testInfo.outputPath('interactive-unwrapped.png')
await unwrappedDownload.saveAs(unwrappedPath)
const unwrappedSize = pngSize(await readFile(unwrappedPath))
await wrapButton.click()
await expect(wrapButton).toHaveAttribute('aria-pressed', 'true')
await expect(dialog.locator('[data-code-cell]').first()).toHaveCSS('white-space', 'pre-wrap')
const wrappedDownloadPromise = page.waitForEvent('download')
await dialog.getByRole('button', { name: 'Download' }).click()
const wrappedDownload = await wrappedDownloadPromise
const wrappedPath = testInfo.outputPath('interactive-wrapped.png')
await wrappedDownload.saveAs(wrappedPath)
const wrappedSize = pngSize(await readFile(wrappedPath))
expect(wrappedSize.height).toBeGreaterThan(unwrappedSize.height)
const copyButton = dialog.locator('[data-hapi-code-copy="true"]').first()
await copyButton.click()
await expect(copyButton).toHaveAttribute('title', 'Copied')
await expect.poll(() => page.evaluate(() => navigator.clipboard.readText())).toContain('type ExportResult')
const previewImage = dialog.locator('[data-image-preview-trigger] img').first()
const previewImageBox = await previewImage.boundingBox()
await previewImage.click()
const imageDialog = page.getByRole('dialog', { name: 'HAPI landscape export fixture' })
await expect(imageDialog).toBeVisible()
const lightboxImageBox = await imageDialog.getByRole('img', { name: 'HAPI landscape export fixture' }).boundingBox()
expect(lightboxImageBox?.width ?? 0).toBeGreaterThan(previewImageBox?.width ?? 0)
const fitButton = imageDialog.getByTitle('Fit to screen')
await expect(fitButton).toHaveText('100%')
await imageDialog.getByRole('img', { name: 'HAPI landscape export fixture' }).hover()
await page.mouse.wheel(0, -100)
await expect(fitButton).not.toHaveText('100%')
await page.keyboard.press('Tab')
await expect(imageDialog.locator(':focus')).toHaveCount(1)
await page.keyboard.press('Escape')
await expect(page.getByRole('dialog', { name: 'HAPI landscape export fixture' })).toHaveCount(0)
await expect(dialog).toBeVisible()
})
test('uses a prepared PNG while native share still has click activation', async ({ page }) => {
await page.addInitScript(() => {
const state = { calls: 0, active: false, fileType: '', fileName: '' }