UNPKG

@coinbase/onchaintestkit

Version:

End-to-end testing toolkit for blockchain applications, powered by Playwright

130 lines (129 loc) 4.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCacheDir = createCacheDir; exports.downloadExtension = downloadExtension; exports.extractExtension = extractExtension; exports.downloadMetaMask = downloadMetaMask; const node_os_1 = __importDefault(require("node:os")); const node_path_1 = __importDefault(require("node:path")); const extract_zip_1 = __importDefault(require("extract-zip")); const fs_extra_1 = __importDefault(require("fs-extra")); const constants_1 = require("./constants"); /** * Downloads a remote file with caching support * Returns true if file was served from cache */ async function getRemoteFile({ url, outputPath, useCache = true, }) { // Use cached version if available and requested if (useCache && (await fs_extra_1.default.pathExists(outputPath))) { return true; // Served from cache } try { // Make sure target directory exists await fs_extra_1.default.ensureDir(node_path_1.default.dirname(outputPath)); // Fetch file content const res = await fetch(url); if (!res.ok) { throw new Error(`Network error: ${res.status} - ${res.statusText}`); } // Save to disk const fileData = await res.arrayBuffer(); await fs_extra_1.default.writeFile(outputPath, Buffer.from(fileData)); return false; // Freshly downloaded } catch (err) { const errMsg = err instanceof Error ? err.message : String(err); throw new Error(`Download operation failed: ${errMsg}`); } } /** * Extracts a zip archive to a folder with the same name * Returns the path to the extracted directory */ async function unpackZipArchive({ zipFile, useCache = true, }) { const targetDir = zipFile.replace(/\.zip$/, ""); // Return existing directory if allowed if (useCache && (await fs_extra_1.default.pathExists(targetDir))) { return targetDir; } try { // Create target directory and extract await fs_extra_1.default.ensureDir(targetDir); await (0, extract_zip_1.default)(zipFile, { dir: targetDir }); return targetDir; } catch (err) { // Clean up partial extraction on error try { await fs_extra_1.default.remove(targetDir); } catch { // Ignore cleanup errors } const errMsg = err instanceof Error ? err.message : String(err); throw new Error(`Extraction operation failed: ${errMsg}`); } } /** * Creates a cache directory for the test kit */ async function createCacheDir(name) { const dirPath = node_path_1.default.join(node_os_1.default.tmpdir(), "onchaintestkit", name); await fs_extra_1.default.mkdir(dirPath, { recursive: true }); return dirPath; } /** * Downloads a browser extension from a URL */ async function downloadExtension(params) { const { extensionUrl, cacheDir, filename, forceDownload = false } = params; const filePath = node_path_1.default.join(cacheDir, filename); const isCached = await getRemoteFile({ url: extensionUrl, outputPath: filePath, useCache: !forceDownload, }); return { filePath, fromCache: isCached }; } /** * Extracts a browser extension from a zip file */ async function extractExtension(params) { const { zipFilePath, forceExtract = false } = params; const extractedPath = await unpackZipArchive({ zipFile: zipFilePath, useCache: !forceExtract, }); const fromCache = !forceExtract && (await fs_extra_1.default.pathExists(extractedPath)); return { extractedPath, fromCache }; } /** * Sets up the MetaMask extension for testing * Downloads and extracts the extension if needed */ async function downloadMetaMask() { try { // Prepare cache location const cachePath = await createCacheDir("metamask-files"); const zipPath = node_path_1.default.join(cachePath, constants_1.EXTENSION_FILENAME); // Get extension zip (from cache if possible) const { fromCache: zipFromCache } = await downloadExtension({ extensionUrl: constants_1.EXTENSION_URL, cacheDir: cachePath, filename: constants_1.EXTENSION_FILENAME, }); // Extract the zip (from cache if possible) const { extractedPath } = await extractExtension({ zipFilePath: zipPath, forceExtract: !zipFromCache, // Only re-extract if we downloaded a new zip }); return extractedPath; } catch (err) { const errMsg = err instanceof Error ? err.message : String(err); throw new Error(`MetaMask extension preparation failed: ${errMsg}`); } }