test(ci): stabilize attachment fixtures
This commit is contained in:
1 parent
0516edb037
commit
de022388ea
3 files changed
+35
-20
No files matched your search
@@ -44,17 +44,6 @@ describe('web e2e: agent-preset authoring is a host-side copy', () => {
|
||||
return page.getByRole('dialog', { name: '设置' })
|
||||
}
|
||||
|
||||
/** Tokenize the lane-owned preset root after general aria normalization. */
|
||||
function withPresetRoot(snapshot: string): string {
|
||||
const rootSuffix = `/${userRoot.split('/').pop()!}`
|
||||
return snapshot.split('\n').map((line) => {
|
||||
const rootStart = line.indexOf(rootSuffix)
|
||||
if (rootStart === -1) return line
|
||||
const pathStart = line.lastIndexOf(' ', rootStart) + 1
|
||||
return `${line.slice(0, pathStart)}{{presetRoot}}${line.slice(rootStart + rootSuffix.length)}`
|
||||
}).join('\n')
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
userRoot = await realpath(await mkdtemp(join(tmpdir(), 'dsh-web-e2e-presets-')))
|
||||
scaffold = await launchWebScaffold({
|
||||
@@ -146,8 +135,9 @@ describe('web e2e: agent-preset authoring is a host-side copy', () => {
|
||||
// The copy dialog is detached, so the settings dialog is the only one
|
||||
// left (it names itself via aria-labelledby, which a CSS attribute
|
||||
// selector cannot address).
|
||||
const snapshot = withPresetRoot(
|
||||
await captureStableAria(page, '[role="dialog"]', scaffold.workspaceCwd))
|
||||
const snapshot = await captureStableAria(page, '[role="dialog"]', scaffold.workspaceCwd, {
|
||||
replacements: [[userRoot, '{{presetRoot}}']],
|
||||
})
|
||||
await compareOrRefreshGolden(CREATED_EXPECTED, snapshot, MODE)
|
||||
expect(snapshot).toContain('{{presetRoot}}/my-agent')
|
||||
|
||||
@@ -196,8 +186,9 @@ describe('web e2e: agent-preset authoring is a host-side copy', () => {
|
||||
await dialog.getByRole('button', { name: 'Agent 预设' }).click()
|
||||
await dialog.getByText('加载失败').first().waitFor({ timeout: 10_000 })
|
||||
|
||||
const snapshot = withPresetRoot(
|
||||
await captureStableAria(page, '[role="dialog"]', scaffold.workspaceCwd))
|
||||
const snapshot = await captureStableAria(page, '[role="dialog"]', scaffold.workspaceCwd, {
|
||||
replacements: [[userRoot, '{{presetRoot}}']],
|
||||
})
|
||||
await compareOrRefreshGolden(DAMAGED_EXPECTED, snapshot, MODE)
|
||||
// Both damage shapes surface as marked, unselectable, uncopyable cards
|
||||
// that still carry their metadata and the discovery-reported reason.
|
||||
|
||||
@@ -1177,20 +1177,30 @@ function normalizeAria(snapshot: string, workspaceCwd: string, age: boolean): st
|
||||
* @param selector - the region locator selector.
|
||||
* @param workspaceCwd - normalization input.
|
||||
* @param options - `normalizeAge` collapses relative-time buckets to `{{age}}`
|
||||
* for a region whose rows are dated from live wall-clock state.
|
||||
* for a region whose rows are dated from live wall-clock state;
|
||||
* `replacements` tokenizes scenario-owned values before generic normalization.
|
||||
* @returns the stable normalized snapshot.
|
||||
*/
|
||||
export async function captureStableAria(
|
||||
page: Page,
|
||||
selector: string,
|
||||
workspaceCwd: string,
|
||||
options: { normalizeAge?: boolean } = {},
|
||||
options: {
|
||||
normalizeAge?: boolean
|
||||
replacements?: readonly (readonly [value: string, token: string])[]
|
||||
} = {},
|
||||
): Promise<string> {
|
||||
const region = page.locator(selector).first()
|
||||
const age = options.normalizeAge === true
|
||||
let previous = normalizeAria(await region.ariaSnapshot(), workspaceCwd, age)
|
||||
const normalize = (snapshot: string): string => {
|
||||
for (const [value, token] of options.replacements ?? []) {
|
||||
snapshot = snapshot.split(value).join(token)
|
||||
}
|
||||
return normalizeAria(snapshot, workspaceCwd, age)
|
||||
}
|
||||
let previous = normalize(await region.ariaSnapshot())
|
||||
await expect.poll(async () => {
|
||||
const current = normalizeAria(await region.ariaSnapshot(), workspaceCwd, age)
|
||||
const current = normalize(await region.ariaSnapshot())
|
||||
const stable = current === previous
|
||||
previous = current
|
||||
return stable
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
import { SessionLogOffset } from '@deepseek-ai/dsh-session'
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type { ModelSelection as AgentModelSelection } from '@deepseek-ai/dsh-agent'
|
||||
import type { AdmittedPromptContentPart, AttachmentAdmissionPart } from '@deepseek-ai/dsh-attachment'
|
||||
import type {
|
||||
AdmittedPromptContentPart,
|
||||
AttachmentAdmissionPart,
|
||||
ImageAttachmentLimits,
|
||||
} from '@deepseek-ai/dsh-attachment'
|
||||
import type { SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
|
||||
import {
|
||||
SessionPersistenceNotFoundError,
|
||||
@@ -94,6 +98,15 @@ export interface TestSessionRemoteDefaults {
|
||||
|
||||
const installed = new WeakMap<Context, SessionController>()
|
||||
|
||||
const TEST_IMAGE_LIMITS: ImageAttachmentLimits = Object.freeze({
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
maxImageDimension: 2000,
|
||||
mediaTypes: Object.freeze(['image/png'] as const),
|
||||
})
|
||||
|
||||
/** Compact header-and-events point read a persistence double declares per session. */
|
||||
interface TestSessionInspection {
|
||||
readonly meta: SessionHeader
|
||||
@@ -239,6 +252,7 @@ function installControllers(
|
||||
}
|
||||
if (ctx.get('attachments') === undefined) {
|
||||
ctx.provide('attachments', {
|
||||
imageLimits: TEST_IMAGE_LIMITS,
|
||||
admitPromptContent: async (
|
||||
content: readonly AttachmentAdmissionPart[],
|
||||
): Promise<AdmittedPromptContentPart[]> => {
|
||||
|
||||
Reference in new issue
Block a user