Files
skillfactor-pipeline/pipeline/factorial_probe.mjs

75 lines
3.3 KiB
JavaScript

// Extrahiert Design-Tokens (Fonts, Farben, Buttons, Radien) von factorialhr.com
// per echtem Browser + Referenz-Screenshots fuer den Gitea-Factorial-Look.
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
const staging = "C:/Program Files (x86)/TempoBill/Zeiterfassung.Cloud/Sites(staging)";
const require = createRequire(path.join(staging, "package.json"));
const puppeteer = require("puppeteer-core");
const EDGE = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
const here = path.dirname(fileURLToPath(import.meta.url));
const outDir = path.join(here, "..", "docs", "factorial-ref");
import { mkdirSync } from "node:fs";
mkdirSync(outDir, { recursive: true });
const browser = await puppeteer.launch({
executablePath: EDGE, headless: true,
args: ["--no-sandbox"],
defaultViewport: { width: 1920, height: 1080 },
});
const page = await browser.newPage();
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36 Edg/126.0");
await page.goto("https://factorialhr.com/", { waitUntil: "networkidle2", timeout: 90000 });
await new Promise(r => setTimeout(r, 3000));
const tokens = await page.evaluate(() => {
const cs = (el) => el ? getComputedStyle(el) : null;
const pick = (s, keys) => Object.fromEntries(keys.map(k => [k, s?.[k]]));
const body = cs(document.body);
const h1 = cs(document.querySelector("h1"));
const h2 = cs(document.querySelector("h2"));
const links = [...document.querySelectorAll("a,button")];
// Primaer-Buttons: auffaellige Hintergrundfarben sammeln
const btnStyles = [];
for (const el of links.slice(0, 400)) {
const s = getComputedStyle(el);
if (s.backgroundColor && s.backgroundColor !== "rgba(0, 0, 0, 0)") {
btnStyles.push({
text: (el.textContent || "").trim().slice(0, 40),
bg: s.backgroundColor, color: s.color, radius: s.borderRadius,
font: s.fontFamily.split(",")[0], weight: s.fontWeight, size: s.fontSize,
padding: s.padding,
});
}
}
// Farbstatistik ueber viele Elemente
const colorCount = {};
for (const el of document.querySelectorAll("*")) {
const s = getComputedStyle(el);
for (const c of [s.color, s.backgroundColor]) {
if (c && c !== "rgba(0, 0, 0, 0)") colorCount[c] = (colorCount[c] || 0) + 1;
}
}
const topColors = Object.entries(colorCount).sort((a, b) => b[1] - a[1]).slice(0, 20);
// Header/Nav
const nav = cs(document.querySelector("header") || document.querySelector("nav"));
return {
body: pick(body, ["fontFamily", "fontSize", "color", "backgroundColor", "lineHeight"]),
h1: pick(h1, ["fontFamily", "fontSize", "fontWeight", "color", "letterSpacing", "lineHeight"]),
h2: pick(h2, ["fontFamily", "fontSize", "fontWeight", "color"]),
nav: pick(nav, ["backgroundColor", "height", "boxShadow"]),
buttons: btnStyles.slice(0, 15),
topColors,
title: document.title,
};
});
console.log(JSON.stringify(tokens, null, 1));
await page.screenshot({ path: path.join(outDir, "factorial-hero.png") });
await page.evaluate(() => window.scrollTo(0, 1200));
await new Promise(r => setTimeout(r, 1500));
await page.screenshot({ path: path.join(outDir, "factorial-section2.png") });
await browser.close();