15 lines
4.8 KiB
JavaScript
15 lines
4.8 KiB
JavaScript
import {setDifficulty,startJourney} from './helpers.mjs';import {chromium} from 'playwright';import assert from 'node:assert/strict';import fs from 'node:fs';
|
|
const browser=await chromium.launch({executablePath:'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',headless:true});
|
|
const context=await browser.newContext({viewport:{width:390,height:844},isMobile:true,hasTouch:true,deviceScaleFactor:2});const p=await context.newPage(),errors=[];p.on('pageerror',e=>errors.push(e.message));await p.goto('http://localhost:4173');await setDifficulty(p,{snap:0,bounce:3});assert.deepEqual(await p.locator('#modal [data-snap]').evaluateAll(bs=>bs.map(b=>b.getAttribute('data-snap'))),['0','1','2']);assert.deepEqual(await p.locator('#modal [data-bounce]').evaluateAll(bs=>bs.map(b=>b.getAttribute('data-bounce'))),['0','1','3','2']);await p.clock.install();await startJourney(p);
|
|
const state=()=>p.evaluate(()=>shanheDebug.state()),cdp=await context.newCDPSession(p);const touch=(type,x,y)=>cdp.send('Input.dispatchTouchEvent',{type,touchPoints:x===undefined?[]:[{id:1,x,y}]});
|
|
let box=await p.locator('#board').boundingBox();let start=await state();assert.equal(start.dropped,0);assert.equal(start.groups,0);assert.equal(start.pending.remaining,null);assert.ok(start.pending.bottom<start.dangerY);assert.ok((await p.locator('#drop-countdown').textContent()).includes('∞'));await p.clock.runFor(30000);assert.equal((await state()).dropped,0);
|
|
const y=box.y+30;await touch('touchStart',box.x+start.pending.x,y);await touch('touchMove',box.x+start.pending.x+60,y);await p.clock.runFor(50);const aimed=await state();assert.ok(aimed.pending.x>start.pending.x);assert.ok(aimed.aiming);assert.equal(aimed.dropped,0);assert.equal(aimed.shakeCount,0);await p.screenshot({path:'artifacts/manual-prepared.png'});await touch('touchEnd');const released=await state();assert.equal(released.dropped,1);assert.equal(released.groups,1);assert.notEqual(released.pending.serial,start.pending.serial);assert.equal(released.shakeCount,0);
|
|
// System cancellation and a pause while dragging never drop in manual mode.
|
|
box=await p.locator('#board').boundingBox();let n=await state();await touch('touchStart',box.x+n.pending.x,box.y+30);await touch('touchMove',box.x+n.pending.x-40,box.y+30);await touch('touchCancel');assert.equal((await state()).dropped,1);assert.equal((await state()).aiming,false);
|
|
n=await state();await touch('touchStart',box.x+n.pending.x,box.y+30);await p.keyboard.press(' ');const paused=await state();assert.equal(paused.status,'paused');await touch('touchEnd');await p.clock.runFor(10000);assert.equal((await state()).dropped,1);assert.equal((await state()).elapsed,paused.elapsed);await p.getByRole('button',{name:'继续游戏',exact:true}).tap();assert.equal((await state()).dropped,1);await p.locator('#board').focus();await p.keyboard.press('Enter');assert.equal((await state()).dropped,2);await p.locator('#pause').tap();await p.getByRole('button',{name:'结束旅程',exact:true}).tap();assert.equal((await state()).result.bounceName,'元气弹跳');assert.equal((await state()).result.speedName,'随心落子');assert.equal((await state()).result.snapName,'轻松拼');await p.screenshot({path:'artifacts/manual-result.png'});
|
|
// Restart and replay always require confirmation; cancelling preserves the result.
|
|
await p.locator('#replay').tap();assert.equal((await state()).screen,'result');await p.locator('[data-snap="2"]').tap();await p.getByRole('button',{name:'取消',exact:true}).tap();assert.equal((await state()).result.snapName,'轻松拼');
|
|
await p.locator('#replay').tap();await p.locator('[data-snap="2"]').tap();await p.locator('#confirm-journey').tap();assert.equal((await state()).snap,2);assert.equal((await state()).speed,4);await p.clock.runFor(30000);assert.equal((await state()).dropped,0);
|
|
await p.locator('#board').press('Enter');await p.locator('#pause').tap();const preserved=await state();await p.getByRole('button',{name:'重新开局',exact:true}).tap();await p.locator('[data-snap="1"]').tap();await p.getByRole('button',{name:'取消',exact:true}).tap();assert.equal((await state()).status,'paused');assert.equal((await state()).dropped,preserved.dropped);assert.equal((await state()).snap,2);await p.getByRole('button',{name:'继续游戏',exact:true}).tap();assert.equal((await state()).status,'playing');
|
|
assert.deepEqual(errors,[]);fs.writeFileSync('artifacts/staging-report.json',JSON.stringify({passed:true,scope:'CDP touch in modern Chrome; real container validation pending',results:['开局确认三档吸附与四档弹性,无速度选项','待落块在红线上方,等待30秒不自动落','横向调整松手一次释放,取消/暂停不误放','Enter辅助释放、成绩包含吸附难度和弹性','重开与再玩必须确认,取消保留原局或成绩'],errors},null,2));console.log('随心落子、吸附难度和强制开局确认流程通过');await browser.close();
|