Files
orca/src/main/computer/desktop-script-provider-errors.test.ts
T
Neil ef90f6099c fix(computer): supervise Linux and Windows desktop providers from main (#11468)
* fix(computer): supervise desktop providers from main

* fix(computer): remove unreachable provider timeout mapping

* test(computer): flush stale supervisor response
2026-07-29 19:14:10 -07:00

127 lines
3.9 KiB
TypeScript

import { afterEach, describe, expect, it } from 'vitest'
import {
createDesktopScriptProviderClient,
mockBridgeExecutionError,
mockBridgeResponse,
resetDesktopScriptProviderTestHarness,
sampleBridgeSnapshot,
sampleCapabilities
} from './desktop-script-provider-test-harness'
describe('DesktopScriptProviderClient errors and capabilities', () => {
afterEach(resetDesktopScriptProviderTestHarness)
it('explains screenshot capture failures while keeping accessibility state usable', async () => {
mockBridgeResponse({
ok: true,
snapshot: {
...sampleBridgeSnapshot('Text Editor', 'initial'),
screenshotPngBase64: null
}
})
const client = await createDesktopScriptProviderClient('linux', '/tmp/runtime.py')
await expect(client.snapshot({ app: 'Text Editor' })).resolves.toMatchObject({
snapshot: {
elementCount: 1
},
screenshotStatus: {
state: 'failed',
code: 'screenshot_failed',
message: expect.stringContaining('--no-screenshot')
}
})
})
it('preserves desktop provider screenshot failure reasons', async () => {
mockBridgeResponse({
ok: true,
snapshot: {
...sampleBridgeSnapshot('Text Editor', 'initial'),
screenshotPngBase64: null,
screenshotError: {
code: 'screenshot_failed',
message:
'screenshot exceeded the computer-use payload cap after downscaling; retry with --no-screenshot or target a smaller window'
}
}
})
const client = await createDesktopScriptProviderClient('linux', '/tmp/runtime.py')
await expect(client.snapshot({ app: 'Text Editor' })).resolves.toMatchObject({
snapshot: {
elementCount: 1
},
screenshotStatus: {
state: 'failed',
code: 'screenshot_failed',
message: expect.stringContaining('payload cap')
}
})
})
it('normalizes list-windows responses after provider handshake', async () => {
mockBridgeResponse({
ok: true,
capabilities: sampleCapabilities()
})
mockBridgeResponse({
ok: true,
app: { name: 'Text Editor', bundleIdentifier: 'Text Editor', pid: 100 },
windows: [
{
index: 0,
app: { name: 'Text Editor', bundleIdentifier: 'Text Editor', pid: 100 },
id: 99,
title: 'Document',
x: 10,
y: 20,
width: 300,
height: 200,
isMinimized: false,
isOffscreen: false,
screenIndex: null,
platform: { backend: 'at-spi' }
}
]
})
const client = await createDesktopScriptProviderClient('linux', '/tmp/runtime.py')
await expect(client.listWindows({ app: 'Text Editor' })).resolves.toMatchObject({
app: { name: 'Text Editor', bundleId: 'Text Editor', pid: 100 },
windows: [{ index: 0, id: 99, title: 'Document' }]
})
})
it('maps bridge app errors to RuntimeClientError codes', async () => {
mockBridgeResponse({ ok: false, error: 'appNotFound("Missing")' })
const client = await createDesktopScriptProviderClient('linux', '/tmp/runtime.py')
await expect(client.snapshot({ app: 'Missing' })).rejects.toMatchObject({
code: 'app_not_found'
})
})
it('maps blocked app bridge errors to a policy error', async () => {
mockBridgeResponse({ ok: false, error: 'appBlocked("1Password")' })
const client = await createDesktopScriptProviderClient('windows', '/tmp/runtime.ps1')
await expect(client.snapshot({ app: '1Password' })).rejects.toMatchObject({
code: 'app_blocked'
})
})
it('maps supervised provider process failures', async () => {
mockBridgeExecutionError('appNotFound("Missing")')
const client = await createDesktopScriptProviderClient('linux', '/tmp/runtime.py')
await expect(client.listApps()).rejects.toMatchObject({ code: 'app_not_found' })
})
})