nimiq-branding-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -0
- package/NOTICE.md +32 -0
- package/README.md +73 -0
- package/assets/css/legacy/nimiq-style.icons.svg +1 -0
- package/assets/css/legacy/nimiq-style.min.css +5 -0
- package/assets/css/modern/animations.css +179 -0
- package/assets/css/modern/atomic.css +148 -0
- package/assets/css/modern/colors.css +82 -0
- package/assets/css/modern/fonts.css +17 -0
- package/assets/css/modern/index.css +8 -0
- package/assets/css/modern/preflight.css +190 -0
- package/assets/css/modern/spacing.css +1023 -0
- package/assets/css/modern/static-content.css +300 -0
- package/assets/css/modern/typography.css +632 -0
- package/assets/css/modern/utilities.css +861 -0
- package/assets/fonts/mulish-0b696a2e.woff2 +0 -0
- package/assets/fonts/mulish-294ced17.woff2 +0 -0
- package/assets/fonts/mulish-4eb440e1.woff2 +0 -0
- package/assets/fonts/mulish-78a2d471.woff2 +0 -0
- package/assets/fonts/mulish-81f6c1ba.woff2 +0 -0
- package/assets/fonts/mulish-c1a61bc6.woff2 +0 -0
- package/assets/fonts/mulish-c7803f2b.woff2 +0 -0
- package/assets/fonts/mulish-e64de9e7.woff2 +0 -0
- package/assets/fonts/mulish-ecf98336.woff2 +0 -0
- package/assets/fonts/mulish-f727ad98.woff2 +0 -0
- package/assets/icons/duotone/duotone-arrow-to-top-left-from-corner.svg +1 -0
- package/assets/icons/duotone/duotone-bank-building.svg +1 -0
- package/assets/icons/duotone/duotone-bell.svg +1 -0
- package/assets/icons/duotone/duotone-block-stairs.svg +1 -0
- package/assets/icons/duotone/duotone-btc-invoice.svg +1 -0
- package/assets/icons/duotone/duotone-cactus.svg +1 -0
- package/assets/icons/duotone/duotone-cash-register.svg +1 -0
- package/assets/icons/duotone/duotone-column-chart.svg +1 -0
- package/assets/icons/duotone/duotone-credit-card.svg +1 -0
- package/assets/icons/duotone/duotone-crypto-currencies-btc-eth.svg +1 -0
- package/assets/icons/duotone/duotone-crypto-currencies-btc-usdc.svg +1 -0
- package/assets/icons/duotone/duotone-cryptos-pizza.svg +1 -0
- package/assets/icons/duotone/duotone-dashboard.svg +1 -0
- package/assets/icons/duotone/duotone-displaced-hamburguer.svg +1 -0
- package/assets/icons/duotone/duotone-document-text.svg +1 -0
- package/assets/icons/duotone/duotone-document-vertical-line.svg +1 -0
- package/assets/icons/duotone/duotone-document.svg +1 -0
- package/assets/icons/duotone/duotone-employee.svg +1 -0
- package/assets/icons/duotone/duotone-envelope.svg +1 -0
- package/assets/icons/duotone/duotone-fiat-currencies.svg +1 -0
- package/assets/icons/duotone/duotone-fiat-exchange.svg +1 -0
- package/assets/icons/duotone/duotone-fluctuations.svg +1 -0
- package/assets/icons/duotone/duotone-gamepad.svg +1 -0
- package/assets/icons/duotone/duotone-globe.svg +1 -0
- package/assets/icons/duotone/duotone-group.svg +1 -0
- package/assets/icons/duotone/duotone-handshake.svg +1 -0
- package/assets/icons/duotone/duotone-high-five.svg +1 -0
- package/assets/icons/duotone/duotone-htlc-box.svg +1 -0
- package/assets/icons/duotone/duotone-incognito.svg +1 -0
- package/assets/icons/duotone/duotone-key-puzzle.svg +1 -0
- package/assets/icons/duotone/duotone-languages.svg +1 -0
- package/assets/icons/duotone/duotone-magnifying-glass.svg +1 -0
- package/assets/icons/duotone/duotone-medal.svg +1 -0
- package/assets/icons/duotone/duotone-network.svg +1 -0
- package/assets/icons/duotone/duotone-nim-phone.svg +1 -0
- package/assets/icons/duotone/duotone-nimiq-environment.svg +1 -0
- package/assets/icons/duotone/duotone-no-chargeback.svg +1 -0
- package/assets/icons/duotone/duotone-oasis-puzzle.svg +1 -0
- package/assets/icons/duotone/duotone-paper-plane.svg +1 -0
- package/assets/icons/duotone/duotone-peer-to-peer.svg +1 -0
- package/assets/icons/duotone/duotone-pin-with-shadow.svg +1 -0
- package/assets/icons/duotone/duotone-safe-lock.svg +1 -0
- package/assets/icons/duotone/duotone-smart-contract.svg +1 -0
- package/assets/icons/duotone/duotone-sparkling-swap.svg +1 -0
- package/assets/icons/duotone/duotone-speedmeter.svg +1 -0
- package/assets/icons/duotone/duotone-staking-ripple.svg +1 -0
- package/assets/icons/duotone/duotone-successful-sequence.svg +1 -0
- package/assets/icons/duotone/duotone-three-hands-hexagon.svg +1 -0
- package/assets/icons/nimiq-flags.json +1274 -0
- package/assets/icons/nimiq-icons.json +1631 -0
- package/assets/img/bg-hexagons.svg +1 -0
- package/assets/img/cpl-preview.webp +0 -0
- package/assets/img/gods-light.webp +0 -0
- package/assets/img/iqons.min.svg +1 -0
- package/assets/img/multisig-preview.svg +1 -0
- package/assets/img/nimiq-pay-preview.webp +0 -0
- package/assets/img/nimiq-wallet-preview.webp +0 -0
- package/assets/img/world-map.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-bitcoin-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-bitcoin-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-bitcoin-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-bitcoin.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-colones-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-colones-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cpl-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cpl-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cpl-tag-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cpl-tag.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cpl-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-crypto-map-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-crypto-map-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-crypto-map-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-crypto-map-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-crypto-map.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cryptocity-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cryptocity-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cryptocity-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cryptocity-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-cryptocity.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-developer-center-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-developer-center-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-developer-center-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-discord-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-discord.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-ethereum-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-ethereum.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-euro-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-euro-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-facebook-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-facebook.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-fm-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-fm-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-fm-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-fm-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-fm.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-github-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-github.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-gmaps-pin-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-gmaps-pin.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-instagram-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-instagram.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-lightning-bitcoin-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-lightning-bitcoin-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-lightning-bitcoin-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-lightning-bitcoin.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-multisig-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-multisig.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-forum-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-forum.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-hexagon-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-hexagon-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-pay-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-pay-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-pay-vertical-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-pay-vertical.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-pay-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-vertical-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-vertical.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-wallet-horizontal-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-wallet-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-wallet-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-white-horizontal.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq-white-vertical.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-nimiq.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-reddit-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-reddit.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-shiny-nim-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-shiny-nim.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-super-simple-swap-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-super-simple-swap-text-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-super-simple-swap-text.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-super-simple-swap.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-telegram-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-telegram.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-twitter-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-twitter.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usd-outline-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usd-outline.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usdc-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usdc.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usdt-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-usdt.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-youtube-mono.svg +1 -0
- package/assets/logos/nimiq-icons-logos/logos-youtube.svg +1 -0
- package/assets/logos/official/black/nimiq_logo_black_horizontal.svg +1 -0
- package/assets/logos/official/black/nimiq_logo_black_vertical.svg +1 -0
- package/assets/logos/official/black/nimiq_signet_black_16x16.svg +1 -0
- package/assets/logos/official/black/nimiq_signet_black_32x32.svg +1 -0
- package/assets/logos/official/black/nimiq_signet_black_64x64.svg +1 -0
- package/assets/logos/official/black/nimiq_signet_black_base_size.svg +1 -0
- package/assets/logos/official/colored/_extended/nimiq_keyguard.svg +1 -0
- package/assets/logos/official/colored/_extended/nimiq_miner.svg +1 -0
- package/assets/logos/official/colored/_extended/nimiq_safe.svg +1 -0
- package/assets/logos/official/colored/_extended/nimiq_shop.svg +1 -0
- package/assets/logos/official/colored/nimiq_logo_rgb_horizontal.svg +1 -0
- package/assets/logos/official/colored/nimiq_logo_rgb_vertical.svg +1 -0
- package/assets/logos/official/colored/nimiq_logo_rgb_white_horizontal.svg +1 -0
- package/assets/logos/official/colored/nimiq_logo_rgb_white_vertical.svg +1 -0
- package/assets/logos/official/colored/nimiq_signet_rgb_16x16.svg +1 -0
- package/assets/logos/official/colored/nimiq_signet_rgb_32x32.svg +1 -0
- package/assets/logos/official/colored/nimiq_signet_rgb_64x64.svg +1 -0
- package/assets/logos/official/colored/nimiq_signet_rgb_base_size.svg +1 -0
- package/assets/logos/official/nimiq-logo.min.svg +1 -0
- package/assets/logos/official/white/nimiq_logo_white_horizontal.svg +1 -0
- package/assets/logos/official/white/nimiq_logo_white_vertical.svg +1 -0
- package/assets/logos/official/white/nimiq_signet_white_16x16.svg +1 -0
- package/assets/logos/official/white/nimiq_signet_white_32x32.svg +1 -0
- package/assets/logos/official/white/nimiq_signet_white_64x64.svg +1 -0
- package/assets/logos/official/white/nimiq_signet_white_base_size.svg +1 -0
- package/assets/tokens.md +28 -0
- package/bin/nq.js +274 -0
- package/package.json +51 -0
- package/registry/components/account-header/meta.json +70 -0
- package/registry/components/account-list/meta.json +84 -0
- package/registry/components/account-ring/meta.json +48 -0
- package/registry/components/address-display/meta.json +22 -0
- package/registry/components/address-input/meta.json +24 -0
- package/registry/components/amount/meta.json +26 -0
- package/registry/components/amount-input/meta.json +25 -0
- package/registry/components/amount-with-fee/meta.json +25 -0
- package/registry/components/app-showcase-card/meta.json +24 -0
- package/registry/components/backup-banner/meta.json +15 -0
- package/registry/components/balance-distribution/meta.json +20 -0
- package/registry/components/buttons/meta.json +22 -0
- package/registry/components/card/meta.json +18 -0
- package/registry/components/close-button/meta.json +18 -0
- package/registry/components/consensus-icon/meta.json +20 -0
- package/registry/components/copyable/meta.json +20 -0
- package/registry/components/fiat-amount/meta.json +24 -0
- package/registry/components/hero-section/meta.json +56 -0
- package/registry/components/honeycomb-band/meta.json +30 -0
- package/registry/components/identicon/meta.json +38 -0
- package/registry/components/label-input/meta.json +24 -0
- package/registry/components/loading-spinner/meta.json +18 -0
- package/registry/components/page-body/meta.json +18 -0
- package/registry/components/page-footer/meta.json +18 -0
- package/registry/components/page-header/meta.json +23 -0
- package/registry/components/payment-info-line/meta.json +97 -0
- package/registry/components/price-chart/meta.json +21 -0
- package/registry/components/qr-code/meta.json +60 -0
- package/registry/components/search-bar/meta.json +20 -0
- package/registry/components/select-bar/meta.json +22 -0
- package/registry/components/slider-toggle/meta.json +23 -0
- package/registry/components/small-page/meta.json +18 -0
- package/registry/components/status-alert/meta.json +22 -0
- package/registry/components/status-screen/meta.json +27 -0
- package/registry/components/swap-balance-bar/meta.json +97 -0
- package/registry/components/timer/meta.json +25 -0
- package/registry/components/toast-notification/meta.json +24 -0
- package/registry/components/tooltip/meta.json +28 -0
- package/registry/components/transaction-list/meta.json +48 -0
- package/registry/index.json +394 -0
- package/scripts/snap.mjs +42 -0
- package/scripts/verify.mjs +76 -0
package/scripts/snap.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Snapshot a component's truth render to its reference.png.
|
|
2
|
+
// Usage: node scripts/snap.mjs <component> [--demo]
|
|
3
|
+
// default: renders registry/components/<name>/truth/truth.html -> reference.png
|
|
4
|
+
// --demo : renders html/demo.html -> .verify/<name>.got.png (for eyeballing)
|
|
5
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { dirname, join, resolve } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
11
|
+
const name = process.argv[2];
|
|
12
|
+
const demoMode = process.argv.includes('--demo');
|
|
13
|
+
if (!name) { console.error('usage: node scripts/snap.mjs <component> [--demo]'); process.exit(1); }
|
|
14
|
+
|
|
15
|
+
const dir = join(ROOT, 'registry', 'components', name);
|
|
16
|
+
const meta = JSON.parse(await readFile(join(dir, 'meta.json'), 'utf8'));
|
|
17
|
+
const v = meta.verify ?? {};
|
|
18
|
+
const src = demoMode ? join(dir, 'html', 'demo.html') : join(dir, 'truth', 'truth.html');
|
|
19
|
+
if (!existsSync(src)) { console.error(`missing ${src}`); process.exit(1); }
|
|
20
|
+
|
|
21
|
+
const { chromium } = await import('playwright');
|
|
22
|
+
const browser = await chromium.launch();
|
|
23
|
+
const page = await browser.newPage({
|
|
24
|
+
viewport: v.viewport ?? { width: 800, height: 600 },
|
|
25
|
+
deviceScaleFactor: v.scale ?? 2,
|
|
26
|
+
});
|
|
27
|
+
await page.goto('file://' + src);
|
|
28
|
+
await page.waitForLoadState('networkidle');
|
|
29
|
+
await page.evaluate(() => document.fonts.ready);
|
|
30
|
+
await page.waitForTimeout(v.settleMs ?? 250);
|
|
31
|
+
const target = v.selector ? page.locator(v.selector) : page;
|
|
32
|
+
const buf = await target.screenshot({ animations: 'disabled' });
|
|
33
|
+
let out;
|
|
34
|
+
if (demoMode) {
|
|
35
|
+
await mkdir(join(ROOT, '.verify'), { recursive: true });
|
|
36
|
+
out = join(ROOT, '.verify', `${name}.got.png`);
|
|
37
|
+
} else {
|
|
38
|
+
out = join(dir, 'reference.png');
|
|
39
|
+
}
|
|
40
|
+
await writeFile(out, buf);
|
|
41
|
+
console.log(out);
|
|
42
|
+
await browser.close();
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Pixel-verification harness: renders a component's html variant headlessly,
|
|
2
|
+
// screenshots it, and diffs against registry/components/<name>/reference.png.
|
|
3
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
9
|
+
const REGISTRY = join(ROOT, 'registry', 'components');
|
|
10
|
+
|
|
11
|
+
export async function verify(name) {
|
|
12
|
+
const dir = join(REGISTRY, name);
|
|
13
|
+
const metaPath = join(dir, 'meta.json');
|
|
14
|
+
if (!existsSync(metaPath)) return { status: 'skip', reason: 'no meta.json' };
|
|
15
|
+
const meta = JSON.parse(await readFile(metaPath, 'utf8'));
|
|
16
|
+
const demo = join(dir, 'html', 'demo.html');
|
|
17
|
+
const ref = join(dir, 'reference.png');
|
|
18
|
+
if (!existsSync(demo)) return { status: 'skip', reason: 'no html/demo.html' };
|
|
19
|
+
if (!existsSync(ref)) return { status: 'skip', reason: 'no reference.png' };
|
|
20
|
+
|
|
21
|
+
const { chromium } = await import('playwright');
|
|
22
|
+
const { PNG } = await import('pngjs');
|
|
23
|
+
const pixelmatch = (await import('pixelmatch')).default;
|
|
24
|
+
|
|
25
|
+
const v = meta.verify ?? {};
|
|
26
|
+
const viewport = v.viewport ?? { width: 800, height: 600 };
|
|
27
|
+
const threshold = v.maxDiffPct ?? 1.0; // percent of pixels allowed to differ
|
|
28
|
+
|
|
29
|
+
const browser = await chromium.launch();
|
|
30
|
+
try {
|
|
31
|
+
const page = await browser.newPage({ viewport, deviceScaleFactor: v.scale ?? 2 });
|
|
32
|
+
await page.goto('file://' + demo);
|
|
33
|
+
await page.waitForLoadState('networkidle');
|
|
34
|
+
await page.evaluate(() => document.fonts.ready);
|
|
35
|
+
await page.waitForTimeout(v.settleMs ?? 250); // let transitions settle
|
|
36
|
+
const target = v.selector ? page.locator(v.selector) : page;
|
|
37
|
+
const shotBuf = await target.screenshot({ animations: 'disabled' });
|
|
38
|
+
|
|
39
|
+
const refPng = PNG.sync.read(await readFile(ref));
|
|
40
|
+
let gotPng = PNG.sync.read(shotBuf);
|
|
41
|
+
if (gotPng.width !== refPng.width || gotPng.height !== refPng.height) {
|
|
42
|
+
return {
|
|
43
|
+
status: 'fail', diffPct: 100, threshold,
|
|
44
|
+
diffPath: `size mismatch: got ${gotPng.width}x${gotPng.height}, ref ${refPng.width}x${refPng.height}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const diff = new PNG({ width: refPng.width, height: refPng.height });
|
|
48
|
+
const badPixels = pixelmatch(refPng.data, gotPng.data, diff.data, refPng.width, refPng.height, {
|
|
49
|
+
threshold: v.pixelThreshold ?? 0.1,
|
|
50
|
+
});
|
|
51
|
+
const diffPct = +(100 * badPixels / (refPng.width * refPng.height)).toFixed(3);
|
|
52
|
+
if (diffPct <= threshold) return { status: 'pass', diffPct, threshold };
|
|
53
|
+
const outDir = join(ROOT, '.verify');
|
|
54
|
+
await mkdir(outDir, { recursive: true });
|
|
55
|
+
const diffPath = join(outDir, `${name}.diff.png`);
|
|
56
|
+
await writeFile(diffPath, PNG.sync.write(diff));
|
|
57
|
+
await writeFile(join(outDir, `${name}.got.png`), shotBuf);
|
|
58
|
+
return { status: 'fail', diffPct, threshold, diffPath };
|
|
59
|
+
} finally {
|
|
60
|
+
await browser.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// CLI entry: node scripts/verify.mjs <name|all>
|
|
65
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
66
|
+
const { readdir } = await import('node:fs/promises');
|
|
67
|
+
const target = process.argv[2] ?? 'all';
|
|
68
|
+
const names = target === 'all' ? (await readdir(REGISTRY)).sort() : [target];
|
|
69
|
+
let fail = 0;
|
|
70
|
+
for (const n of names) {
|
|
71
|
+
const r = await verify(n);
|
|
72
|
+
console.log(`${r.status === 'pass' ? '✓' : r.status === 'skip' ? '·' : '✗'} ${n}`, r);
|
|
73
|
+
if (r.status === 'fail') fail++;
|
|
74
|
+
}
|
|
75
|
+
process.exitCode = fail ? 1 : 0;
|
|
76
|
+
}
|