Skip to content
Astera Technology

Reorder a draft with drag and keyboard controls

Exercise the same meaningful final order through both input methods.

Download complete case notes and answer keys ↓

Set the decision and its input

The local draft starts S1,S2,S3 and requires S3 before S2. Dragging can achieve this, but a drag-only interface offers no keyboard action. Labelled move-up controls let keyboard Enter produce the same S1,S3,S2 order.

Filled local test worksheet
CaseInput JSON
Base test{"method":"keyboard"}
Download editable CSV ↓

Run the supplied comparison

The proof executes browser drag/drop and keyboard actions. It deliberately changes a meaningful draft sequence; no published business-state change is inferred.

Faulty and required outputs
PathOutput JSON
Faulty path{"order":["S1","S2","S3"],"keyboardAvailable":false}
Required path{"order":["S1","S3","S2"],"keyboardAvailable":true}
Download editable CSV ↓
Node24.14.1 programme; Playwright1.63 Chromium required
import assert from 'node:assert/strict';
import {createRequire} from 'node:module';
const htmlEscape=s=>String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
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);}
Download runnable example ↓

Choose from the boundary evidence

Both repaired paths produce the same required order. Unknown method is held without inventing a move.

  1. State the target order
  2. Operate both required paths
  3. Read the actual draft order

A local reorder is not evidence of saving or publishing elsewhere.

Editable boundary inputs and outputs
ConditionInput JSONExpected output JSON
pointer path has same order{"method":"pointer"}{"order":["S1","S3","S2"],"keyboardAvailable":true}
method not supplied{"method":null}{"held":true}
Download editable CSV ↓

Does one successful pointer drag complete the keyboard requirement?

Show the worked answer

No. The keyboard control must separately move S3 up to produce S1,S3,S2.

Related resources