Files
fusion/packages/dashboard/app/__tests__/mobile-scripts.test.ts
gsxdsm da36094d74 FN-7586: add iOS edge-swipe-back gesture parity via AppDelegate patch
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>
2026-07-05 12:24:12 -07:00

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");
});
});
});