test: repair nested SSH fixture after HUB restart (#19098)

* test: restore paired nested SSH fixture after HUB restart

* test: cover failed re-pair selection and background window safety

* test: use required braces in re-pair regression fixture

* test: use current paired runtime identity after re-pairing
This commit is contained in:
Neil
2026-09-06 09:51:31 -07:00
committed by GitHub
parent 5dab495655
commit b459b8f16d
4 changed files with 150 additions and 59 deletions
@@ -1,4 +1,6 @@
import type { Page } from '@stablyai/playwright-test'
import type { PairedElectronClient, RuntimeDesktopPairingOffer } from './paired-electron-client'
import { revealPairedClientWindow } from './paired-client-window-reveal'
/**
* Points a freshly launched paired desktop client at the HUB runtime and makes it the active
@@ -35,3 +37,71 @@ export async function selectPairedRuntimeEnvironment(
return environmentId
}, args)
}
export async function rePairPairedElectronClient(
client: PairedElectronClient,
offer: RuntimeDesktopPairingOffer,
name: string
): Promise<void> {
await client.captureDirectSshAttempts()
const environmentId = await client.page.evaluate(
async ({ currentEnvironmentId, name, pairingUrl }) => {
const store = window.__store
if (!store) {
throw new Error('Paired desktop store is unavailable')
}
if (!(await store.getState().setActiveRuntimeEnvironmentPreference(null))) {
throw new Error('Paired desktop could not select local before replacing the HUB')
}
await window.api.runtimeEnvironments.remove({ selector: currentEnvironmentId })
const result = await window.api.runtimeEnvironments.addFromPairingCode({
name,
pairingCode: pairingUrl
})
store.getState().setRuntimeEnvironments(await window.api.runtimeEnvironments.list())
if (!(await store.getState().refreshRuntimeEnvironmentStatus(result.environment.id))) {
throw new Error('Re-paired desktop could not reach the HUB runtime')
}
if (!(await store.getState().setActiveRuntimeEnvironmentPreference(result.environment.id))) {
throw new Error('Re-paired desktop could not select the HUB runtime')
}
return result.environment.id
},
{
currentEnvironmentId: client.environmentId,
name,
pairingUrl: offer.pairingUrl
}
)
client.environmentId = environmentId
// Why: removing and re-adding the same HUB changes the environment identity; remount so no pane keeps the retired transport wrapper.
await client.page.reload()
// Xvfb needs a mapped window to resume actionability frames after reload.
if (
process.env.GITHUB_ACTIONS === 'true' &&
process.platform === 'linux' &&
process.env.DISPLAY &&
process.env.ORCA_BACKGROUND_LAUNCH !== '1'
) {
await revealPairedClientWindow(client)
}
await client.page.waitForFunction(
() => window.__store?.getState().workspaceSessionReady === true,
null,
{ timeout: 30_000, polling: 100 }
)
await client.installDirectSshAttemptProbe()
const reachable = await client.page.evaluate(async (nextEnvironmentId) => {
const store = window.__store
if (!store) {
throw new Error('Re-paired desktop store is unavailable after reload')
}
if (!(await store.getState().refreshRuntimeEnvironmentStatus(nextEnvironmentId))) {
return false
}
return store.getState().setActiveRuntimeEnvironmentPreference(nextEnvironmentId)
}, environmentId)
if (!reachable) {
throw new Error('Re-paired desktop could not reach the HUB after reload')
}
}
@@ -0,0 +1,74 @@
import { afterEach, expect, it, vi } from 'vitest'
import { rePairPairedElectronClient } from './paired-client-runtime-environment'
import type { PairedElectronClient } from './paired-electron-client'
afterEach(() => {
vi.unstubAllGlobals()
vi.unstubAllEnvs()
})
function fixture(canSelectLocal: boolean) {
let selected: string | null = 'old-hub'
const remove = vi.fn(async () => {
if (selected !== null) {
throw new Error('Cannot remove the selected runtime')
}
})
const state = {
setActiveRuntimeEnvironmentPreference: vi.fn(async (id: string | null) => {
if (id === null && !canSelectLocal) {
return false
}
selected = id
return true
}),
setRuntimeEnvironments: vi.fn(),
refreshRuntimeEnvironmentStatus: vi.fn(async () => true)
}
vi.stubGlobal('window', {
__store: { getState: () => state },
api: {
runtimeEnvironments: {
remove,
addFromPairingCode: vi.fn(async () => ({ environment: { id: 'new-hub' } })),
list: vi.fn(async () => [{ id: 'new-hub' }])
}
}
})
const nativeEvaluate = vi.fn()
const reload = vi.fn(async () => undefined)
const client = {
environmentId: 'old-hub',
captureDirectSshAttempts: vi.fn(async () => undefined),
installDirectSshAttemptProbe: vi.fn(async () => undefined),
app: { evaluate: nativeEvaluate },
page: {
evaluate: async (callback: (args: unknown) => unknown, args: unknown) => callback(args),
reload,
waitForFunction: vi.fn(async () => undefined)
}
} as unknown as PairedElectronClient
return { client, remove, reload, nativeEvaluate }
}
it('keeps the old pairing when selecting local fails', async () => {
const { client, remove, reload } = fixture(false)
await expect(rePairPairedElectronClient(client, { pairingUrl: 'code' }, 'HUB')).rejects.toThrow(
'could not select local'
)
expect(remove).not.toHaveBeenCalled()
expect(reload).not.toHaveBeenCalled()
expect(client.environmentId).toBe('old-hub')
})
it('replaces the active pairing without touching native windows in background mode', async () => {
vi.stubEnv('ORCA_BACKGROUND_LAUNCH', '1')
vi.stubEnv('GITHUB_ACTIONS', 'true')
vi.stubEnv('DISPLAY', ':99')
const { client, remove, reload, nativeEvaluate } = fixture(true)
await rePairPairedElectronClient(client, { pairingUrl: 'code' }, 'HUB')
expect(remove).toHaveBeenCalledWith({ selector: 'old-hub' })
expect(client.environmentId).toBe('new-hub')
expect(reload).toHaveBeenCalledOnce()
expect(nativeEvaluate).not.toHaveBeenCalled()
})
+5 -58
View File
@@ -25,6 +25,8 @@ import {
import { createPairedWebClientUrl, type PairedWebClientOptions } from './paired-web-client-url'
import { selectPairedRuntimeEnvironment } from './paired-client-runtime-environment'
export { rePairPairedElectronClient } from './paired-client-runtime-environment'
export type { SameIdPairingReplacement } from './nested-runtime-same-id-pairing'
export type PairedElectronClient = {
@@ -222,13 +224,13 @@ export async function launchPairedElectronClient(
replacementOffer: RuntimeDesktopPairingOffer
): Promise<SameIdPairingReplacement> =>
replaceRuntimePairingInPlace({
environmentId,
environmentId: client.environmentId,
page,
pairingUrl: replacementOffer.pairingUrl,
userDataDir
})
return {
const client: PairedElectronClient = {
app,
page,
environmentId,
@@ -247,6 +249,7 @@ export async function launchPairedElectronClient(
replacePairingInPlace,
userDataDir
}
return client
} catch (error) {
await closeElectronAppForE2E(app)
await cleanupE2EDaemons(userDataDir)
@@ -254,59 +257,3 @@ export async function launchPairedElectronClient(
throw error
}
}
export async function rePairPairedElectronClient(
client: PairedElectronClient,
offer: RuntimeDesktopPairingOffer,
name: string
): Promise<void> {
await client.captureDirectSshAttempts()
const environmentId = await client.page.evaluate(
async ({ currentEnvironmentId, name, pairingUrl }) => {
const store = window.__store
if (!store) {
throw new Error('Paired desktop store is unavailable')
}
await window.api.runtimeEnvironments.remove({ selector: currentEnvironmentId })
const result = await window.api.runtimeEnvironments.addFromPairingCode({
name,
pairingCode: pairingUrl
})
store.getState().setRuntimeEnvironments(await window.api.runtimeEnvironments.list())
if (!(await store.getState().refreshRuntimeEnvironmentStatus(result.environment.id))) {
throw new Error('Re-paired desktop could not reach the HUB runtime')
}
if (!(await store.getState().setActiveRuntimeEnvironmentPreference(result.environment.id))) {
throw new Error('Re-paired desktop could not select the HUB runtime')
}
return result.environment.id
},
{
currentEnvironmentId: client.environmentId,
name,
pairingUrl: offer.pairingUrl
}
)
client.environmentId = environmentId
// Why: removing and re-adding the same HUB changes the environment identity; remount so no pane keeps the retired transport wrapper.
await client.page.reload()
await client.page.waitForFunction(
() => window.__store?.getState().workspaceSessionReady === true,
null,
{ timeout: 30_000 }
)
await client.installDirectSshAttemptProbe()
const reachable = await client.page.evaluate(async (nextEnvironmentId) => {
const store = window.__store
if (!store) {
throw new Error('Re-paired desktop store is unavailable after reload')
}
if (!(await store.getState().refreshRuntimeEnvironmentStatus(nextEnvironmentId))) {
return false
}
return store.getState().setActiveRuntimeEnvironmentPreference(nextEnvironmentId)
}, environmentId)
if (!reachable) {
throw new Error('Re-paired desktop could not reach the HUB after reload')
}
}
@@ -722,7 +722,7 @@ test('restores a paired nested SSH route after the HUB restarts', async ({
if (!(await store.getState().refreshRuntimeEnvironmentStatus(environmentId))) {
return false
}
return store.getState().switchRuntimeEnvironment(environmentId)
return store.getState().setActiveRuntimeEnvironmentPreference(environmentId)
}, preRestartEnvironmentId)
expect(existingPairingRecovered).toBe(true)
await reconnectDisconnectedDockerSshRelayTarget(hubLaunch.page, remote.targetId)