Path: blob/main/tests/unit/tools/chrome-for-testing.test.ts
12925 views
/*1* chrome-for-testing.test.ts2*3* Copyright (C) 2026 Posit Software, PBC4*/56import { unitTest } from "../../test.ts";7import { assert, assertEquals } from "testing/asserts";8import { arch, os } from "../../../src/deno_ral/platform.ts";9import { join } from "../../../src/deno_ral/path.ts";10import { safeRemoveSync } from "../../../src/deno_ral/fs.ts";11import { isWindows } from "../../../src/deno_ral/platform.ts";12import { runningInCI } from "../../../src/core/ci-info.ts";13import { InstallContext } from "../../../src/tools/types.ts";14import {15detectCftPlatform,16downloadAndExtractCft,17fetchLatestCftRelease,18findCftExecutable,19} from "../../../src/tools/impl/chrome-for-testing.ts";2021// Step 1: detectCftPlatform()22unitTest("detectCftPlatform - returns valid CftPlatform for current system", async () => {23const result = detectCftPlatform();24const validPlatforms = ["linux64", "mac-arm64", "mac-x64", "win32", "win64"];25assert(26validPlatforms.includes(result.platform),27`Expected one of ${validPlatforms.join(", ")}, got: ${result.platform}`,28);29assert(result.os.length > 0, "os should be non-empty");30assert(result.arch.length > 0, "arch should be non-empty");31});3233unitTest("detectCftPlatform - returns win64 on Windows x86_64", async () => {34if (os !== "windows" || arch !== "x86_64") {35return; // Skip on non-Windows36}37const result = detectCftPlatform();38assertEquals(result.platform, "win64");39assertEquals(result.os, "windows");40assertEquals(result.arch, "x86_64");41});4243// Step 2: fetchLatestCftRelease()44// These tests make real HTTP calls to the CfT API — skip on CI.45unitTest("fetchLatestCftRelease - returns valid version string", async () => {46const release = await fetchLatestCftRelease();47assert(release.version, "version should be non-empty");48assert(49/^\d+\.\d+\.\d+\.\d+$/.test(release.version),50`version should match X.Y.Z.W format, got: ${release.version}`,51);52}, { ignore: runningInCI() });5354unitTest("fetchLatestCftRelease - has chrome-headless-shell downloads", async () => {55const release = await fetchLatestCftRelease();56const downloads = release.downloads["chrome-headless-shell"];57assert(downloads, "chrome-headless-shell downloads should exist");58assert(downloads!.length > 0, "should have at least one download");59}, { ignore: runningInCI() });6061unitTest("fetchLatestCftRelease - download URLs are valid", async () => {62const release = await fetchLatestCftRelease();63const downloads = release.downloads["chrome-headless-shell"]!;64for (const dl of downloads) {65assert(66dl.url.startsWith("https://storage.googleapis.com/"),67`URL should start with googleapis.com, got: ${dl.url}`,68);69assert(70dl.url.includes(release.version),71`URL should contain version ${release.version}, got: ${dl.url}`,72);73}74}, { ignore: runningInCI() });7576// Step 3: findCftExecutable()77unitTest("findCftExecutable - finds binary in CfT directory structure", async () => {78const tempDir = Deno.makeTempDirSync();79try {80const { platform } = detectCftPlatform();81const subdir = join(tempDir, `chrome-headless-shell-${platform}`);82Deno.mkdirSync(subdir);83const binaryName = isWindows84? "chrome-headless-shell.exe"85: "chrome-headless-shell";86const binaryPath = join(subdir, binaryName);87Deno.writeTextFileSync(binaryPath, "fake binary");8889const found = findCftExecutable(tempDir, "chrome-headless-shell");90assert(found !== undefined, "should find the binary");91assert(92found!.endsWith(binaryName),93`found path should end with ${binaryName}, got: ${found}`,94);95} finally {96safeRemoveSync(tempDir, { recursive: true });97}98});99100unitTest("findCftExecutable - returns undefined for empty directory", async () => {101const tempDir = Deno.makeTempDirSync();102try {103const found = findCftExecutable(tempDir, "chrome-headless-shell");104assertEquals(found, undefined);105} finally {106safeRemoveSync(tempDir, { recursive: true });107}108});109110unitTest("findCftExecutable - finds binary in nested structure", async () => {111const tempDir = Deno.makeTempDirSync();112try {113const { platform } = detectCftPlatform();114const nested = join(tempDir, `chrome-headless-shell-${platform}`, "subfolder");115Deno.mkdirSync(nested, { recursive: true });116const binaryName = isWindows117? "chrome-headless-shell.exe"118: "chrome-headless-shell";119const binaryPath = join(nested, binaryName);120Deno.writeTextFileSync(binaryPath, "fake binary");121122const found = findCftExecutable(tempDir, "chrome-headless-shell");123assert(found !== undefined, "should find the binary in nested dir");124} finally {125safeRemoveSync(tempDir, { recursive: true });126}127});128129// Step 4: downloadAndExtractCft() — integration test, downloads ~50MB130unitTest(131"downloadAndExtractCft - downloads and extracts chrome-headless-shell",132async () => {133const release = await fetchLatestCftRelease();134const { platform } = detectCftPlatform();135const downloads = release.downloads["chrome-headless-shell"]!;136const dl = downloads.find((d) => d.platform === platform);137assert(dl, `No download found for platform ${platform}`);138139const targetDir = Deno.makeTempDirSync();140try {141const mockContext: InstallContext = {142workingDir: targetDir,143info: (_msg: string) => {},144withSpinner: async (_options, op) => {145await op();146},147error: (_msg: string) => {},148confirm: async (_msg: string) => true,149download: async (_name: string, url: string, target: string) => {150const resp = await fetch(url);151if (!resp.ok) throw new Error(`Download failed: ${resp.status}`);152const data = new Uint8Array(await resp.arrayBuffer());153Deno.writeFileSync(target, data);154},155props: {},156flags: {},157};158159await downloadAndExtractCft("Chrome Headless Shell", dl!.url, targetDir, mockContext, "chrome-headless-shell");160161const found = findCftExecutable(targetDir, "chrome-headless-shell");162assert(163found !== undefined,164"should find chrome-headless-shell after extraction",165);166} finally {167safeRemoveSync(targetDir, { recursive: true });168}169},170{171ignore: runningInCI(),172},173);174175176