fix: close mdtodo source modal in web probe

This commit is contained in:
Codex
2026-06-26 12:55:24 +00:00
parent e0df385f12
commit a93236010c
7 changed files with 67 additions and 8 deletions
@@ -364,6 +364,7 @@ async function processCommand(command) {
case "assertSessionInvariant": return withObserverSync(await assertSessionInvariant(command), "assertSessionInvariant");
case "gotoProjectMdtodo": return withObserverSync(await gotoProjectMdtodo(), "gotoProjectMdtodo");
case "openMdtodoSourceConfig": return openMdtodoSourceConfig(command);
case "closeMdtodoSourceConfig": return closeMdtodoSourceConfig(command);
case "configureMdtodoHwpodSource": return configureMdtodoHwpodSource(command);
case "probeMdtodoSource": return probeMdtodoSource(command);
case "reindexMdtodoSource": return reindexMdtodoSource(command);
@@ -2141,10 +2142,14 @@ async function selectMdtodoTask(command) {
const clicked = await target.locator.evaluate((element) => ({
taskRef: element.getAttribute("data-task-ref") || null,
taskId: element.getAttribute("data-task-id") || element.getAttribute("data-rxx-id") || null,
status: element.getAttribute("data-task-status") || null
status: element.getAttribute("data-task-status") || null,
selected: element.getAttribute("data-selected") === "true" || element.getAttribute("aria-selected") === "true"
})).catch(() => ({ taskRef: target.taskRef || null, taskId: target.taskId || null, status: null }));
await target.locator.click();
await page.waitForTimeout(700);
if (!clicked.selected) {
await target.locator.scrollIntoViewIfNeeded().catch(() => null);
await target.locator.click();
await page.waitForTimeout(700);
}
const afterProject = await projectManagementCommandSnapshot();
return {
beforeUrl,
@@ -2154,6 +2159,7 @@ async function selectMdtodoTask(command) {
selectedTask: opaqueIdSummary(clicked.taskRef || target.taskRef),
selectedTaskId: clicked.taskId || target.taskId || null,
selectedTaskStatus: clicked.status || null,
alreadySelected: clicked.selected === true,
beforeProject,
afterProject,
pageId,
@@ -2224,6 +2230,49 @@ async function ensureMdtodoSourceConfigOpen() {
return { opened: true };
}
async function closeMdtodoSourceConfig(command) {
ensureProjectManagementCommand("closeMdtodoSourceConfig");
const beforeUrl = currentPageUrl();
const beforeProject = await projectManagementCommandSnapshot();
const close = await closeMdtodoSourceConfigIfOpen({ required: true });
return {
beforeUrl,
afterUrl: currentPageUrl(),
type: "closeMdtodoSourceConfig",
close,
beforeProject,
afterProject: await projectManagementCommandSnapshot(),
pageId,
valuesRedacted: true
};
}
async function closeMdtodoSourceConfigIfOpen(options = {}) {
const dialog = page.locator('[data-testid="mdtodo-source-config-dialog"], [role="dialog"]').filter({
has: page.locator('[data-testid="mdtodo-source-form-hwpod"], [data-testid="mdtodo-source-form-node"], [data-testid="mdtodo-source-form-root"], [data-testid="mdtodo-source-reindex-dialog"]')
}).first();
if (!await visibleLocator(dialog)) return { wasOpen: false, stillVisible: false };
const closeButton = dialog.locator('[data-testid="mdtodo-source-config-close"], [aria-label="关闭配置"], [aria-label*="关闭"], [aria-label="Close"], button:has-text("关闭"), button:has-text("Cancel"), button:has-text("取消")').first();
let closeClick = null;
try {
await closeButton.waitFor({ state: "visible", timeout: 5000 });
await closeButton.click({ timeout: 5000 });
closeClick = { attempted: true, ok: true };
} catch (error) {
closeClick = { attempted: true, ok: false, error: errorSummary(error) };
await page.keyboard.press("Escape").catch(() => null);
}
await page.waitForTimeout(400);
const stillVisible = await visibleLocator(dialog);
const result = { wasOpen: true, closeClick, stillVisible, valuesRedacted: true };
if (options.required && stillVisible) {
const error = new Error("closeMdtodoSourceConfig dialog remained visible after close attempt");
error.details = result;
throw error;
}
return result;
}
async function fillMdtodoField(testId, value) {
if (typeof value !== "string" || !value.trim()) return { testId, filled: false };
const locator = page.locator('[data-testid="' + cssEscape(testId) + '"]').first();
@@ -2267,6 +2316,7 @@ async function configureMdtodoHwpodSource(command) {
await fillMdtodoField("mdtodo-source-form-root", commandValue(command, ["root", "path"])),
];
const save = await clickProjectButtonAndMaybeWait("mdtodo-source-save", /^\/v1\/project-management\/mdtodo\/sources/u);
const close = await closeMdtodoSourceConfigIfOpen();
return {
beforeUrl,
afterUrl: currentPageUrl(),
@@ -2274,6 +2324,7 @@ async function configureMdtodoHwpodSource(command) {
dialog,
fields,
save,
close,
beforeProject,
afterProject: await projectManagementCommandSnapshot(),
pageId,
@@ -2287,7 +2338,8 @@ async function probeMdtodoSource(command) {
const beforeProject = await projectManagementCommandSnapshot();
await ensureMdtodoSourceConfigOpen();
const probe = await clickProjectButtonAndMaybeWait("mdtodo-source-probe", /^\/v1\/project-management\/mdtodo\/sources/u);
return { beforeUrl, afterUrl: currentPageUrl(), type: "probeMdtodoSource", probe, beforeProject, afterProject: await projectManagementCommandSnapshot(), pageId, valuesRedacted: true };
const close = await closeMdtodoSourceConfigIfOpen();
return { beforeUrl, afterUrl: currentPageUrl(), type: "probeMdtodoSource", probe, close, beforeProject, afterProject: await projectManagementCommandSnapshot(), pageId, valuesRedacted: true };
}
async function reindexMdtodoSource(command) {
@@ -2298,7 +2350,8 @@ async function reindexMdtodoSource(command) {
const dialogButton = page.locator('[data-testid="mdtodo-source-reindex-dialog"]').first();
const buttonTestId = await visibleLocator(dialogButton) ? "mdtodo-source-reindex-dialog" : "mdtodo-source-reindex";
const reindex = await clickProjectButtonAndMaybeWait(buttonTestId, /^\/v1\/project-management\/mdtodo\/sources/u);
return { beforeUrl, afterUrl: currentPageUrl(), type: "reindexMdtodoSource", buttonTestId, reindex, beforeProject, afterProject: await projectManagementCommandSnapshot(), pageId, valuesRedacted: true };
const close = await closeMdtodoSourceConfigIfOpen();
return { beforeUrl, afterUrl: currentPageUrl(), type: "reindexMdtodoSource", buttonTestId, reindex, close, beforeProject, afterProject: await projectManagementCommandSnapshot(), pageId, valuesRedacted: true };
}
async function selectTaskIfCommandTargetsOne(command) {
@@ -2430,6 +2483,7 @@ async function openMdtodoReportPreview(command) {
return false;
}
}, { timeout: 30000 }).then((response) => ({ observed: true, status: response.status(), path: new URL(response.url()).pathname })).catch((error) => ({ observed: false, waitError: errorSummary(error) }));
await link.scrollIntoViewIfNeeded().catch(() => null);
await link.click();
const response = await responsePromise;
await page.locator('[data-testid="mdtodo-report-preview"], [data-testid="mdtodo-report-error"]').first().waitFor({ state: "visible", timeout: 10000 }).catch(() => null);