test: exercise application selection through the recorded Web session

This commit is contained in:
creatixchu committed 2026-09-20 10:41:48 +08:00
1 parent 0ae1b2f91c
commit e435340eff
5 files changed
+32 -8

No files matched your search

+22 -3
View File
@@ -102,10 +102,17 @@ describe.skipIf(MODE === 'record')('web e2e: document preview through Files', ()
const command = process.platform === 'darwin' ? 'open' : 'xdg-open'
await writeFile(join(nativeRoot, command), `#!/usr/bin/env node
const fs = require('node:fs');
const path = process.argv[2] === '-R' ? process.argv[3] : process.argv[2];
const action = process.argv[2] === '-R' || fs.statSync(path).isDirectory() ? 'reveal' : 'open';
const path = process.argv[2] === '-a' ? process.argv[4] : process.argv[2] === '-R' ? process.argv[3] : process.argv[2];
const action = process.argv[2] === '-a' ? 'application' : process.argv[2] === '-R' || fs.statSync(path).isDirectory() ? 'reveal' : 'open';
fs.appendFileSync(${JSON.stringify(openLog)}, JSON.stringify({ path, action }) + '\\n');
`, { mode: 0o700 })
if (process.platform === 'darwin') {
const apps = [
{ id: '/Applications/Test Player.app', name: 'Test Player', default: true, icon: `data:image/png;base64,${TINY_PNG.toString('base64')}` },
{ id: '/Applications/Other Player.app', name: 'Other Player', default: false, icon: null },
]
await writeFile(join(nativeRoot, 'osascript'), `#!/usr/bin/env node\nprocess.stdout.write(${JSON.stringify(JSON.stringify(apps))});\n`, { mode: 0o700 })
}
vi.stubEnv('PATH', `${nativeRoot}${delimiter}${process.env.PATH ?? ''}`)
}
// The Open In rows carry the default-application controls; the SSH marker
@@ -756,13 +763,25 @@ fs.appendFileSync(${JSON.stringify(openLog)}, JSON.stringify({ path, action }) +
expect(gestures[0]).toEqual({ path: clip, action: 'open' })
expect(gestures[1]?.action).toBe('reveal')
expect([clip, cwd]).toContain(gestures[1]?.path)
if (process.platform === 'darwin') {
await expect.poll(() => headerOpen.locator('img').count()).toBe(1)
await unsupported.locator('[data-open-path-more]').click()
await page.getByRole('menuitem', { name: 'Test Player (default)', exact: true }).waitFor()
await compareOrRefreshGolden(join(SNAPSHOT_DIR, 'applications.expected.md'), await page.getByRole('menu').ariaSnapshot(), MODE)
await page.getByRole('menuitem', { name: 'Other Player', exact: true }).click()
await expect.poll(async () => (await opened()).length).toBe(3)
expect((await opened())[2]).toEqual({ path: clip, action: 'application' })
await headerOpen.click()
await expect.poll(async () => (await opened()).length).toBe(4)
expect((await opened())[3]).toEqual({ path: clip, action: 'open' })
}
// Gesture facts stay out of the golden: the stub does not run on Windows.
expect(await page.getByRole('alert').count()).toBe(0)
}
expect(tripwire.pageErrors).toEqual([])
expect(tripwire.warnings).toEqual([])
await compareOrRefreshGolden(EXPECTED, sections.join('\n\n'), MODE)
await assertFixtureInventory(SNAPSHOT_DIR, ['document.expected.md', 'paging.patch.yml'])
await assertFixtureInventory(SNAPSHOT_DIR, ['document.expected.md', 'applications.expected.md', 'paging.patch.yml'])
})
})
@@ -182,7 +182,7 @@ it('keeps default opening available when application discovery fails', async ()
const b = bench()
render(<OpenPathAction {...b.props} applications={async () => null} />)
await act(async () => { fireEvent.click(screen.getByRole('button', { name: zh['path.more'] })) })
expect(screen.getByRole('menuitem', { name: zh['path.appsError'] }).getAttribute('aria-disabled')).toBe('true')
expect(screen.getByRole('menuitem', { name: zh['path.appsError'] }).hasAttribute('disabled')).toBe(true)
await act(async () => { fireEvent.click(screen.getByRole('menuitem', { name: zh['path.defaultApp'] })) })
expect(b.openPath).toHaveBeenLastCalledWith(ABSOLUTE_PATH, 'open', undefined)
})
@@ -50,7 +50,7 @@ export async function nativeFileApplications(
const platform = internals.platform ?? process.platform
if (platform !== 'darwin') return []
const run = internals.run ?? runNativeCommand
const { stdout } = await run('/usr/bin/osascript', ['-l', 'JavaScript', '-e', MAC_APPLICATIONS, path], signal)
const { stdout } = await run('osascript', ['-l', 'JavaScript', '-e', MAC_APPLICATIONS, path], signal)
const value: unknown = JSON.parse(stdout)
if (!Array.isArray(value)) throw new Error('Invalid native application list')
const applications: NativeFileApplication[] = []
@@ -80,5 +80,5 @@ export async function openNativeFileApplication(
const apps = await nativeFileApplications(path, signal, internals)
if (!apps.some(app => app.id === application)) throw new Error('Application is not registered for this file')
const run = internals.run ?? runNativeCommand
await run('/usr/bin/open', ['-a', application, path], signal)
await run('open', ['-a', application, path], signal)
}
@@ -10,7 +10,7 @@ describe('native file associations', () => {
const run = vi.fn(async () => ({ stdout: JSON.stringify([application]), stderr: '' }))
const path = '/tmp/中文 $(touch nope).mp3'
await expect(nativeFileApplications(path, signal, { platform: 'darwin', run })).resolves.toEqual([application])
expect(run).toHaveBeenCalledWith('/usr/bin/osascript', ['-l', 'JavaScript', '-e', expect.any(String), path], signal)
expect(run).toHaveBeenCalledWith('osascript', ['-l', 'JavaScript', '-e', expect.any(String), path], signal)
})
it.each(['{}', '[null]', '[{"id":1}]', JSON.stringify([{ ...application, icon: 'javascript:alert(1)' }])])('rejects malformed native output %s', async (stdout) => {
@@ -22,7 +22,7 @@ describe('native file associations', () => {
it('launches only a currently registered application with argv', async () => {
const run = vi.fn(async () => ({ stdout: JSON.stringify([application]), stderr: '' }))
await openNativeFileApplication('/file.mp3', application.id, signal, { platform: 'darwin', run })
expect(run).toHaveBeenLastCalledWith('/usr/bin/open', ['-a', application.id, '/file.mp3'], signal)
expect(run).toHaveBeenLastCalledWith('open', ['-a', application.id, '/file.mp3'], signal)
run.mockClear()
await expect(openNativeFileApplication('/file.mp3', '/arbitrary.app', signal, { platform: 'darwin', run })).rejects.toThrow('not registered')
expect(run).toHaveBeenCalledOnce()
@@ -0,0 +1,5 @@
- menu:
- menuitem "Open in default app"
- menuitem "Test Player (default)"
- menuitem "Other Player"
- menuitem "Show file location"