Files
software-mansion__argent/packages/tool-server/test/restart-app-android-activity.test.ts
Ignacy Łątka 9769a9bf5b test(restart-app): cover dot-prefixing of bare Android activity class names (#431)
## What

Adds regression coverage for the Android `restart-app` / `launch-app`
activity-component builder.

Both handlers route the `activity` param through the shared
`normalizeActivityComponent(bundleId, activity)` helper in
`launch-app/platforms/android.ts`, which dot-prefixes a **bare class
name** like `MainActivity` into `com.example.app/.MainActivity`. Without
the leading dot, `am start -W -n` treats the class as default-package,
matches no activity, and `restart-app` throws a spurious
`ANDROID_RESTART_FAILED`.

That helper (and `restart-app`'s use of it) shipped in #374; this PR
locks the behavior in with a dedicated test so a future refactor can't
silently regress it.

## Test

Adds `packages/tool-server/test/restart-app-android-activity.test.ts`,
which drives the real `restart-app` and `launch-app` Android handlers
(mocking only `adbShell`), captures the emitted `am start -W -n
'<component>'`, and asserts the component for bare / relative / FQCN /
full-component shapes plus parity between the two tools. Verified it
fails when `normalizeActivityComponent` is reverted to the pre-#374
three-case logic (bare name emitted un-dotted) and passes against
current source.
2026-07-02 17:37:30 +02:00

56 lines
1.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
const shellCalls: string[] = [];
vi.mock("../src/utils/adb", async (importActual) => {
const actual = await importActual<typeof import("../src/utils/adb")>();
return {
...actual,
adbShell: vi.fn(async (_s: string, cmd: string) => {
shellCalls.push(cmd);
return "Status: ok\n";
}),
};
});
import { androidImpl as restartAndroid } from "../src/tools/restart-app/platforms/android";
import { androidImpl as launchAndroid } from "../src/tools/launch-app/platforms/android";
function startComponent(): string | undefined {
const cmd = shellCalls.find((c) => c.includes("am start -W -n"));
return cmd?.match(/am start -W -n '([^']+)'/)?.[1];
}
const B = "com.example.app";
const cases: Array<[string, string]> = [
["MainActivity", `${B}/.MainActivity`],
[".MainActivity", `${B}/.MainActivity`],
["com.fully.Qualified", `${B}/com.fully.Qualified`],
[`${B}/.X`, `${B}/.X`],
];
describe("restart-app android activity component", () => {
beforeEach(() => {
shellCalls.length = 0;
});
for (const [activity, expected] of cases) {
it(`restart-app builds ${expected} for "${activity}"`, async () => {
await restartAndroid.handler(
{} as never,
{ udid: "emulator-5554", bundleId: B, activity },
{} as never
);
expect(startComponent()).toBe(expected);
});
it(`restart-app matches launch-app for "${activity}"`, async () => {
await launchAndroid.handler(
{} as never,
{ udid: "emulator-5554", bundleId: B, activity },
{} as never
);
const launch = startComponent();
shellCalls.length = 0;
await restartAndroid.handler(
{} as never,
{ udid: "emulator-5554", bundleId: B, activity },
{} as never
);
expect(startComponent()).toBe(launch);
});
}
});