mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 08:03:12 +00:00
Hosted iOS security e2e (three branch-only harness bugs): - `simctl privacy grant` terminates the app; the relaunch cold-resumes straight onto the session route, so skip workspace-row activation when the hybrid handoff already landed on /session/. Activation failures now name the document href. - Uploaded-path regex fused two abutting orca-paste-*.png paths; use a lazy segment quantifier. - Photos orders by capture date, which addmedia takes from file birth time; stage a freshly written fixture copy (copyFile clones birth time on APFS) so "last Photo" is the fixture. Root tests: - Allowlist walker skips -test-fakes / -test-fixture(s) / .test-support sources, which are not mobile call sites. - Drop the height-only OSC-8 test: main's #17759 clears restored ranges on any dimension change and pins it. - Drop serve-update-handoff-startup-order.test.ts: main pins the same order against main-process-preflight.ts. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
106 lines
2.6 KiB
JavaScript
106 lines
2.6 KiB
JavaScript
import { activateHostedWebViewControl } from './hosted-webview-cdp-session.mjs'
|
|
|
|
export async function activateHostedWorkspaceRow(
|
|
document,
|
|
workspaceName,
|
|
activateControl = activateHostedWebViewControl,
|
|
timeoutMs = 30_000,
|
|
resolveDocument
|
|
) {
|
|
const deadline = Date.now() + timeoutMs
|
|
let activeDocument = document
|
|
let lastError
|
|
while (Date.now() < deadline) {
|
|
try {
|
|
await activateHostedWorkspaceRowOnce(activeDocument, workspaceName, activateControl)
|
|
return
|
|
} catch (error) {
|
|
if (isStaleDocument(error) && resolveDocument) {
|
|
activeDocument = await resolveDocument()
|
|
continue
|
|
}
|
|
if (isMissingControl(error) && resolveDocument) {
|
|
const resolvedDocument = await resolveDocument()
|
|
if (resolvedDocument.href !== activeDocument.href) {
|
|
return
|
|
}
|
|
activeDocument = resolvedDocument
|
|
}
|
|
if (!isMissingControl(error)) {
|
|
throw error
|
|
}
|
|
lastError = error
|
|
await delay(250)
|
|
}
|
|
}
|
|
throw new Error(
|
|
`${lastError?.message ?? `Hosted WebView control was not found: ${workspaceName}`} (document ${activeDocument.href})`,
|
|
{ cause: lastError }
|
|
)
|
|
}
|
|
|
|
async function activateHostedWorkspaceRowOnce(document, workspaceName, activateControl) {
|
|
try {
|
|
await activateControl(document, {
|
|
kind: 'label',
|
|
value: `Open ${workspaceName}`,
|
|
reveal: true
|
|
})
|
|
return
|
|
} catch (error) {
|
|
if (!isMissingControl(error)) {
|
|
throw error
|
|
}
|
|
}
|
|
try {
|
|
await activateControl(document, {
|
|
kind: 'text',
|
|
value: workspaceName,
|
|
ignoreCase: true,
|
|
occurrence: 1,
|
|
reveal: true
|
|
})
|
|
} catch (error) {
|
|
if (!isMissingControl(error)) {
|
|
throw error
|
|
}
|
|
await activateControl(document, {
|
|
kind: 'text',
|
|
value: workspaceName,
|
|
ignoreCase: true,
|
|
reveal: true
|
|
})
|
|
await delay(250)
|
|
try {
|
|
await activateControl(document, {
|
|
kind: 'text',
|
|
value: workspaceName,
|
|
ignoreCase: true,
|
|
occurrence: 1,
|
|
reveal: true
|
|
})
|
|
} catch (fallbackError) {
|
|
if (isStaleDocument(fallbackError)) {
|
|
return
|
|
}
|
|
throw fallbackError
|
|
}
|
|
}
|
|
}
|
|
|
|
function isMissingControl(error) {
|
|
return error instanceof Error && error.message.includes('control was not found')
|
|
}
|
|
|
|
function isStaleDocument(error) {
|
|
return (
|
|
error instanceof Error &&
|
|
(error.message.includes('CDP connection closed') ||
|
|
error.message.includes('Unexpected server response: 500'))
|
|
)
|
|
}
|
|
|
|
function delay(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
}
|