Skip to content

Commit

Permalink
feat: screenshots of modals added to curric automate script
Browse files Browse the repository at this point in the history
  • Loading branch information
orangemug committed Nov 19, 2024
1 parent 3650525 commit 825f3aa
Show file tree
Hide file tree
Showing 7 changed files with 639 additions and 362 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`wrapHtmlLayout wraps content with layout 1`] = `
"
<html>
<body>
<style>
html {
box-sizing: border-box;
font-family: sans-serif;
font-size: 14px;
}
html, body {
margin: 0;
padding: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.column-header{
background: #eeeeee;
padding: 8px;
position: sticky;
top: 8px;
z-index: 9999;
border-radius: 5px;
}
.nav-item{
margin:8px 0;
display:flex;
align-items: center;
}
.nav-item a {
text-wrap: nowrap;
color:#333;
}
.nav-item a:hover{
color: #777;
}
.pill{
background:#333;
color:#fff;
padding:2px 4px;
border-radius:3px;
}
.image-holder{
position: relative;
overflow: hidden;
}
.diff-image{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
mix-blend-mode: difference;
}
.image-holder img{
width: 100%;
}
</style>
<div style="display: flex;">
<p>Hello world</p>
</div>
</body>
</html>
"
`;
268 changes: 114 additions & 154 deletions scripts/dev/curriculum/_commands/compare.ts
Original file line number Diff line number Diff line change
@@ -1,172 +1,132 @@
import { writeFile } from "fs/promises";
import { basename, join, relative } from "path";
import { join } from "path";

import { glob } from "glob";
import { sortBy, uniq } from "lodash";
import open from "open";

// function formatPath(input: string) {
// return `./${input}`;
// }

const removeFileExtension = (filename: string) =>
filename.substring(0, filename.lastIndexOf(".")) || filename;

function outputPathFromLabel(label: string) {
const labelName = label.replace(/^:/, "");
return `${process.cwd()}/scripts/dev/curriculum/output/screenshots/${labelName}/`;
}
import {
readJson,
resolveInputPath,
wrapHtmlLayout,
removeFileExtension,
renderComparison,
ScreenshotResult,
ScreenshotPageResult,
ScreenshotModalResult,
} from "./helpers";

