訂判斷及所需輸入
題內可見範圍390×300。固定框用 overflow clip,Calculate 在下方被藏。可捲動更正讓焦點到按鈕,再回輸入欄;兩步都要做到,整頁高度未證明框內能到達。
| 情況 | 輸入 JSON |
|---|---|
| 原例測試 | {"height":300} |
跑所附比較
瀏覽器真正轉焦點後,核控制欄位置。縮小範圍是題內測試幾何,不表示已開真設備鍵盤。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"buttonReachable":false,"fieldRecoverable":true} |
| 所需路徑 | {"buttonReachable":true,"fieldRecoverable":true} |
import assert from 'node:assert/strict';
const smallWhole=(x,max)=>Number.isSafeInteger(x)&&x>=0&&x<=max;
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(!smallWhole(i.height,800)||i.height<200)return {held:true};
return withPage(async page=>{await page.setContent('<style>body{margin:0;overflow:hidden}.frame{position:fixed;inset:0;overflow:'+(corrected?'auto':'clip')+'}.space{height:650px}</style><form class="frame"><label>Memo<input id="field"></label><div class="space"></div><button type="button" id="calculate">Calculate</button></form>');
await page.focus('#calculate');const buttonReachable=await page.evaluate(()=>{const r=document.querySelector('#calculate').getBoundingClientRect();return r.top>=0&&r.bottom<=innerHeight;});
await page.focus('#field');const fieldRecoverable=await page.evaluate(()=>{const r=document.querySelector('#field').getBoundingClientRect();return r.top>=0&&r.bottom<=innerHeight;});return {buttonReachable,fieldRecoverable};
},{viewport:{width:390,height:i.height}});
};
const cases=[{"input":{"height":300},"corrected":false,"expected":{"buttonReachable":false,"fieldRecoverable":true}},{"input":{"height":300},"corrected":true,"expected":{"buttonReachable":true,"fieldRecoverable":true}},{"input":{"height":240},"corrected":true,"expected":{"buttonReachable":true,"fieldRecoverable":true}},{"input":{"height":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);}
按邊界依據作判斷
高240 像素邊界也保同一路徑;可見高度欠缺便停,不自行猜。
- 沿所附可見範圍
- 焦點到必要動作
- 再回輸入欄
手機可見範圍資料欠缺,先補觀察才判可否使用。
| 條件 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 較細的可見範圍 | {"height":240} | {"buttonReachable":true,"fieldRecoverable":true} |
| 可見範圍未知 | {"height":null} | {"held":true} |
原例更正後須看到甚麼?
查看參考答案
焦點到 Calculate 後看得到,之後可回輸入欄;藏在框外的動作不符合任務。