update
This commit is contained in:
183
scripts/open-four-players.mjs
Normal file
183
scripts/open-four-players.mjs
Normal file
@@ -0,0 +1,183 @@
|
||||
import { chromium } from 'playwright'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
|
||||
const baseUrl = 'http://127.0.0.1:5173'
|
||||
const chromePath = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
|
||||
const rootDir = process.cwd()
|
||||
const runtimeDir = path.join(rootDir, '.tmp', 'manual-four-players', String(Date.now()))
|
||||
|
||||
const players = [
|
||||
{ username: 'pwtest04', loginId: '13812345681', password: 'play123', owner: true },
|
||||
{ username: 'pwtest01', loginId: '13812345678', password: 'play123', owner: false },
|
||||
{ username: 'pwtest02', loginId: '13812345679', password: 'play123', owner: false },
|
||||
{ username: 'pwtest03', loginId: '13812345680', password: 'play123', owner: false },
|
||||
]
|
||||
|
||||
function log(message) {
|
||||
console.log(`[setup] ${message}`)
|
||||
}
|
||||
|
||||
async function launchPlayer(player) {
|
||||
const profileDir = path.join(runtimeDir, player.username)
|
||||
await fs.mkdir(profileDir, { recursive: true })
|
||||
log(`launch browser for ${player.username}`)
|
||||
|
||||
const context = await chromium.launchPersistentContext(profileDir, {
|
||||
headless: false,
|
||||
executablePath: chromePath,
|
||||
args: ['--no-first-run', '--no-default-browser-check'],
|
||||
viewport: { width: 1400, height: 960 },
|
||||
})
|
||||
|
||||
let page = context.pages()[0]
|
||||
if (!page) {
|
||||
page = await context.newPage()
|
||||
}
|
||||
await page.goto(`${baseUrl}/login`, { waitUntil: 'domcontentloaded' })
|
||||
return { ...player, context, page, profileDir }
|
||||
}
|
||||
|
||||
async function login(page, player) {
|
||||
log(`login ${player.username}`)
|
||||
await page.goto(`${baseUrl}/login`, { waitUntil: 'domcontentloaded' })
|
||||
await page.getByRole('textbox', { name: '登录ID' }).fill(player.loginId)
|
||||
await page.getByRole('textbox', { name: '密码' }).fill(player.password)
|
||||
const submitButton = page.locator('form').getByRole('button', { name: '登录' })
|
||||
await Promise.all([
|
||||
page.waitForURL('**/hall', { timeout: 15000 }),
|
||||
submitButton.click(),
|
||||
])
|
||||
await page.getByText(`用户名:${player.username}`).waitFor({ timeout: 15000 })
|
||||
log(`logged in ${player.username}`)
|
||||
}
|
||||
|
||||
async function createRoom(page) {
|
||||
const roomName = `manual-${Date.now()}`
|
||||
log(`create room ${roomName}`)
|
||||
await page.getByRole('button', { name: '创建房间' }).click()
|
||||
await page.getByRole('textbox', { name: '房间名' }).fill(roomName)
|
||||
await page.getByRole('button', { name: '创建', exact: true }).click()
|
||||
const roomText = await page.getByText(/房间ID:/).textContent()
|
||||
const roomId = roomText?.replace('房间ID:', '').trim()
|
||||
if (!roomId) {
|
||||
throw new Error('Failed to read room id')
|
||||
}
|
||||
return { roomId, roomName }
|
||||
}
|
||||
|
||||
async function ownerEnterRoom(page, roomId) {
|
||||
log(`owner enter room ${roomId}`)
|
||||
await Promise.all([
|
||||
page.waitForURL(`**/game/chengdu/${roomId}*`, { timeout: 15000 }),
|
||||
page.getByRole('button', { name: '进入房间' }).click(),
|
||||
])
|
||||
log(`owner entered room ${roomId}`)
|
||||
}
|
||||
|
||||
async function ownerStartGame(page) {
|
||||
log('owner start game')
|
||||
const startButton = page.getByRole('button', { name: '开始游戏' })
|
||||
await startButton.waitFor({ timeout: 15000 })
|
||||
await startButton.click()
|
||||
log('owner clicked start game')
|
||||
}
|
||||
|
||||
async function joinRoom(page, roomId, username) {
|
||||
log(`join room ${roomId} as ${username}`)
|
||||
await page.goto(`${baseUrl}/hall`, { waitUntil: 'domcontentloaded' })
|
||||
await page.getByRole('textbox', { name: '输入 room_id' }).fill(roomId)
|
||||
await Promise.all([
|
||||
page.waitForURL(`**/game/chengdu/${roomId}*`, { timeout: 15000 }),
|
||||
page.getByRole('button', { name: '加入' }).click(),
|
||||
])
|
||||
log(`joined room ${roomId} as ${username}`)
|
||||
}
|
||||
|
||||
async function snapshotPage(session) {
|
||||
const bodyText = ((await session.page.locator('body').textContent()) ?? '').replace(/\s+/g, ' ').trim()
|
||||
return {
|
||||
username: session.username,
|
||||
loginId: session.loginId,
|
||||
url: session.page.url(),
|
||||
started: bodyText.includes('对局中') || bodyText.includes('牌局进行中'),
|
||||
bodyPreview: bodyText.slice(0, 240),
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await fs.mkdir(runtimeDir, { recursive: true })
|
||||
log(`runtimeDir ${runtimeDir}`)
|
||||
|
||||
const sessions = []
|
||||
for (const player of players) {
|
||||
sessions.push(await launchPlayer(player))
|
||||
}
|
||||
|
||||
try {
|
||||
for (const session of sessions) {
|
||||
await login(session.page, session)
|
||||
}
|
||||
|
||||
const owner = sessions.find((session) => session.owner)
|
||||
if (!owner) {
|
||||
throw new Error('Owner session missing')
|
||||
}
|
||||
|
||||
const { roomId } = await createRoom(owner.page)
|
||||
log(`room ready ${roomId}`)
|
||||
|
||||
for (const session of sessions) {
|
||||
if (!session.owner) {
|
||||
await joinRoom(session.page, roomId, session.username)
|
||||
}
|
||||
}
|
||||
|
||||
await ownerEnterRoom(owner.page, roomId)
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||
await ownerStartGame(owner.page)
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 8000))
|
||||
|
||||
const playersSnapshot = []
|
||||
for (const session of sessions) {
|
||||
let snapshot = await snapshotPage(session)
|
||||
if (!snapshot.started) {
|
||||
log(`reload game page for ${session.username}`)
|
||||
await session.page.reload({ waitUntil: 'domcontentloaded' })
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||
snapshot = await snapshotPage(session)
|
||||
}
|
||||
playersSnapshot.push(snapshot)
|
||||
await session.page.bringToFront()
|
||||
}
|
||||
|
||||
console.log(JSON.stringify({
|
||||
roomId,
|
||||
roomUrl: `${baseUrl}/game/chengdu/${roomId}`,
|
||||
players: playersSnapshot,
|
||||
}, null, 2))
|
||||
|
||||
if (process.env.KEEP_ALIVE === '1') {
|
||||
log('setup finished; keeping browsers alive for manual testing')
|
||||
await new Promise(() => {})
|
||||
}
|
||||
|
||||
for (const session of sessions) {
|
||||
await session.context.close()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
if (process.env.KEEP_ALIVE !== '1') {
|
||||
for (const session of sessions) {
|
||||
try {
|
||||
await session.context.close()
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
await main()
|
||||
Reference in New Issue
Block a user