@coinbase/onchaintestkit
Version:
End-to-end testing toolkit for blockchain applications, powered by Playwright
130 lines (129 loc) • 4.86 kB
JavaScript
;
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}`);
}
}