UNPKG

test-real-styles

Version:

utilities to test real styling of dom elements

359 lines (346 loc) 11 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/index.ts var src_exports = {}; __export(src_exports, { PLAYWRIGHT_BROWSERS: () => PLAYWRIGHT_BROWSERS, cleanup: () => cleanup, getRealStyles: () => getRealStyles, launch: () => launchPage, normalizeValue: () => normalize, toCss: () => toCss }); module.exports = __toCommonJS(src_exports); // src/launch.ts var import_playwright = __toESM(require("playwright"), 1); // src/resolveStyleInput.ts function resolveStyleInput(stylesP) { return __async(this, null, function* () { const styles = yield stylesP; if (typeof styles !== "string") { return styles; } if (styles.match(/^http/)) { return { url: styles }; } else if (styles.match(/\{/)) { return { content: styles }; } return { path: styles }; }); } // src/launch.ts var import_dom_to_playwright = __toESM(require("dom-to-playwright"), 1); // src/getStyles.ts var import_lodash = __toESM(require("lodash.kebabcase"), 1); // src/normalize.ts var import_rgb_hex = __toESM(require("rgb-hex"), 1); var import_color_namer = __toESM(require("color-namer"), 1); function normalize(value) { return value.replace(/rgb\([0-9, ]+\)/gi, (match) => { return `#${(0, import_rgb_hex.default)(match)}`; }).replace( /(#([0-9a-f]{6}|[0-9a-f]{3}))([^0-9a-f]|$)/gi, (_, hex, __, delm) => { const namedColor = (0, import_color_namer.default)(hex).html[0]; return `${(namedColor.distance === 0 ? namedColor.name : hex).toLowerCase()}${delm}`; } ); } // src/extractStyles.ts function extractStyles(element, { styles, pseudoElt }) { const computed = window.getComputedStyle(element, pseudoElt); return styles.reduce((memo, { key, name }) => { memo[name] = computed.getPropertyValue(key); return memo; }, {}); } // src/getStyles.ts function getStyles(_0, _1, _2) { return __async(this, arguments, function* (page, selector, props, { normalize: normalize2 = normalize, pseudoElt } = {}) { const styles = props.map((prop) => { if (typeof prop !== "string") { throw new Error(`Unexpected prop ${prop} of type ${typeof prop}`); } return { name: prop, key: (0, import_lodash.default)(prop).toLowerCase() }; }); const computedStyles = yield page.$eval(selector, extractStyles, { styles, pseudoElt }); return Object.keys(computedStyles).reduce((memo, key) => { memo[key] = normalize2(computedStyles[key], key); return memo; }, {}); }); } // src/withTimeout.ts function withTimeout(promisedValue, message = "Timed out after %n", timeout = 1e4) { return Promise.race([ promisedValue, new Promise( (_, rej) => setTimeout( () => rej( new Error( message.replace( "%n", timeout >= 1e3 ? `${Math.round(timeout / 1e3)}s` : `${timeout}ms` ) ) ), timeout ) ) ]); } // src/launch.ts var import_ichschwoer = require("ichschwoer"); var domToPlaywright = ( /* @ts-ignore */ import_dom_to_playwright.default.__esModule ? ( /* @ts-ignore */ import_dom_to_playwright.default.default ) : import_dom_to_playwright.default ); if (!global.setImmediate) { global.setImmediate = setTimeout; } var PLAYWRIGHT_BROWSERS = [ "chromium", "firefox", "webkit" ]; var cache = {}; var DISABLE_TRANSITIONS = ` * { -moz-transition: none !important; -webkit-transition: none !important; transition: none !important; }`; function launchPage(browserName, stylesInput) { if (!cache[browserName]) { cache[browserName] = withTimeout( import_playwright.default[browserName].launch(), `Failed to launch ${browserName} in under %n` ); } const browserP = cache[browserName]; const contextP = withTimeout( browserP.then((b) => b.newContext()), `Failed to create context in ${browserName} in under %n` ); const pageP = withTimeout( contextP.then((c) => c.newPage()), `Failed to create page in ${browserName} in under %n` ); const dtpP = pageP.then(domToPlaywright); const globalStylesP = withTimeout( resolveStyleInput(stylesInput), `Failed to global resolve style input for ${browserName} in under %n` ); const q = (0, import_ichschwoer.createQueue)(1); return { name: browserName, getPlaywright() { return __async(this, null, function* () { return { browser: yield browserP, context: yield contextP, page: yield pageP }; }); }, updatePage(element, { transitions = false, styles: pageStylesP } = {}) { return q.push(() => __async(this, null, function* () { const { update } = yield dtpP; const page = yield pageP; const styles = yield globalStylesP; yield withTimeout( update(element), `Failed to update page within ${browserName} in under %n` ); yield withTimeout( page.addStyleTag(styles), `Failed to add global styles to page within ${browserName} in under %n` ); if (pageStylesP) { const pageStyles = yield withTimeout( resolveStyleInput(pageStylesP), `Failed to resolve page style input for ${browserName} in under %n` ); yield withTimeout( page.addStyleTag(pageStyles), `Failed to add page styles to page within ${browserName} in under %n` ); } if (!transitions) { yield withTimeout( page.addStyleTag({ content: DISABLE_TRANSITIONS }), `Failed to disable transitions within ${browserName} in under %n` ); } })); }, getStyles(element, styles, options) { return q.push(() => __async(this, null, function* () { const { select } = yield dtpP; const page = yield pageP; return withTimeout( getStyles(page, select(element), styles, options), `Failed to get styles within ${browserName} in under %n` ); })); }, hover(element) { return q.push(() => __async(this, null, function* () { const { select } = yield dtpP; const page = yield pageP; yield withTimeout( page.hover(select(element)), `Failed to hover element within ${browserName} in under %n` ); })); }, focus(element) { return q.push(() => __async(this, null, function* () { const { select } = yield dtpP; const page = yield pageP; yield withTimeout( page.focus(select(element)), `Failed to focus element within ${browserName} in under %n` ); })); } }; } function cleanup() { return __async(this, null, function* () { const toBeCleared = __spreadValues({}, cache); for (const key in cache) { delete cache[key]; } for (const key in toBeCleared) { const browser = yield toBeCleared[key]; for (const context of browser.contexts()) { yield context.close(); } yield browser.close(); } }); } if (typeof afterAll === "function") { afterAll(cleanup); } // src/getRealStyles.ts function isDocument(elm) { return Boolean(elm.body); } function getElement(elm) { return isDocument(elm) ? elm.body : elm; } function getRealStyles(_0) { return __async(this, arguments, function* ({ browser = "chromium", css, doc, element = getElement(doc), hover, focus, getStyles: getStyles2, transitions, options, preparePage }) { const sb = launchPage(browser, css); const { page, context } = yield sb.getPlaywright(); yield preparePage == null ? void 0 : preparePage(page); yield sb.updatePage(doc, { transitions }); if (focus) { yield sb.focus(focus); } if (hover) { yield sb.hover(hover); } const styles = yield sb.getStyles(element, getStyles2, options); yield page.close(); yield context.close(); return styles; }); } // src/toCss.ts var import_lodash2 = __toESM(require("lodash.kebabcase"), 1); function toCss(style) { return Object.keys(style).map((key) => `${(0, import_lodash2.default)(key).toLowerCase()}: ${style[key]};`).join("\n"); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PLAYWRIGHT_BROWSERS, cleanup, getRealStyles, launch, normalizeValue, toCss }); //# sourceMappingURL=index.cjs.map