Skip to content
Astera Technology

Complete operations independently of animation end

Update from the operation result even when motion is disabled.

Download complete case notes and answer keys ↓

Set the decision and its input

Actual CSS disables animation for prefers-reduced-motion. The faulty handler waits for animationend, leaving a supplied completed operation processing. The repair updates from the supplied operation promise. That result can be completed, failed or unknown.

Filled local test worksheet
CaseInput JSON
Base test{"motion":"reduce","outcome":"completed"}
Download editable CSV ↓

Run the supplied comparison

The browser applies both motion preferences and executes the handlers. Labels belong to the local synthetic operation; finishing an animation is not proof of an external business success.

Faulty and required outputs
PathOutput JSON
Faulty path{"state":"processing"}
Required path{"state":"completed"}
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(!['completed','failed','unknown'].includes(i.outcome)||!['normal','reduce'].includes(i.motion))return {held:true};
    return withPage(async page=>{await page.setContent('<style>.animate{animation:pulse 10ms linear}@keyframes pulse{to{opacity:.5}}@media(prefers-reduced-motion:reduce){.animate{animation:none}}</style><div class="progress">Working</div><output id="state">processing</output>');
      await page.evaluate(({corrected,outcome})=>{const state=document.querySelector('#state');if(corrected)Promise.resolve(outcome).then(result=>state.textContent=result);else document.querySelector('.progress').addEventListener('animationend',()=>state.textContent='completed');document.querySelector('.progress').classList.add('animate');},{corrected,outcome:i.outcome});
      if(corrected||i.motion==='normal')await page.waitForFunction(()=>document.querySelector('#state').textContent!=='processing',{timeout:2000});
      return {state:await page.locator('#state').textContent()};
    },{reducedMotion:i.motion==='reduce'?'reduce':'no-preference'});
  };
const cases=[{"input":{"motion":"reduce","outcome":"completed"},"corrected":false,"expected":{"state":"processing"}},{"input":{"motion":"reduce","outcome":"completed"},"corrected":true,"expected":{"state":"completed"}},{"input":{"motion":"normal","outcome":"completed"},"corrected":true,"expected":{"state":"completed"}},{"input":{"motion":"reduce","outcome":"failed"},"corrected":true,"expected":{"state":"failed"}},{"input":{"motion":"reduce","outcome":"unknown"},"corrected":true,"expected":{"state":"unknown"}}];
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

Normal motion reaches completed for a completed result. Failed and unknown results remain distinct under reduced motion.

  1. Apply the required motion preference
  2. Receive the operation result
  3. Update the labelled state

Do not convert a failed or unknown operation into a visual success.

Editable boundary inputs and outputs
ConditionInput JSONExpected output JSON
normal-motion operation{"motion":"normal","outcome":"completed"}{"state":"completed"}
failed actual result{"motion":"reduce","outcome":"failed"}{"state":"failed"}
unknown actual result{"motion":"reduce","outcome":"unknown"}{"state":"unknown"}
Download editable CSV ↓

What drives the repaired base completion?

Show the worked answer

The supplied operation result. Animationend may be absent; it cannot be the only completion signal.

Related resources