export default async function compare(
basepathInput: string,
targetpathInput: string,
) {
const basepath = basepathInput.startsWith(":")
? outputPathFromLabel(basepathInput)
: basepathInput;
const targetpath = targetpathInput.startsWith(":")
? outputPathFromLabel(targetpathInput)
: targetpathInput;
const baseFiles = await glob(`${basepath}/*.png`);
const targetFiles = await glob(`${targetpath}/*.png`);
const basepath = resolveInputPath(basepathInput);
const targetpath = resolveInputPath(targetpathInput);

const baseJson: ScreenshotResult = await readJson(
join(basepath, "index.json"),
);
const targetJson: ScreenshotResult = await readJson(
join(targetpath, "index.json"),
);

const includesModals = baseJson.includesModals ?? targetJson.includesModals;

const outbasePath = process.cwd() + "/scripts/dev/curriculum/output/";
const relBasepath = relative(outbasePath, basepath);
const relTargetpath = relative(outbasePath, targetpath);

const baseFilesStub = baseFiles.map((f) => basename(f));
const targetFilesStub = targetFiles.map((f) => basename(f));
const allFiles = sortBy(uniq([...baseFilesStub, ...targetFilesStub]));
const html = `
<body>
<style>
html {
box-sizing: border-box;
font-family: sans-serif;
font-size: 14px;
}
html, body {
margin: 0;
padding: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.column-header{
background: #eeeeee;
padding: 8px;
position: sticky;
top: 8px;
z-index: 9999;
border-radius: 5px;
}
.nav-item{
margin:8px 0;
display:flex;
}
.nav-item a{
padding:4px;
border:1px solid #ccc;
background:#f6f6f6;
border-radius:5px;
text-decoration:none;
text-wrap: nowrap;
color:#333;
}
.nav-item a:hover{
background:#e6e6e6;
}
.pill{
background:#333;
color:#fff;
padding:2px 4px;
border-radius:3px;
}
.image-holder{
position: relative;
overflow: hidden;
}
.diff-image{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
mix-blend-mode: difference;
}
.image-holder img{
width: 100%;
}
</style>
<div style="display: flex;">
<div style="width: fit-content;">
<div style="
position: sticky;
top: 0;
padding: 10px;
height: 100vh;
overflow-y: auto;
">
${allFiles
.map((filename) => {
return `<div class="nav-item"><a href="#${filename}">${removeFileExtension(
filename,
)}</a></div>`;
})
.join("")}
</div>
</div>
<div style="
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 0 8px;
border-left: 1px solid #ccc;
">
${allFiles
.map((filename) => {
let imageHtml = `
<span id="${filename}" style="grid-column: 1 / -1"></span>
<div class="column-header" >
<span class="pill">${basepathInput}</span> ${filename}
</div>
<div class="column-header">
<span class="pill">${targetpathInput}</span> ${filename}
</div>
<div class="column-header">
<span class="pill">diff</span> ${filename}
</div>
`;
if (baseFilesStub.includes(filename)) {
imageHtml += `<div class="image-holder"><img src="${relBasepath}/${filename}" /></div>`;
} else {
imageHtml += `<div style="background: #eee; padding: 8px;">Missing</div>`;
}
if (targetFilesStub.includes(filename)) {
imageHtml += `<div class="image-holder"><img src="${relTargetpath}/${filename}" /></div>`;
} else {
imageHtml += `<div style="background: #eee; padding: 8px;">Missing</div>`;
}
const baseJsonBySlug: Record<string, ScreenshotPageResult> = {};
const targetJsonBySlug: Record<string, ScreenshotPageResult> = {};
for (const obj of baseJson.pages) {
baseJsonBySlug[obj.slug] = obj;
}
for (const obj of targetJson.pages) {
targetJsonBySlug[obj.slug] = obj;
}

const allSlugs = sortBy(
uniq([...Object.keys(baseJsonBySlug), ...Object.keys(targetJsonBySlug)]),
);

if (includesModals) {
for (const slug of allSlugs) {
const baseModalJsonBySlug: Record<string, ScreenshotModalResult> = {};
const targetModalJsonBySlug: Record<string, ScreenshotModalResult> = {};
for (const obj of baseJsonBySlug[slug]!.modals) {
baseModalJsonBySlug[obj.slug] = obj;
}
for (const obj of targetJsonBySlug[slug]!.modals) {
targetModalJsonBySlug[obj.slug] = obj;
}

const modalSlugs = sortBy(
uniq([
...Object.keys(baseModalJsonBySlug),
...Object.keys(targetModalJsonBySlug),
]),
);

const html = wrapHtmlLayout(`
<div style="
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 0 8px;
border-left: 1px solid #ccc;
">
${modalSlugs
.map((modalSlug) => {
return renderComparison(
basepathInput,
targetpathInput,
baseModalJsonBySlug[modalSlug]!,
targetModalJsonBySlug[modalSlug]!,
);
})
.join("")}
</div>
`);
await writeFile(outbasePath + `/${slug}.html`, html);
}
}

if (
baseFilesStub.includes(filename) &&
targetFilesStub.includes(filename)
) {
imageHtml += `<div style="filter:invert(1)" class="image-holder">
<img src="${relBasepath}/${filename}" />
<div class="diff-image"><img src="${relTargetpath}/${filename}" /></div>
</div>`;
} else {
imageHtml += `<div style="background: #eee; padding: 8px;">Missing</div>`;
}
const html = wrapHtmlLayout(`
<div style="width: fit-content;">
<div style="
position: sticky;
top: 0;
padding: 10px;
height: 100vh;
overflow-y: auto;
">
${allSlugs
.map((slug) => {
return `<div class="nav-item">
<a href="#${slug}">${removeFileExtension(slug)}
${includesModals ? `</a>&nbsp;—&nbsp;<a href="./${slug}.html">modals↗</a>` : ""}
</div>`;
})
.join("")}
</div>
</div>
<div style="
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 0 8px;
border-left: 1px solid #ccc;
">
${allSlugs
.map((slug) => {
return renderComparison(
basepathInput,
targetpathInput,
baseJsonBySlug[slug]!,
targetJsonBySlug[slug]!,
);
})
.join("")}
</div>
`);

return imageHtml;
})
.join("")}
</div>
</div>
</body>
`;
const outpath = join(outbasePath, `compare.html`);
await writeFile(outpath, html);
console.log(`📄 written to: ${outpath}`);
Expand Down
Loading

0 comments on commit 825f3aa

Please sign in to comment.