訂判斷及所需輸入
本地草稿原是 S1、S2、S3,要 S3 在 S2 前。拖動做到,不表示鍵盤有路徑;有名稱的移上控制,讓 Enter 也成 S1、S3、S2。
| 情況 | 輸入 JSON |
|---|---|
| 原例測試 | {"method":"keyboard"} |
跑所附比較
核對真正執行瀏覽器拖放及鍵盤操作,只刻意改草稿次序,未推正式業務狀態已更改。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"order":["S1","S2","S3"],"keyboardAvailable":false} |
| 所需路徑 | {"order":["S1","S3","S2"],"keyboardAvailable":true} |
import assert from 'node:assert/strict';
import {createRequire} from 'node:module';
const htmlEscape=s=>String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
async function withPage(action,options={}){
const require=createRequire(import.meta.url);const {chromium}=require('playwright');
const browser=await chromium.launch({headless:true});
try{const context=await browser.newContext(options);const page=await context.newPage();
const requests=[];await page.route('**/*',route=>{requests.push(route.request().url());return route.abort();});
return await action(page,context,requests);
}finally{await browser.close();}
}
const run=async function run(i,corrected=true){
if(!['keyboard','pointer'].includes(i.method))return {held:true};
return withPage(async page=>{await page.setContent('<main id="list"></main>');await page.evaluate(corrected=>{
let order=['S1','S2','S3'];const render=()=>{document.querySelector('#list').innerHTML=order.map(id=>'<div id="'+id+'" draggable="true">'+id+(corrected?'<button id="up-'+id+'">Move '+id+' up</button>':'')+'</div>').join('');
for(const id of order){const row=document.getElementById(id);row.addEventListener('dragstart',e=>e.dataTransfer.setData('text/plain',id));row.addEventListener('dragover',e=>e.preventDefault());row.addEventListener('drop',e=>{e.preventDefault();const from=e.dataTransfer.getData('text/plain');order=order.filter(x=>x!==from);order.splice(order.indexOf(id),0,from);render();});
document.getElementById('up-'+id)?.addEventListener('click',()=>{const n=order.indexOf(id);if(n>0)[order[n-1],order[n]]=[order[n],order[n-1]];render();document.getElementById('up-'+id).focus();});}
};render();window.readOrder=()=>order;
},corrected);
if(i.method==='pointer')await page.dragAndDrop('#S3','#S2');else if(corrected){await page.focus('#up-S3');await page.press('#up-S3','Enter');}
return page.evaluate(()=>({order:window.readOrder(),keyboardAvailable:!!document.querySelector('#up-S3')}));});
};
const cases=[{"input":{"method":"keyboard"},"corrected":false,"expected":{"order":["S1","S2","S3"],"keyboardAvailable":false}},{"input":{"method":"keyboard"},"corrected":true,"expected":{"order":["S1","S3","S2"],"keyboardAvailable":true}},{"input":{"method":"pointer"},"corrected":true,"expected":{"order":["S1","S3","S2"],"keyboardAvailable":true}},{"input":{"method":null},"corrected":true,"expected":{"held":true}}];
for(const test of cases){const actual=await run(test.input,test.corrected);assert.deepEqual(actual,test.expected);console.log(actual);}
按邊界依據作判斷
更正兩路得同一所需次序;方法未知便停,不推已移動。
- 訂最後次序
- 各走所需路徑
- 核真正草稿次序
本地調位未證明已在其他地方儲存或發佈。
| 條件 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 拖動得到同一次序 | {"method":"pointer"} | {"order":["S1","S3","S2"],"keyboardAvailable":true} |
| 輸入方法未訂 | {"method":null} | {"held":true} |
拖動一次成功,就完成鍵盤要求嗎?
查看參考答案
不是,鍵盤控制也須把 S3 移上,成 S1、S3、S2。