batch E: close tail checks and refresh smoke evidence

This commit is contained in:
lix-2026
2026-05-21 17:15:28 +08:00
parent 1e8f5c5816
commit cc91a56603
16 changed files with 1093 additions and 45 deletions
@@ -98,6 +98,27 @@ async function typeDirtyText(page, text) {
await waitForEditorText(page, text.trim());
}
async function getConflictEnvelope(page, documentId) {
return await page.evaluate((docId) => {
const snapshot = window.__mnoteDebugDocumentSessions?.snapshot?.();
if (!snapshot) return null;
const session = snapshot.sessions.find((s) => s.documentId === docId);
return session?.lastExternalConflictEnvelope || null;
}, documentId);
}
async function verifyConflictEnvelope(page, documentId, label) {
const envelope = await getConflictEnvelope(page, documentId);
assert(envelope, `${label}: 冲突信封应存在`);
assert(typeof envelope.editorBaseVersion === 'string', `${label}: editorBaseVersion 应为字符串`);
assert(typeof envelope.currentDiskVersion === 'string', `${label}: currentDiskVersion 应为字符串`);
// BufferStore 字段应存在(可为 null 但必须声明)
assert('externalActor' in envelope, `${label}: 冲突信封应包含 externalActor 字段(BufferStore 桥接)`);
assert('dirtyState' in envelope, `${label}: 冲突信封应包含 dirtyState 字段(BufferStore 桥接)`);
assert('bufferFileVersion' in envelope, `${label}: 冲突信封应包含 bufferFileVersion 字段(BufferStore 桥接)`);
debug[`envelope_${label}`] = envelope;
}
async function waitForFileText(filePath, expected) {
const deadline = Date.now() + UI_TIMEOUT_MS;
while (Date.now() < deadline) {
@@ -161,6 +182,7 @@ async function run() {
fs.writeFileSync(path.join(root, acceptFile), markdown("Accept Disk", ["initial accept", diskAcceptToken]), "utf8");
await waitForEditorStatus(page, "external-change-conflict");
await page.locator('[data-testid="mnote-editor-conflict-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await verifyConflictEnvelope(page, localMdDocumentId(acceptFile), "accept-disk");
await page.locator('[data-testid="mnote-conflict-open-diff"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator('[data-testid="mnote-conflict-diff-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await page.waitForFunction(
@@ -187,6 +209,7 @@ async function run() {
fs.writeFileSync(path.join(root, keepFile), markdown("Keep Current", ["initial keep", diskKeepToken]), "utf8");
await waitForEditorStatus(page, "external-change-conflict");
await page.locator('[data-testid="mnote-editor-conflict-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await verifyConflictEnvelope(page, localMdDocumentId(keepFile), "keep-current");
await page.locator('[data-testid="mnote-conflict-keep-current"]').click({ timeout: UI_TIMEOUT_MS });
await waitForFileText(path.join(root, keepFile), localKeepToken);
const keepContent = fs.readFileSync(path.join(root, keepFile), "utf8");
@@ -202,6 +225,7 @@ async function run() {
fs.writeFileSync(path.join(root, mergeFile), markdown("Merge Result", ["initial merge", diskMergeToken]), "utf8");
await waitForEditorStatus(page, "external-change-conflict");
await page.locator('[data-testid="mnote-editor-conflict-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await verifyConflictEnvelope(page, localMdDocumentId(mergeFile), "merge");
await page.locator('[data-testid="mnote-conflict-open-diff"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator('[data-testid="mnote-conflict-diff-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await page.locator('[data-testid="mnote-conflict-merge-text"]').fill(`initial merge\n${localMergeToken}\n${diskMergeToken}\n${mergedToken}`);
@@ -234,6 +258,7 @@ async function run() {
}, { documentId: localMdDocumentId(agentFile), runId: agentRunId });
await waitForEditorStatus(page, "external-change-conflict");
await page.locator('[data-testid="mnote-editor-conflict-panel"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
await verifyConflictEnvelope(page, localMdDocumentId(agentFile), "agent");
await page.waitForFunction(
(expected) => {
const panel = document.querySelector('[data-testid="mnote-editor-conflict-panel"]');