UNPKG

@cappa/core

Version:

Core Playwright screenshot functionality for Cappa

218 lines (214 loc) 6.92 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion let node_fs = require("node:fs"); node_fs = __toESM(node_fs); let node_path = require("node:path"); node_path = __toESM(node_path); let playwright_core = require("playwright-core"); playwright_core = __toESM(playwright_core); //#region src/config.ts /** * Type helper to make it easier to use vite.config.ts accepts a direct UserConfig object, or a function that returns it. The function receives a ConfigEnv object. */ function defineConfig(options) { return options; } //#endregion //#region src/screenshot.ts var ScreenshotTool = class { browserType; headless; viewport; outputDir; fullPage; browser = null; context = null; page = null; constructor(options) { this.browserType = options.browserType || "chromium"; this.headless = options.headless !== false; this.viewport = options.viewport || { width: 1920, height: 1080 }; this.outputDir = options.outputDir || "./screenshots"; this.fullPage = options.fullPage !== false; } async init() { if (!node_fs.default.existsSync(this.outputDir)) node_fs.default.mkdirSync(this.outputDir, { recursive: true }); const browserClass = { chromium: playwright_core.chromium, firefox: playwright_core.firefox, webkit: playwright_core.webkit }[this.browserType]; if (!browserClass) throw new Error(`Unsupported browser type: ${this.browserType}`); this.browser = await browserClass.launch({ headless: this.headless }); const defaultUserAgent = (await this.browser.newContext()).newPage().then((page) => page.evaluate(() => navigator.userAgent)); this.context = await this.browser.newContext({ reducedMotion: "reduce", deviceScaleFactor: 1, userAgent: `${await defaultUserAgent} CappaStorybook` }); this.page = await this.context?.newPage(); this.page?.setViewportSize(this.viewport); } async close() { if (this.browser) await this.browser.close(); } async goTo(page, url) { if (!this.context) throw new Error("Browser not initialized"); await page.goto(url, { waitUntil: "domcontentloaded" }); } getFilePath(filename) { return node_path.default.join(this.outputDir, filename); } async takeScreenshot(page, filename, options = {}) { if (!this.browser) throw new Error("Browser not initialized"); try { if (options.waitForSelector) { console.log(`Waiting for selector: ${options.waitForSelector}`); await page.waitForSelector(options.waitForSelector, { timeout: 1e4 }); } const waitTime = options.waitForTimeout !== void 0 ? options.waitForTimeout : 0; if (waitTime > 0) { console.log(`Waiting for ${waitTime}ms for dynamic content`); await page.waitForTimeout(waitTime); } const filepath = this.getFilePath(filename); const screenshotOptions = { path: filepath, fullPage: options.fullPage !== void 0 ? options.fullPage : this.fullPage, type: "png", timeout: 6e4, mask: options.mask, omitBackground: options.omitBackground, scale: "css" }; await page.screenshot(screenshotOptions); console.log(`Screenshot saved: ${filepath}`); return filepath; } catch (error) { console.error(`Error taking screenshot of ${page.url()}:`, error.message); throw error; } } async takeElementScreenshot(page, selector, options = {}) { if (!this.browser) throw new Error("Browser not initialized"); try { await page.waitForSelector(selector, { timeout: 1e4 }); const element = await page.$(selector); if (!element) throw new Error(`Element not found: ${selector}`); const filename = options.filename || `${selector.replace(/[^a-zA-Z0-9]/g, "_")}.png`; const filepath = this.getFilePath(filename); const elementScreenshotOptions = { path: filepath, type: "png" }; await element.screenshot(elementScreenshotOptions); console.log(`Element screenshot saved: ${filepath}`); return filepath; } catch (error) { console.error(`Error taking element screenshot of ${page.url()}:`, error.message); throw error; } finally { await page.close(); } } async batchScreenshots(urls, options = {}) { const results = []; for (const url of urls) try { const page = this.page; if (!page) throw new Error("Page not initialized"); await this.goTo(page, url); const filepath = await this.takeScreenshot(page, url, options); results.push({ url, success: true, filepath }); } catch (error) { results.push({ url, success: false, error: error.message, filepath: "" }); } return results; } async takeResponsiveScreenshots(url, viewports = [ { width: 1920, height: 1080, name: "desktop" }, { width: 768, height: 1024, name: "tablet" }, { width: 375, height: 667, name: "mobile" } ], options = {}) { if (!this.context) throw new Error("Browser not initialized"); const results = []; for (const viewport of viewports) try { const page = await this.context?.newPage(); await page.setViewportSize(viewport); await page.goto(url, { waitUntil: "domcontentloaded" }); await page.waitForTimeout(2e3); const filename = `${viewport.name}.png`; const filepath = this.getFilePath(filename); const responsiveScreenshotOptions = { path: filepath, fullPage: options.fullPage !== void 0 ? options.fullPage : this.fullPage, type: "png" }; await page.screenshot(responsiveScreenshotOptions); await page.close(); console.log(`Responsive screenshot saved: ${filepath}`); results.push({ viewport: viewport.name, success: true, filepath }); } catch (error) { console.error(`Error taking responsive screenshot for ${viewport.name}:`, error.message); results.push({ viewport: viewport.name, success: false, error: error.message, filepath: "" }); } return results; } }; var screenshot_default = ScreenshotTool; //#endregion exports.ScreenshotTool = screenshot_default; exports.defineConfig = defineConfig; //# sourceMappingURL=index.js.map