72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
import { mkdir } from 'node:fs/promises'
|
||
import { dirname, resolve } from 'node:path'
|
||
import { chromium } from 'playwright-core'
|
||
|
||
/**
|
||
* 截图核对用。
|
||
*
|
||
* 用法:
|
||
* node scripts/screenshot.mjs # 首屏
|
||
* node scripts/screenshot.mjs http://127.0.0.1:5199/#buttons shots/buttons.png
|
||
* node scripts/screenshot.mjs http://127.0.0.1:5199/ shots/cards.png '#cards' # 只截某一节
|
||
*
|
||
* 依赖本机的 Chrome / Edge(playwright-core 不自带浏览器),
|
||
* 优先 Chrome,找不到再退回 Edge。
|
||
*/
|
||
const [, , urlArg, outArg, selectorArg] = process.argv
|
||
const url = urlArg ?? 'http://127.0.0.1:5199/'
|
||
const out = resolve(outArg ?? 'shots/site.png')
|
||
// 第四个参数可以是选择器,也可以是 `full`(整页截图)
|
||
const wantsFull = selectorArg === 'full'
|
||
const selector = selectorArg === undefined || wantsFull ? undefined : selectorArg
|
||
|
||
const channels = ['chrome', 'msedge']
|
||
let browser
|
||
let lastError
|
||
|
||
for (const channel of channels) {
|
||
try {
|
||
browser = await chromium.launch({ channel, headless: true })
|
||
break
|
||
} catch (error) {
|
||
lastError = error
|
||
}
|
||
}
|
||
|
||
if (browser === undefined) {
|
||
console.error('找不到可用的 Chrome / Edge,无法截图:', lastError)
|
||
process.exit(1)
|
||
}
|
||
|
||
try {
|
||
// 可以用环境变量指定视口,方便做移动端 / 平板核对:
|
||
// $env:SHOT_WIDTH=390; $env:SHOT_HEIGHT=844; node scripts/screenshot.mjs <url> <out>
|
||
const width = Number(process.env.SHOT_WIDTH ?? 1440)
|
||
const height = Number(process.env.SHOT_HEIGHT ?? 900)
|
||
const page = await browser.newPage({ viewport: { width, height } })
|
||
|
||
await page.goto(url, { waitUntil: 'networkidle' })
|
||
await page.evaluate(() => document.fonts.ready)
|
||
|
||
// 带 #锚点 时,浏览器在 React 渲染前就尝试跳转了,这里补一次
|
||
const hash = new URL(url).hash
|
||
if (hash !== '' && selector === undefined) {
|
||
await page.evaluate((id) => {
|
||
document.getElementById(id)?.scrollIntoView({ block: 'start' })
|
||
}, hash.slice(1))
|
||
}
|
||
|
||
await page.waitForTimeout(350)
|
||
await mkdir(dirname(out), { recursive: true })
|
||
|
||
if (selector !== undefined) {
|
||
await page.locator(selector).screenshot({ path: out })
|
||
} else {
|
||
await page.screenshot({ path: out, fullPage: wantsFull })
|
||
}
|
||
|
||
console.log(`已保存:${out}`)
|
||
} finally {
|
||
await browser.close()
|
||
}
|