Enables the WKWebView interactive-pop (edge-swipe-back) gesture on iOS, matching the Android predictive-back parity already in place, by patching the generated AppDelegate.swift during cap sync. - Add packages/mobile/scripts/patch-ios-webview.ts: patches AppDelegate.swift to cast the root view controller to CAPBridgeViewController and set webView?.allowsBackForwardNavigationGestures = true before the didFinishLaunchingWithOptions return, is idempotent, and no-ops safely when no ios/ project exists yet - Wire capacitor:sync:after to run both patch-android-manifest.ts and patch-ios-webview.ts so cap sync keeps both native back-gesture opt-ins in sync; add patch:ios-webview script - Add unit tests covering patch, idempotency, already-patched, missing-project, and source-preservation cases for the new iOS webview patch, alongside the existing Android manifest patch tests - Add TaskDetail.swipe-back.test.tsx coverage proving the shared popstate-driven nav-history dismissal stack (no iOS-specific native-back emitter needed) already satisfies the gesture's dismissal contract - Add mobile-scripts.test.ts dashboard coverage and update MOBILE.md / packages/mobile/README.md documenting the new iOS gesture opt-in Files changed: MOBILE.md | 12 ++ .../dashboard/app/__tests__/mobile-scripts.test.ts | 31 +++++ .../__tests__/TaskDetail.swipe-back.test.tsx | 131 +++++++++++++++++++++ packages/mobile/README.md | 36 ++++++ packages/mobile/package.json | 3 +- packages/mobile/scripts/patch-ios-webview.ts | 119 +++++++++++++++++++ packages/mobile/src/__tests__/native-shell.test.ts | 122 +++++++++++++++++++ 7 files changed, 453 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7586 Fusion-Task-Lineage: 248092a1-de1b-49b6-94ef-70675a7b93a1 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
78 lines
3.2 KiB
TypeScript
78 lines
3.2 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
interface WorkspacePackageJson {
|
|
scripts?: Record<string, string | undefined>;
|
|
}
|
|
|
|
describe("mobile pipeline scripts", () => {
|
|
const rootPackagePath = resolve(__dirname, "../../../../package.json");
|
|
|
|
it("defines required root mobile scripts", () => {
|
|
const packageJson = JSON.parse(readFileSync(rootPackagePath, "utf8")) as WorkspacePackageJson;
|
|
const scripts = packageJson.scripts ?? {};
|
|
|
|
const requiredScriptNames = [
|
|
"mobile:build",
|
|
"mobile:ios",
|
|
"mobile:android",
|
|
"mobile:dev:ios",
|
|
"mobile:dev:android",
|
|
"mobile:sync",
|
|
];
|
|
|
|
for (const scriptName of requiredScriptNames) {
|
|
expect(typeof scripts[scriptName]).toBe("string");
|
|
expect((scripts[scriptName] ?? "").trim().length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it("configures mobile:build to run dashboard build and cap sync", () => {
|
|
const packageJson = JSON.parse(readFileSync(rootPackagePath, "utf8")) as WorkspacePackageJson;
|
|
const mobileBuild = packageJson.scripts?.["mobile:build"] ?? "";
|
|
|
|
expect(mobileBuild).toContain("dashboard");
|
|
expect(mobileBuild).toContain("build");
|
|
expect(mobileBuild).toContain("cap sync");
|
|
});
|
|
|
|
it("includes platform-specific open commands", () => {
|
|
const packageJson = JSON.parse(readFileSync(rootPackagePath, "utf8")) as WorkspacePackageJson;
|
|
|
|
expect(packageJson.scripts?.["mobile:ios"] ?? "").toContain("ios");
|
|
expect(packageJson.scripts?.["mobile:android"] ?? "").toContain("android");
|
|
});
|
|
|
|
/*
|
|
FNXC:TaskDetailIOSSwipeBack 2026-07-05-12:10:
|
|
FN-7586: `WKWebView.allowsBackForwardNavigationGestures` defaults to false and no
|
|
capacitor.config toggle exists for it (confirmed against the installed @capacitor/cli
|
|
declarations), so the fix is a tracked post-`cap sync` patch script
|
|
(`packages/mobile/scripts/patch-ios-webview.ts`) wired into Capacitor's own
|
|
`capacitor:sync:after` npm hook — mirroring FN-7583's Android manifest-patch precedent —
|
|
so `cap sync` regeneration of the git-ignored `ios/` project can never silently drop the
|
|
gesture opt-in. This asserts the patch/wiring is present in tracked source; it fails on the
|
|
pre-fix tree (no patch script, no hook) and passes after.
|
|
*/
|
|
describe("iOS edge-swipe-back gesture patch wiring (FN-7586)", () => {
|
|
const mobilePackagePath = resolve(__dirname, "../../../mobile/package.json");
|
|
const patchScriptPath = resolve(__dirname, "../../../mobile/scripts/patch-ios-webview.ts");
|
|
|
|
it("ships a tracked post-cap-sync iOS WKWebView patch script", () => {
|
|
const source = readFileSync(patchScriptPath, "utf8");
|
|
|
|
expect(source).toContain("allowsBackForwardNavigationGestures");
|
|
expect(source).toContain("CAPBridgeViewController");
|
|
});
|
|
|
|
it("wires the iOS webview patch into a Capacitor sync hook so cap sync cannot drop it", () => {
|
|
const mobilePackageJson = JSON.parse(readFileSync(mobilePackagePath, "utf8")) as WorkspacePackageJson;
|
|
const scripts = mobilePackageJson.scripts ?? {};
|
|
|
|
const syncAfterHook = scripts["capacitor:sync:after"] ?? "";
|
|
expect(syncAfterHook).toContain("patch-ios-webview");
|
|
});
|
|
});
|
|
});
|