Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions scripts/mobile-showcase.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
// @effect-diagnostics nodeBuiltinImport:off - expectations mirror the host path joins the script under test performs.
// @effect-diagnostics nodeBuiltinImport:off - Clears capture outputs in a real temporary folder.
import * as NodeFSP from "node:fs/promises";
import * as NodeOS from "node:os";
import * as NodePath from "node:path";

import { assert, it } from "@effect/vitest";
import { PNG } from "pngjs";

import type { ShowcaseStoreAssetSpec } from "./mobile-showcase.config.ts";
import showcaseConfig, {
type ShowcaseScene,
type ShowcaseStoreAssetSpec,
} from "./mobile-showcase.config.ts";
import {
clearShowcaseCaptureOutputs,
encodeAndroidPairingUrls,
normalizeStorePng,
parsePairingCredentialOutput,
planShowcaseCaptures,
readPngMetadata,
showcaseCaptureDirectory,
validateStoreAsset,
} from "./mobile-showcase.ts";

Expand Down Expand Up @@ -91,3 +101,40 @@ it("encodes Android pairing URLs without shell-sensitive JSON quotes", () => {
assert.deepStrictEqual(JSON.parse(decodeURIComponent(encoded.slice("json-uri:".length))), urls);
assert.equal(encoded.includes('"'), false);
});

it("keeps unselected scenes on a partial capture and clears the folder on a full one", async () => {
const pixel = showcaseConfig.devices.find((device) => device.id === "pixel");
assert.ok(pixel);
const seeded = [...pixel.scenes.map((scene) => `${scene}.png`), "stale.png"];
const cases = [
{
scenes: new Set<ShowcaseScene>(["thread"]),
remaining: seeded.filter((file) => file !== "thread.png"),
},
{ scenes: new Set<ShowcaseScene>(), remaining: [] },
];
const outputDirectory = await NodeFSP.mkdtemp(
NodePath.join(NodeOS.tmpdir(), "t3-showcase-test-"),
);
try {
for (const { scenes, remaining } of cases) {
const [capture] = planShowcaseCaptures(showcaseConfig, {
platforms: new Set(),
deviceIds: new Set(["pixel"]),
scenes,
appearances: new Set(),
themes: new Set(),
});
assert.ok(capture);
const directory = showcaseCaptureDirectory(outputDirectory, capture);
await NodeFSP.mkdir(directory, { recursive: true });
for (const file of seeded) {
await NodeFSP.writeFile(NodePath.join(directory, file), "png");
}
await clearShowcaseCaptureOutputs(outputDirectory, capture);
assert.deepStrictEqual((await NodeFSP.readdir(directory)).sort(), remaining.sort());
}
} finally {
await NodeFSP.rm(outputDirectory, { recursive: true, force: true });
}
});
37 changes: 24 additions & 13 deletions scripts/mobile-showcase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,27 @@ export function showcaseCaptureDirectory(
);
}

function isFullCapture(capture: ShowcaseCapture): boolean {
return capture.scenes.length === capture.device.scenes.length;
}

export async function clearShowcaseCaptureOutputs(
outputDirectory: string,
capture: ShowcaseCapture,
): Promise<void> {
const directory = showcaseCaptureDirectory(outputDirectory, capture);
if (isFullCapture(capture)) {
await NodeFSP.rm(directory, { recursive: true, force: true });
} else {
await Promise.all(
capture.scenes.map((scene) =>
NodeFSP.rm(NodePath.join(directory, `${scene}.png`), { force: true }),
),
);
}
await NodeFSP.mkdir(directory, { recursive: true });
}

async function finalizeCapture(destination: string, device: ShowcaseDevice): Promise<void> {
const normalized = normalizeStorePng(await NodeFSP.readFile(destination));
await NodeFSP.writeFile(destination, normalized);
Expand Down Expand Up @@ -1537,11 +1558,7 @@ async function main(): Promise<void> {
const outputDirectory = NodePath.resolve(REPO_ROOT, showcaseConfig.outputDirectory);
if (options.validateOnly) {
for (const capture of captures) {
await validateCaptureSet(
capture,
outputDirectory,
capture.scenes.length === capture.device.scenes.length,
);
await validateCaptureSet(capture, outputDirectory, isFullCapture(capture));
}
return;
}
Expand All @@ -1550,9 +1567,7 @@ async function main(): Promise<void> {
const metroHost = hasIos ? lanIpv4Address() : "127.0.0.1";
await NodeFSP.mkdir(outputDirectory, { recursive: true });
for (const capture of captures) {
const directory = showcaseCaptureDirectory(outputDirectory, capture);
await NodeFSP.rm(directory, { recursive: true, force: true });
await NodeFSP.mkdir(directory, { recursive: true });
await clearShowcaseCaptureOutputs(outputDirectory, capture);
}

const showcaseRootDir = await NodeFSP.mkdtemp(
Expand Down Expand Up @@ -1622,11 +1637,7 @@ async function main(): Promise<void> {
(cleanup) => androidCleanups.push(cleanup),
);
}
await validateCaptureSet(
capture,
outputDirectory,
capture.scenes.length === capture.device.scenes.length,
);
await validateCaptureSet(capture, outputDirectory, isFullCapture(capture));
}

NodeProcess.stdout.write(
Expand Down
Loading