Own browser UI sessions and shared navigation

This commit is contained in:
vorotamoroz committed 2026-10-29 14:58:38 +00:00
1 parent cfdc698775
commit 273079e827
28 files changed
+1948 -121

No files matched your search

@@ -38,7 +38,10 @@ type ObsidianTestApp = {
| {
core?: {
services?: {
conflict?: { ensureAllProcessed(): Promise<boolean> };
conflict?: {
ensureAllProcessed(): Promise<boolean>;
conflictProcessQueueCount: { value: number };
};
};
};
}
@@ -607,11 +610,40 @@ async function main(): Promise<void> {
await requestRepeatedConflictChecks(cliBinary, repeatedSession.cliEnv, repeatedPath, 3);
await page.waitForFunction((element) => !element.isConnected, original, { timeout: uiTimeoutMs });
await modal.waitFor({ state: "visible", timeout: uiTimeoutMs });
await page.waitForTimeout(250);
// All enqueue calls have settled. Only the final resolver may remain
// while its dialogue waits for a response; earlier checks also count.
await page.waitForFunction(
(targetPath) => {
const conflict = (globalThis as ObsidianTestGlobal).app?.plugins?.plugins?.["obsidian-livesync"]
?.core?.services?.conflict;
const visible = Array.from(document.querySelectorAll(".modal-container")).filter(
(element) =>
element.getClientRects().length > 0 &&
element.querySelector(".modal-title")?.textContent?.includes("Conflicting changes") &&
element.textContent?.includes(targetPath)
);
return conflict?.conflictProcessQueueCount.value === 1 && visible.length === 1;
},
repeatedPath,
{ timeout: uiTimeoutMs }
);
const visibleCount = await conflictDialogue(page, repeatedPath).evaluateAll(
(elements) => elements.filter((element) => element.getClientRects().length > 0).length
);
if (visibleCount !== 1) {
const dialogues = await page.locator(".modal-container").evaluateAll((elements) =>
elements.map((element) => ({
visible: element.getClientRects().length > 0,
text: element.textContent?.slice(0, 1200),
}))
);
const fixture = await readConflictFixture(cliBinary, repeatedSession.cliEnv, repeatedPath);
console.error(JSON.stringify({ sameFileReplacementFailure: { visibleCount, dialogues, fixture } }));
await captureObsidianPage(
repeatedSession.remoteDebuggingPort,
"conflict-dialog-same-file-replacement.failure.png",
async () => {}
);
throw new Error(`Expected one newest same-file dialogue, but found ${visibleCount}`);
}
});
@@ -265,7 +265,51 @@ async function main(): Promise<void> {
);
screenshotPaths.push(await captureStep(page, "06-after-search-next-match"));
const highlightDiff = modal.locator('.history-highlight-diff-label input[type="checkbox"]');
await highlightDiff.check();
const diffBlocks = modal.locator(".history-added, .history-deleted");
await diffBlocks.first().waitFor({ state: "visible", timeout: 10000 });
const diffIndicator = modal.locator(".diff-nav-indicator");
const diffCount = await diffBlocks.count();
const assertDiffSelection = async (index: number, count: number) => {
assertEqual(
(await diffIndicator.innerText()).trim(),
`${index + 1}/${count}`,
"Unexpected diff indicator."
);
const focused = await diffBlocks.evaluateAll((elements) =>
elements.flatMap((element, index) => (element.classList.contains("diff-focused") ? [index] : []))
);
assertEqual(
JSON.stringify(focused),
JSON.stringify([index]),
"Diff focus did not move to exactly one block."
);
};
await assertDiffSelection(0, diffCount);
const diffPrev = modal.locator(".diff-nav-btn").first();
const diffNext = modal.locator(".diff-nav-btn").last();
await diffPrev.click();
await assertDiffSelection(diffCount - 1, diffCount);
await diffNext.click();
await assertDiffSelection(0, diffCount);
for (let index = 0; index < diffCount; index++) await diffNext.click();
await assertDiffSelection(0, diffCount);
const oldBlock = await diffBlocks.first().elementHandle();
if (oldBlock === null) throw new Error("Could not retain the previous revision's diff block");
const changeRevision = (await nextBtn.isDisabled()) ? prevBtn : nextBtn;
await changeRevision.click();
await page.waitForFunction((element) => !element.isConnected, oldBlock, { timeout: 10000 });
await diffBlocks.first().waitFor({ state: "visible", timeout: 10000 });
const replacementDiffCount = await diffBlocks.count();
await assertDiffSelection(0, replacementDiffCount);
await diffPrev.click();
await assertDiffSelection(replacementDiffCount - 1, replacementDiffCount);
screenshotPaths.push(await captureStep(page, "07-diff-navigation-after-revision-change"));
return [
`diffNavigation: ${diffCount} blocks; replacement revision: ${replacementDiffCount} blocks`,
`initialIndicator: ${initialIndicator}`,
`afterPrevIndicator: ${afterPrevIndicator}`,
`afterNextIndicator: ${afterNextIndicator}`,