test: stabilize PR validation and install server adapter dependencies

This commit is contained in:
程序员阿江(Relakkes)
2026-09-07 21:41:31 +08:00
parent 9c081af746
commit 9e4f83bbe3
3 changed files with 43 additions and 10 deletions
+3
View File
@@ -128,6 +128,9 @@ jobs:
bun-version-file: package.json
- name: Install root dependencies
run: bun install --frozen-lockfile
- name: Install adapter dependencies
working-directory: adapters
run: bun install --frozen-lockfile
- name: Run root runtime checks
run: bun run check:server
+28 -9
View File
@@ -1,4 +1,4 @@
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import { act, cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import '@testing-library/jest-dom'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { TraceSession } from './TraceSession'
@@ -503,16 +503,35 @@ describe('TraceSession', () => {
},
calls: [baseTrace.calls[0]!, makeCall({ id: 'call-2', startedAt: '2026-06-09T10:00:08.000Z' })],
})
await renderReady(20)
// Advance polls only after each state is asserted. A real 20ms interval can
// invalidate the detail cache before the initial assertion under coverage.
vi.useFakeTimers({ toFake: ['setInterval', 'clearInterval'] })
try {
await renderReady(20)
fireEvent.click(within(screen.getByTestId('trace-tree')).getByText('claude-sonnet-4-5'))
await waitFor(() => expect(sessionsApi.getTraceCall).toHaveBeenCalledTimes(1))
await waitFor(() => expect(vi.mocked(sessionsApi.getTrace).mock.calls.length).toBeGreaterThanOrEqual(3))
fireEvent.click(within(screen.getByTestId('trace-tree')).getByText('claude-sonnet-4-5'))
await waitFor(() => expect(sessionsApi.getTraceCall).toHaveBeenCalledTimes(1))
expect(sessionsApi.getTrace).toHaveBeenCalledTimes(1)
expect(sessionsApi.getMessages).toHaveBeenCalledTimes(1)
await screen.findByText('claude-sonnet-4-5 x2')
expect(vi.mocked(sessionsApi.getTraceCall).mock.calls.length).toBeGreaterThan(1)
const detail = within(screen.getByTestId('trace-detail'))
expect(detail.getByRole('heading', { level: 2, name: 'claude-sonnet-4-5' })).toBeInTheDocument()
for (const expectedTraceCalls of [2, 3]) {
await act(async () => { await vi.advanceTimersByTimeAsync(20) })
expect(sessionsApi.getTrace).toHaveBeenCalledTimes(expectedTraceCalls)
expect(sessionsApi.getMessages).toHaveBeenCalledTimes(1)
expect(screen.queryByText('claude-sonnet-4-5 x2')).not.toBeInTheDocument()
}
await act(async () => { await vi.advanceTimersByTimeAsync(20) })
expect(sessionsApi.getTrace).toHaveBeenCalledTimes(4)
expect(sessionsApi.getMessages).toHaveBeenCalledTimes(2)
expect(screen.getByText('claude-sonnet-4-5 x2')).toBeInTheDocument()
expect(vi.mocked(sessionsApi.getTraceCall).mock.calls.length).toBeGreaterThan(1)
const detail = within(screen.getByTestId('trace-detail'))
expect(detail.getByRole('heading', { level: 2, name: 'claude-sonnet-4-5' })).toBeInTheDocument()
} finally {
cleanup()
vi.useRealTimers()
}
})
it('does not refetch full messages for identical trace polls', async () => {
+12 -1
View File
@@ -4,7 +4,7 @@ import { parse } from 'yaml'
type WorkflowJob = {
needs?: string | string[]
steps?: Array<{ name?: string; run?: string }>
steps?: Array<{ name?: string; run?: string; 'working-directory'?: string }>
}
function workflowJobs(workflow: string) {
@@ -70,6 +70,17 @@ describe('PR quality workflow', () => {
}
})
test('installs adapter dependencies before root server tests that import adapters', () => {
const jobs = workflowJobs(readFileSync('.github/workflows/pr-quality.yml', 'utf8'))
const steps = jobs['server-checks'].steps ?? []
const adapterInstall = steps.findIndex(step =>
step['working-directory'] === 'adapters' && step.run === 'bun install --frozen-lockfile',
)
const serverCheck = steps.findIndex(step => step.run === 'bun run check:server')
expect(adapterInstall).toBeGreaterThanOrEqual(0)
expect(adapterInstall).toBeLessThan(serverCheck)
})
test('keeps coverage artifacts observable in CI', () => {
const workflow = readFileSync('.github/workflows/pr-quality.yml', 'utf8')