Files
MES_Manage_View_V20/work/system-manual/capture-system-pages.js

169 lines
6.2 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const WebSocket = require('ws')
const outputDir = path.resolve(__dirname, 'screenshots')
fs.mkdirSync(outputDir, { recursive: true })
const loginUser = process.env.MES_MANUAL_USER
const loginPassword = process.env.MES_MANUAL_PASSWORD
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
async function connect() {
const targets = await fetch('http://127.0.0.1:9222/json').then(res => res.json())
const target = targets.find(item => item.type === 'page')
if (!target) throw new Error('No Chrome page target found')
const ws = new WebSocket(target.webSocketDebuggerUrl)
let id = 0
const pending = new Map()
ws.on('message', raw => {
const message = JSON.parse(raw.toString())
if (message.id && pending.has(message.id)) {
const { resolve, reject } = pending.get(message.id)
pending.delete(message.id)
message.error ? reject(new Error(message.error.message)) : resolve(message.result)
}
})
await new Promise((resolve, reject) => {
ws.once('open', resolve)
ws.once('error', reject)
})
const send = (method, params = {}) => new Promise((resolve, reject) => {
const requestId = ++id
pending.set(requestId, { resolve, reject })
ws.send(JSON.stringify({ id: requestId, method, params }))
})
return { ws, send }
}
async function main() {
const { ws, send } = await connect()
await send('Page.enable')
await send('Runtime.enable')
await send('Emulation.setDeviceMetricsOverride', {
width: 1920,
height: 1080,
deviceScaleFactor: 1,
mobile: false
})
const evaluate = expression => send('Runtime.evaluate', {
expression,
awaitPromise: true,
returnByValue: true
}).then(result => result.result.value)
async function waitFor(expression, timeout = 30000) {
const started = Date.now()
while (Date.now() - started < timeout) {
if (await evaluate(`Boolean(${expression})`)) return
await wait(300)
}
throw new Error(`Timed out waiting for: ${expression}`)
}
async function screenshot(name) {
await wait(700)
const result = await send('Page.captureScreenshot', {
format: 'png',
captureBeyondViewport: false,
fromSurface: true
})
fs.writeFileSync(path.join(outputDir, `${name}.png`), Buffer.from(result.data, 'base64'))
console.log(`Captured ${name}`)
}
async function navigate(hashPath) {
await send('Page.navigate', { url: `https://127.0.0.1:1997/#${hashPath}` })
await waitFor("document.readyState === 'complete'")
await waitFor("document.querySelector('.app-main') || document.querySelector('.el-card')", 40000)
await wait(1800)
}
async function clickByText(text, selector = 'button') {
return evaluate(`(() => {
const nodes = [...document.querySelectorAll(${JSON.stringify(selector)})]
const node = nodes.find(item => item.innerText && item.innerText.replace(/\\s+/g, '').includes(${JSON.stringify(text.replace(/\s+/g, ''))}))
if (!node) return false
node.click()
return true
})()`)
}
await send('Page.navigate', { url: 'https://127.0.0.1:1997/#/login' })
await waitFor("document.querySelector('input[name=username]') || document.querySelector('.sidebar-container')", 40000)
if (await evaluate("Boolean(document.querySelector('input[name=username]'))")) {
if (!loginUser || !loginPassword) {
throw new Error('Set MES_MANUAL_USER and MES_MANUAL_PASSWORD before capturing pages')
}
await evaluate(`(() => {
const setValue = (el, value) => {
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set
setter.call(el, value)
el.dispatchEvent(new Event('input', { bubbles: true }))
el.dispatchEvent(new Event('change', { bubbles: true }))
}
setValue(document.querySelector('input[name=username]'), ${JSON.stringify(loginUser)})
setValue(document.querySelector('input[name=password]'), ${JSON.stringify(loginPassword)})
})()`)
await clickByText('登录')
}
await waitFor("document.querySelector('.sidebar-container')", 40000)
await wait(1500)
const pages = [
['01-personnel-list', '/SystemMaintenance/PersonnelManagement/index'],
['02-role-list', '/SystemMaintenance/SystemRrolemaintenance/index'],
['03-menu-list', '/SystemMaintenance/MenuManagement/index'],
['04-workstation-list', '/SystemMaintenance/WorkstationManagement/index'],
['05-operation-log', '/SystemMaintenance/OperationLog/index']
]
for (const [name, route] of pages) {
await navigate(route)
await screenshot(name)
if (name === '01-personnel-list') {
if (await clickByText('新增')) {
await waitFor("document.querySelector('.el-dialog__wrapper:not([style*=\"display: none\"])')")
await screenshot('01-personnel-add-dialog')
await clickByText('取消', '.el-dialog__wrapper:not([style*=\"display: none\"]) button')
}
}
if (name === '02-role-list') {
if (await clickByText('新增')) {
await waitFor("document.querySelector('.el-dialog__wrapper:not([style*=\"display: none\"])')")
await screenshot('02-role-add-dialog')
await clickByText('取消', '.el-dialog__wrapper:not([style*=\"display: none\"]) button')
}
}
if (name === '03-menu-list') {
await evaluate(`document.querySelector('#selectRoleName').click()`)
await waitFor("[...document.querySelectorAll('.el-select-dropdown__item')].some(item => item.innerText.trim() === '管理员')")
await evaluate(`(() => {
const option = [...document.querySelectorAll('.el-select-dropdown__item')]
.find(item => item.innerText.trim() === '管理员')
option.click()
})()`)
await waitFor("document.querySelectorAll('.moduleTree .el-tree-node').length > 0")
await screenshot('03-menu-permission-panel')
}
if (name === '04-workstation-list') {
if (await clickByText('新增')) {
await waitFor("document.querySelector('.el-dialog__wrapper:not([style*=\"display: none\"])')")
await screenshot('04-workstation-add-dialog')
await clickByText('取消', '.el-dialog__wrapper:not([style*=\"display: none\"]) button')
}
}
}
ws.close()
}
main().catch(error => {
console.error(error)
process.exitCode = 1
})