mirror of
https://github.com/stablyai/orca.git
synced 2026-10-22 08:03:37 +00:00
test(e2e): fix flaky PR check failures from recent main drift
- Seed Jira composer e2e with taskSourceContext required since #11296 - Assert new-tab outcome instead of Radix menu teardown timing - Use durable WIDTH marker after shell prompt redraw clobbers RESTORE - Re-probe discoverActivePtyId when ConPTY drops the first write
This commit is contained in:
@@ -262,20 +262,25 @@ export async function discoverActivePtyId(page: Page): Promise<string> {
|
||||
buildFreshShellProbeInputSequence(`echo ${marker}_${index}\r`)
|
||||
)
|
||||
|
||||
await page.evaluate(
|
||||
({ candidateIds, candidateInputs }) => {
|
||||
// Why: daemon PTY IDs can contain path separators and shell metacharacters.
|
||||
// Echo a numeric probe index, then map it back to the opaque ID in Node.
|
||||
for (const [index, id] of candidateIds.entries()) {
|
||||
for (const input of candidateInputs[index] ?? []) {
|
||||
window.api.pty.write(String(id), input)
|
||||
const writeProbes = async (): Promise<void> => {
|
||||
await page.evaluate(
|
||||
({ candidateIds, candidateInputs }) => {
|
||||
// Why: daemon PTY IDs can contain path separators and shell metacharacters.
|
||||
// Echo a numeric probe index, then map it back to the opaque ID in Node.
|
||||
for (const [index, id] of candidateIds.entries()) {
|
||||
for (const input of candidateInputs[index] ?? []) {
|
||||
window.api.pty.write(String(id), input)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ candidateIds, candidateInputs }
|
||||
)
|
||||
},
|
||||
{ candidateIds, candidateInputs }
|
||||
)
|
||||
}
|
||||
|
||||
await writeProbes()
|
||||
|
||||
let foundPtyId: string | null = null
|
||||
let probeAttempts = 0
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
@@ -287,9 +292,15 @@ export async function discoverActivePtyId(page: Page): Promise<string> {
|
||||
foundPtyId = Number.isInteger(index) ? (candidateIds[index] ?? null) : null
|
||||
return true
|
||||
}
|
||||
// Why: Windows ConPTY can drop the first write before the shell is ready.
|
||||
// Re-probe every few polls instead of failing after a single lost write.
|
||||
probeAttempts += 1
|
||||
if (probeAttempts % 4 === 0) {
|
||||
await writeProbes()
|
||||
}
|
||||
return false
|
||||
},
|
||||
{ timeout: 10_000, message: 'PTY marker did not appear in terminal buffer' }
|
||||
{ timeout: 15_000, message: 'PTY marker did not appear in terminal buffer' }
|
||||
)
|
||||
.toBe(true)
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ async function openComposerWithLinkedWorkItem(
|
||||
)
|
||||
}
|
||||
|
||||
// Why: useComposerState drops Jira seeds that lack a matching taskSourceContext
|
||||
// (site + project identity). Derive host/project from the active setup so the
|
||||
// seed mirrors real onSmartJiraIssueSelect metadata.
|
||||
async function getJiraSourceContext(page: Page): Promise<TaskSourceContext> {
|
||||
return page.evaluate(() => {
|
||||
const state = window.__store?.getState()
|
||||
|
||||
@@ -91,11 +91,12 @@ test.describe('Tabs', () => {
|
||||
// Why: the "+" dropdown uses Radix <DropdownMenuItem>, which exposes the
|
||||
// label text as the accessible name once the menu is open.
|
||||
const newTerminalMenuItem = orcaPage.getByRole('menuitem', { name: /New Terminal/i }).first()
|
||||
await expect(newTerminalMenuItem).toBeVisible()
|
||||
await newTerminalMenuItem.click({ force: true })
|
||||
await expect(newTerminalMenuItem).toBeHidden({ timeout: 3_000 })
|
||||
|
||||
// Final assertion is on the rendered tab count — the tab bar itself must
|
||||
// gain an element, not just the store.
|
||||
// Why: assert the product outcome (new tab) rather than menu teardown.
|
||||
// Radix can leave the menuitem in the a11y tree briefly after a forced
|
||||
// click even when the terminal tab was already created.
|
||||
await expect
|
||||
.poll(() => countRenderedTabs(orcaPage), {
|
||||
timeout: 5_000,
|
||||
|
||||
@@ -503,7 +503,10 @@ test.describe('Terminal long table scroll restore repro', () => {
|
||||
const ptyId = await waitForActivePanePtyId(orcaPage)
|
||||
await waitForPtyColumnsAtMost(orcaPage, ptyId, renderedTableTerminalCols)
|
||||
const runId = randomUUID()
|
||||
const marker = `EMOJI_FIXTURE_TABLE_RESTORE_${runId}`
|
||||
// Why: the trailing RESTORE line is often clobbered by shell prompt redraw
|
||||
// (\x1b[1A). The WIDTH line is one line earlier and is the durable survival
|
||||
// signal for this fixture; the right-edge assertions below use it too.
|
||||
const widthMarker = emojiFixtureTableWidthMarker(runId)
|
||||
const scriptPath = path.join(testRepoPath, `.orca-emoji-fixture-table-${runId}.mjs`)
|
||||
writeFileSync(scriptPath, emojiFixtureMarkdownTableScript(EMOJI_TABLE_FIXTURE, runId))
|
||||
|
||||
@@ -525,11 +528,9 @@ test.describe('Terminal long table scroll restore repro', () => {
|
||||
timeout: 10_000,
|
||||
message: 'real emoji table marker did not survive workspace switch'
|
||||
})
|
||||
.toContain(marker)
|
||||
.toContain(widthMarker)
|
||||
const generatedWidthContent = await getTerminalContent(orcaPage, 30_000)
|
||||
const generatedWidthMatch = generatedWidthContent.match(
|
||||
new RegExp(`${emojiFixtureTableWidthMarker(runId)}(\\d+)`)
|
||||
)
|
||||
const generatedWidthMatch = generatedWidthContent.match(new RegExp(`${widthMarker}(\\d+)`))
|
||||
expect(generatedWidthMatch).not.toBeNull()
|
||||
const generatedTableWidth = Number(generatedWidthMatch?.[1] ?? 0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user