Skip to content

Commit

Permalink
scripts(visual-regression): show target filename (ant-design#48444)
Browse files Browse the repository at this point in the history
* scripts(visual-regression): show target filename

* feat: update

* feat: show filename

* feat: update
  • Loading branch information
vagusX authored Apr 15, 2024
1 parent daba39b commit b42ffe6
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 44 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"@emotion/server": "^11.11.0",
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
"@madccc/duplicate-package-checker-webpack-plugin": "^1.0.0",
"@microflash/rehype-figure": "^2.1.0",
"@npmcli/run-script": "^7.0.4",
"@octokit/rest": "^20.1.0",
"@qixian.cs/github-contributors-list": "^2.0.1",
Expand Down Expand Up @@ -314,13 +315,14 @@
"react-router-dom": "^6.22.3",
"react-sticky-box": "^2.0.5",
"regenerator-runtime": "^0.14.1",
"rehype-stringify": "^10.0.0",
"remark": "^15.0.1",
"remark-cli": "^12.0.0",
"remark-gfm": "^4.0.0",
"remark-html": "^16.0.1",
"remark-lint": "^9.1.2",
"remark-lint-no-undefined-references": "^4.2.1",
"remark-preset-lint-recommended": "^6.1.3",
"remark-rehype": "^11.1.0",
"runes2": "^1.1.4",
"semver": "^7.6.0",
"sharp": "^0.33.3",
Expand Down
127 changes: 91 additions & 36 deletions scripts/visual-regression/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import os from 'os';
import path from 'path';
import { Readable } from 'stream';
import { finished } from 'stream/promises';
import simpleGit from 'simple-git';
import chalk from 'chalk';
import fse from 'fs-extra';
import difference from 'lodash/difference';
import minimist from 'minimist';
import pixelmatch from 'pixelmatch';
import { PNG } from 'pngjs';
import { remark } from 'remark';
import remarkGfm from 'remark-gfm';
import remarkHtml from 'remark-html';
import sharp from 'sharp';

import markdown2Html from './convert';

const ROOT_DIR = process.cwd();
const ALI_OSS_BUCKET = 'antd-visual-diff';

Expand Down Expand Up @@ -119,36 +119,100 @@ async function downloadBaseSnapshots(ref: string, targetDir: string) {
});
}

interface IImageDesc {
src: string;
alt: string;
}

function getMdImageTag(desc: IImageDesc, extraCaption?: boolean) {
const { src, alt } = desc;
if (!extraCaption || !alt) {
// in md2html report, we use `@microflash/rehype-figure` to generate a figure
return `![${alt}](${src})`;
}
// show caption with image in github markdown comment
return `![${alt}](${src}) ${alt}`;
}

interface IBadCase {
type: 'removed' | 'changed';
filename: string;
/**
* compare target file
*/
targetFilename?: string;
/**
* 0 - 1
*/
weight: number;
}

function md2Html(md: string) {
return remark().use(remarkGfm).use(remarkHtml).processSync(md).toString();
}
const git = simpleGit();

