feat: strengthen design skill and refresh all showcases
Some checks failed
ci / build (push) Has been cancelled

This commit is contained in:
Yun Chan 2026-09-12 18:16:33 +09:00
parent 69e5cc1efd
commit e09d4efb1c
257 changed files with 8196 additions and 2374 deletions

View file

@ -4,11 +4,19 @@ import puppeteer from "puppeteer-core";
import path from "node:path";
import url from "node:url";
import {
collectPageFailures,
prepareStillPage,
resolveChrome,
routeForFile,
startPublicServer,
waitForStableVisual,
} from "./capture-stable.mjs";
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, "..");
const CHROME = "C:/Program Files/Google/Chrome/Application/chrome.exe";
const shots = path.join(root, "src", "assets", "shots");
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const publicRoot = path.join(root, "public");
function requestedSlugs(argv) {
const slugs = new Set();
@ -34,42 +42,65 @@ const unknown = [...requested].filter((slug) => !known.has(slug));
if (unknown.length) throw new Error(`Unknown app slug(s): ${unknown.join(", ")}`);
const selected = requested.size ? requested : known;
const browser = await puppeteer.launch({
executablePath: CHROME,
headless: "new",
args: ["--no-sandbox", "--disable-gpu", "--force-device-scale-factor=1"],
defaultViewport: { width: 1440, height: 900 },
});
const page = await browser.newPage();
await page.setCacheEnabled(false);
const open = async (app) => {
await page.goto(url.pathToFileURL(path.join(root, "public/work", app, "index.html")).href, { waitUntil: "networkidle0" });
await page.evaluate(() => document.fonts.ready);
await sleep(250);
};
const server = await startPublicServer(publicRoot);
let browser;
if (selected.has("gaon-lms")) {
// 가온: 대시보드 본컷 + 학적 카드(수강생 모달) -2컷
await open("gaon-lms");
await page.screenshot({ path: path.join(shots, "work-gaon-lms.png") });
await page.screenshot({ path: path.join(root, "public/work/gaon-lms/og.png") });
await page.evaluate(() => document.querySelector('[data-view="students"]').click());
await page.evaluate(() => document.querySelector("#stu-table [data-stu]").click());
await page.waitForSelector("#stu-dialog[open]");
await sleep(350); // 모달 등장 모션 200ms + 여유
await page.screenshot({ path: path.join(shots, "work-gaon-lms-2.png") });
async function openSettled(app) {
const page = await browser.newPage();
const failures = collectPageFailures(page, server.origin);
await prepareStillPage(page);
const file = path.join(publicRoot, "work", app, "index.html");
const response = await page.goto(server.origin + routeForFile(publicRoot, file), {
waitUntil: "domcontentloaded",
timeout: 30000,
});
if (!response?.ok()) throw new Error(`${app} returned ${response?.status() ?? "no response"}`);
await waitForStableVisual(page);
if (failures.length) throw new Error(failures.join(" · "));
return page;
}
if (selected.has("dure-enrollment")) {
// 두레: 과목 찾기 본컷 + 강의계획(과목 모달) -2컷
await open("dure-enrollment");
await page.screenshot({ path: path.join(shots, "work-dure-enrollment.png") });
await page.screenshot({ path: path.join(root, "public/work/dure-enrollment/og.png") });
await page.evaluate(() => document.querySelector(".course-row").click());
await page.waitForSelector("#course-dialog[open]");
await sleep(350);
await page.screenshot({ path: path.join(shots, "work-dure-enrollment-2.png") });
try {
browser = await puppeteer.launch({
executablePath: resolveChrome(),
headless: "new",
args: ["--no-sandbox", "--use-angle=swiftshader", "--enable-unsafe-swiftshader", "--force-device-scale-factor=1"],
defaultViewport: { width: 1440, height: 900, deviceScaleFactor: 1 },
});
if (selected.has("gaon-lms")) {
// 가온: 대시보드 본컷 + 학적 카드(수강생 모달) -2컷
const page = await openSettled("gaon-lms");
try {
await page.screenshot({ path: path.join(shots, "work-gaon-lms.png") });
await page.screenshot({ path: path.join(publicRoot, "work/gaon-lms/og.png") });
await page.evaluate(() => document.querySelector('[data-view="students"]').click());
await page.evaluate(() => document.querySelector("#stu-table [data-stu]").click());
await page.waitForSelector("#stu-dialog[open]");
await waitForStableVisual(page, { settleMs: 80 });
await page.screenshot({ path: path.join(shots, "work-gaon-lms-2.png") });
} finally {
await page.close();
}
}
if (selected.has("dure-enrollment")) {
// 두레: 과목 찾기 본컷 + 강의계획(과목 모달) -2컷
const page = await openSettled("dure-enrollment");
try {
await page.screenshot({ path: path.join(shots, "work-dure-enrollment.png") });
await page.screenshot({ path: path.join(publicRoot, "work/dure-enrollment/og.png") });
await page.evaluate(() => document.querySelector(".course-row").click());
await page.waitForSelector("#course-dialog[open]");
await waitForStableVisual(page, { settleMs: 80 });
await page.screenshot({ path: path.join(shots, "work-dure-enrollment-2.png") });
} finally {
await page.close();
}
}
} finally {
if (browser) await browser.close();
await server.close();
}
await browser.close();
console.log("work shots + og.png 갱신 완료");
console.log("정착 상태 work shots + og.png 갱신 완료");