diff --git a/src/serviceFeatures/obsidianReplicationRibbon.ts b/src/serviceFeatures/obsidianReplicationRibbon.ts index 09c63a2e..6841dafd 100644 --- a/src/serviceFeatures/obsidianReplicationRibbon.ts +++ b/src/serviceFeatures/obsidianReplicationRibbon.ts @@ -13,7 +13,7 @@ const REPLICATE_ICON_SVG = ` - + `; /** diff --git a/src/serviceFeatures/obsidianReplicationRibbon.unit.spec.ts b/src/serviceFeatures/obsidianReplicationRibbon.unit.spec.ts index 703ec931..17890afb 100644 --- a/src/serviceFeatures/obsidianReplicationRibbon.unit.spec.ts +++ b/src/serviceFeatures/obsidianReplicationRibbon.unit.spec.ts @@ -42,6 +42,7 @@ describe("useObsidianReplicationRibbonFeature", () => { await expect(initialise?.()).resolves.toBe(true); expect(addIcon).toHaveBeenCalledWith("replicate", expect.any(String)); + expect(addIcon).toHaveBeenCalledWith("replicate", expect.stringContaining("c-7.66 1.98-12.2 9.61-10 17")); expect(addRibbonIcon).toHaveBeenCalledWith( "replicate", $msg("moduleObsidianMenu.replicate"), diff --git a/test/e2e-obsidian/scripts/settings-ui.ts b/test/e2e-obsidian/scripts/settings-ui.ts index dcfae599..eb709f1c 100644 --- a/test/e2e-obsidian/scripts/settings-ui.ts +++ b/test/e2e-obsidian/scripts/settings-ui.ts @@ -1,4 +1,5 @@ import { mkdir } from "node:fs/promises"; +import { assertLocatorWithinViewport, assertNoHorizontalOverflow } from "@vrtmrz/obsidian-test-session"; import { VER } from "@vrtmrz/livesync-commonlib/compat/common/types"; import { discoverObsidianCli, requireObsidianBinary } from "../runner/environment.ts"; import { createE2eObsidianDeviceLocalState, waitForLiveSyncCoreReady } from "../runner/liveSyncWorkflow.ts"; @@ -597,26 +598,42 @@ async function verifyCompatibilityReview(): Promise { ); } -async function verifyConfigDoctorFollowsCompatibilityReview(): Promise { +async function verifyConfigDoctorFollowsCompatibilityReview(): Promise { + const screenshot = await captureObsidianDialogue( + obsidianRemoteDebuggingPort(), + "config-doctor-after-compatibility-review.png", + async (page) => { + const doctor = page.locator(".modal-container").filter({ + has: page.locator(".modal-title").filter({ hasText: "Self-hosted LiveSync Config Doctor" }), + }); + await doctor.waitFor({ state: "visible", timeout: uiTimeoutMs }); + await doctor.getByText("Per-file-saved customization sync", { exact: true }).waitFor({ + state: "visible", + timeout: uiTimeoutMs, + }); + await doctor.getByText("Enhance chunk size", { exact: true }).waitFor({ + state: "visible", + timeout: uiTimeoutMs, + }); + if ((await doctor.getByText("Data Compression", { exact: true }).count()) !== 0) { + throw new Error("Config Doctor still treats supported Data Compression as a problem."); + } + await assertLocatorWithinViewport(page, doctor.locator(".modal").last(), { + label: "Config Doctor dialogue", + }); + await assertNoHorizontalOverflow(page, doctor.locator(".modal").last(), { + label: "Config Doctor dialogue", + }); + } + ); await withObsidianPage(obsidianRemoteDebuggingPort(), async (page) => { const doctor = page.locator(".modal-container").filter({ has: page.locator(".modal-title").filter({ hasText: "Self-hosted LiveSync Config Doctor" }), }); - await doctor.waitFor({ state: "visible", timeout: uiTimeoutMs }); - await doctor.getByText("Per-file-saved customization sync", { exact: true }).waitFor({ - state: "visible", - timeout: uiTimeoutMs, - }); - await doctor.getByText("Enhance chunk size", { exact: true }).waitFor({ - state: "visible", - timeout: uiTimeoutMs, - }); - if ((await doctor.getByText("Data Compression", { exact: true }).count()) !== 0) { - throw new Error("Config Doctor still treats supported Data Compression as a problem."); - } await doctor.getByRole("button", { name: /No, and do not ask again/u }).click(); await doctor.waitFor({ state: "hidden", timeout: uiTimeoutMs }); }); + return screenshot; } async function verifyEffectiveSettings(): Promise<"declarative" | "imperative"> { @@ -1051,7 +1068,8 @@ async function main(): Promise { await resumePendingCompatibilityReviewForSettings(); } else { await verifyCompatibilityReview(); - await verifyConfigDoctorFollowsCompatibilityReview(); + const configDoctorScreenshot = await verifyConfigDoctorFollowsCompatibilityReview(); + console.log(`Config Doctor screenshot: ${configDoctorScreenshot}`); } settingsRenderer = await verifyEffectiveSettings(); const initialisation = await verifyPendingSettingsInitialisationFlow(); diff --git a/test/e2e-obsidian/scripts/smoke.ts b/test/e2e-obsidian/scripts/smoke.ts index 0628b122..59b56c9a 100644 --- a/test/e2e-obsidian/scripts/smoke.ts +++ b/test/e2e-obsidian/scripts/smoke.ts @@ -36,6 +36,13 @@ async function assertMenuFeaturesAreComposed(remoteDebuggingPort: number): Promi if (ribbonCount !== 1) { throw new Error(`Expected one extracted replication ribbon action, found ${ribbonCount}.`); } + + const preservedRibbonPathCount = await page + .locator('.livesync-ribbon-replicate path[d*="c-7.66 1.98-12.2 9.61-10 17"]') + .count(); + if (preservedRibbonPathCount !== 1) { + throw new Error("The extracted replication ribbon does not preserve its established icon path."); + } }); }