function parseArgs() {
async function parseArgs() {
// parse args from -- --pr-id=123 --base_ref=feature
const argv = minimist(process.argv.slice(2));
const prId = argv['pr-id'];
assert(prId, 'Missing --pr-id');
const baseRef = argv['base-ref'];
assert(baseRef, 'Missing --base-ref');

const { latest } = await git.log();

return {
prId,
baseRef,
currentRef: latest?.hash.slice(0, 8) || '',
};
}

function generateLineReport(
badCase: IBadCase,
publicPath: string,
currentRef: string,
extraCaption?: boolean,
) {
const { filename, type, targetFilename } = badCase;

let lineHTMLReport = '';
if (type === 'changed') {
lineHTMLReport += '| ';
lineHTMLReport += [
// add ref as query to avoid github cache image object
getMdImageTag({
src: `${publicPath}/images/base/${filename}?ref=${currentRef}`,
alt: targetFilename || '',
}, extraCaption),
getMdImageTag({
src: `${publicPath}/images/current/${filename}?ref=${currentRef}`,
alt: filename,
}, extraCaption),
getMdImageTag({
src: `${publicPath}/images/diff/${filename}?ref=${currentRef}`,
alt: '',
}, extraCaption),
].join(' | ');
lineHTMLReport += ' |\n';
} else if (type === 'removed') {
lineHTMLReport += '| ';
lineHTMLReport += [
getMdImageTag({
src: `${publicPath}/images/base/${filename}?ref=${currentRef}`,
alt: targetFilename || '',
}, extraCaption),
`⛔️⛔️⛔️ Missing ⛔️⛔️⛔️`,
`🚨🚨🚨 Removed 🚨🚨🚨`,
].join(' | ');
lineHTMLReport += ' |\n';
}
return lineHTMLReport;
}

function generateReport(
badCases: IBadCase[],
targetBranch: string,
targetRef: string,
currentRef: string,
prId: string,
): [string, string] {
const reportDirname = path.basename(REPORT_DIR);
Expand All @@ -174,15 +238,15 @@ function generateReport(
'<img src="https://github.com/ant-design/ant-design/assets/507615/2d1a77dc-dbc6-4b0f-9cbc-19a43d3c29cd" width="300" />',
].join('\n');

return [mdStr, md2Html(mdStr)];
return [mdStr, markdown2Html(mdStr)];
}

let reportMdStr = `
${commonHeader}
${fullReport}
| Image name | Expected | Actual | Diff |
| --- | --- | --- | --- |
| Expected (Branch ${targetBranch}) | Actual (Current PR) | Diff |
| --- | --- | --- |
`.trim();

reportMdStr += '\n';
Expand All @@ -192,44 +256,33 @@ ${fullReport}
let diffCount = 0;

for (const badCase of badCases) {
const { filename, type } = badCase;
let lineReportMdStr = '';
if (type === 'changed') {
lineReportMdStr += '| ';
lineReportMdStr += [
`\`${badCase.filename}\``,
`![${targetBranch}: ${targetRef}](${publicPath}/images/base/${filename})`,
`![current: pr-${prId}](${publicPath}/images/current/${filename})`,
`![diff](${publicPath}/images/diff/${filename})`,
].join(' | ');
lineReportMdStr += ' |\n';
} else if (type === 'removed') {
lineReportMdStr += '| ';
lineReportMdStr += [
`\`${badCase.filename}\``,
`![${targetBranch}: ${targetRef}](${publicPath}/images/base/${filename})`,
`⛔️⛔️⛔️ Missing ⛔️⛔️⛔️`,
`🚨🚨🚨 Removed 🚨🚨🚨`,
].join(' | ');
lineReportMdStr += ' |\n';
}

diffCount += 1;
if (diffCount <= 10) {
reportMdStr += lineReportMdStr;
// 将图片下方增加文件名
reportMdStr += generateLineReport(
badCase,
publicPath,
currentRef,
true,
);
}

fullVersionMd += lineReportMdStr;
fullVersionMd += generateLineReport(
badCase,
publicPath,
currentRef,
false,
);
}

reportMdStr += addonFullReportDesc;

// convert fullVersionMd to html
return [reportMdStr, md2Html(fullVersionMd)];
return [reportMdStr, markdown2Html(fullVersionMd)];
}

async function boot() {
const { prId, baseRef: targetBranch = 'master' } = parseArgs();
const { prId, baseRef: targetBranch = 'master', currentRef } = await parseArgs();

const baseImgSourceDir = path.resolve(ROOT_DIR, `./imageSnapshots-${targetBranch}`);

Expand Down Expand Up @@ -324,6 +377,7 @@ async function boot() {
badCases.push({
type: 'changed',
filename: compareImgName,
targetFilename: baseImgName,
weight: mismatchedPxPercent,
});
} else {
Expand All @@ -340,6 +394,7 @@ async function boot() {
badCases,
targetBranch,
targetCommitSha,
currentRef,
prId,
);
await fse.writeFile(path.join(REPORT_DIR, './report.md'), reportMdStr);
Expand Down
17 changes: 17 additions & 0 deletions scripts/visual-regression/convert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable compat/compat */
/* eslint-disable no-console, no-await-in-loop, import/no-extraneous-dependencies, no-restricted-syntax */
import { remark } from 'remark';
import remarkGfm from 'remark-gfm';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeFigure from '@microflash/rehype-figure';

export default function markdown2Html(content: string) {
return remark()
.use(remarkGfm)
.use(remarkRehype)
.use(rehypeFigure)
.use(rehypeStringify)
.processSync(content)
.toString();
}
35 changes: 28 additions & 7 deletions scripts/visual-regression/report-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
padding-bottom: 16px;
}

/* figcaption */
figcaption {
color: #a3a3a3;
text-align: center;
}

figure {
cursor: pointer;
}

/* Table Styles */
table {
width: 100%;
Expand All @@ -33,12 +43,7 @@

th,
td {
width: 10%;
}

th+th,
td+td {
width: 30%;
width: 33%;
}

th {
Expand Down Expand Up @@ -89,6 +94,22 @@

<body>
{{reportContent}}

<script>
window.addEventListener('click', function (e) {
if (e.target.tagName === 'FIGCAPTION') {
// get previous sibling
const img = e.target.previousElementSibling;
if (img.tagName === 'IMG' && img.src) {
window.open(img.src, '_blank');
}
}

if (e.target.tagName === 'IMG' && e.target.src) {
window.open(e.target.src, '_blank');
}
});
</script>
</body>

</html>
</html>
2 changes: 2 additions & 0 deletions typings/custom-typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ declare module '@npmcli/run-script' {
[key: string]: string | string[] | boolean | NodeJS.ProcessEnv;
}): Promise<void>;
}

declare module '@microflash/rehype-figure';

0 comments on commit b42ffe6

Please sign in to comment.