mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-25 18:43:20 +00:00
Verify P2P pane in a fresh mobile session
This commit is contained in:
1 parent
4194a0067c
commit
51a749099d
6 files changed
+404
-52
No files matched your search
@@ -1,3 +1,5 @@
|
||||
import { mkdir } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import {
|
||||
assertLocatorHasMinimumTouchTarget,
|
||||
assertLocatorWithinSafeArea,
|
||||
@@ -12,13 +14,20 @@ export const desktopViewport = { width: 1024, height: 768 } as const;
|
||||
export const iPhoneSafeArea = { top: 47, right: 0, bottom: 34, left: 0 } as const;
|
||||
|
||||
type ObsidianTestApp = {
|
||||
isMobile?: boolean;
|
||||
emulateMobile?: (mobile: boolean) => void;
|
||||
plugins?: { plugins: Record<string, unknown> };
|
||||
workspace?: { layoutReady?: boolean };
|
||||
};
|
||||
|
||||
type ObsidianTestGlobal = typeof globalThis & { app?: ObsidianTestApp };
|
||||
|
||||
export async function setObsidianMobileTestMode(port: number, enabled: boolean, timeoutMs: number): Promise<void> {
|
||||
async function applyObsidianMobileTestMode(
|
||||
port: number,
|
||||
enabled: boolean,
|
||||
timeoutMs: number,
|
||||
waitForLiveSync: boolean
|
||||
): Promise<void> {
|
||||
await withObsidianPage(port, async (page) => {
|
||||
await page.setViewportSize(enabled ? mobileViewport : desktopViewport);
|
||||
await page.evaluate((nextEnabled) => {
|
||||
@@ -28,17 +37,49 @@ export async function setObsidianMobileTestMode(port: number, enabled: boolean,
|
||||
}
|
||||
obsidianApp.emulateMobile(nextEnabled);
|
||||
}, enabled);
|
||||
await page.waitForFunction(
|
||||
(nextEnabled) => {
|
||||
// Obsidian reopens its workspace layout when platform emulation
|
||||
// changes. Loading a controlled plug-in before that transition has
|
||||
// completed can leave the plug-in enabled but absent from the active
|
||||
// renderer.
|
||||
try {
|
||||
await page.waitForFunction(
|
||||
({ nextEnabled, waitForLiveSync }) => {
|
||||
const obsidianApp = (globalThis as ObsidianTestGlobal).app;
|
||||
return (
|
||||
document.body.classList.contains("is-mobile") === nextEnabled &&
|
||||
obsidianApp?.workspace?.layoutReady === true &&
|
||||
(!waitForLiveSync || obsidianApp?.plugins?.plugins["obsidian-livesync"] !== undefined)
|
||||
);
|
||||
},
|
||||
{ nextEnabled: enabled, waitForLiveSync },
|
||||
{ timeout: timeoutMs }
|
||||
);
|
||||
} catch (error) {
|
||||
const state = await page.evaluate(() => {
|
||||
const obsidianApp = (globalThis as ObsidianTestGlobal).app;
|
||||
return (
|
||||
document.body.classList.contains("is-mobile") === nextEnabled &&
|
||||
obsidianApp?.plugins?.plugins["obsidian-livesync"] !== undefined
|
||||
);
|
||||
},
|
||||
enabled,
|
||||
{ timeout: timeoutMs }
|
||||
);
|
||||
return {
|
||||
appIsMobile: obsidianApp?.isMobile ?? null,
|
||||
bodyClasses: document.body.className,
|
||||
documentReadyState: document.readyState,
|
||||
liveSyncLoaded: obsidianApp?.plugins?.plugins["obsidian-livesync"] !== undefined,
|
||||
viewport: { width: window.innerWidth, height: window.innerHeight },
|
||||
workspaceLayoutReady: obsidianApp?.workspace?.layoutReady ?? null,
|
||||
};
|
||||
});
|
||||
const outputDirectory = process.env.E2E_OBSIDIAN_DIAGNOSTICS_DIR ?? "/tmp/obsidian-livesync-e2e";
|
||||
await mkdir(outputDirectory, { recursive: true });
|
||||
const screenshotPath = join(
|
||||
outputDirectory,
|
||||
waitForLiveSync
|
||||
? "mobile-mode-transition.failure.png"
|
||||
: "mobile-mode-before-plugin-start.failure.png"
|
||||
);
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
throw new Error(
|
||||
`Obsidian mobile-mode transition did not settle: ${JSON.stringify(state)}; screenshot=${screenshotPath}; cause=${detail}`
|
||||
);
|
||||
}
|
||||
await page.evaluate(
|
||||
(safeArea) => {
|
||||
for (const edge of ["top", "right", "bottom", "left"] as const) {
|
||||
@@ -52,6 +93,19 @@ export async function setObsidianMobileTestMode(port: number, enabled: boolean,
|
||||
});
|
||||
}
|
||||
|
||||
/** Enters mobile emulation before LiveSync's first load in a controlled session. */
|
||||
export async function setObsidianMobileTestModeBeforePluginStart(
|
||||
port: number,
|
||||
enabled: boolean,
|
||||
timeoutMs: number
|
||||
): Promise<void> {
|
||||
await applyObsidianMobileTestMode(port, enabled, timeoutMs, false);
|
||||
}
|
||||
|
||||
export async function setObsidianMobileTestMode(port: number, enabled: boolean, timeoutMs: number): Promise<void> {
|
||||
await applyObsidianMobileTestMode(port, enabled, timeoutMs, true);
|
||||
}
|
||||
|
||||
export async function assertMobileDialogueLayout(page: Page, container: Locator, label: string): Promise<void> {
|
||||
const dialogue = container.locator(".modal").last();
|
||||
const closeButton = dialogue.locator(".modal-close-button");
|
||||
|
||||
Reference in new issue
Block a user