Unify transport controls with themed SVG symbols and accessible playback states
This commit is contained in:
40
frontend/transport-icons.test.js
Normal file
40
frontend/transport-icons.test.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const {test}=require('node:test');
|
||||
const assert=require('node:assert/strict');
|
||||
const {readFileSync,readdirSync}=require('node:fs');
|
||||
const {join}=require('node:path');
|
||||
const vm=require('node:vm');
|
||||
const {transport}=require('./download-actions');
|
||||
test('transport symbols cover all actions and layouts with monochrome SVG',()=>{
|
||||
for(const kind of ['play','pause','previous','next','back10','forward10','back15','forward']){
|
||||
assert.match(transport.svg(kind),new RegExp(`href="#transport-${kind}"`));
|
||||
assert.match(transport.svg(kind),/stroke="currentColor"/);
|
||||
for(const layout of ['classic','f7-swipe','glass-stage','bento-hub'])assert.ok(transport.variants[layout][kind]);
|
||||
}
|
||||
assert.throws(()=>transport.svg('unknown'),/Unknown transport/);
|
||||
});
|
||||
test('playback UI swaps shared symbols and accessible names without changing handlers',()=>{
|
||||
const buttons=Object.fromEntries(['playBtn','stgPlay','miniPlayBtn','servicePlayBtn'].map(id=>[id,{onclick:()=>id,setAttribute(k,v){this[k]=v;}}]));
|
||||
const handlers=Object.values(buttons).map(b=>b.onclick);let changes=0;
|
||||
const Player={master:{paused:true}},classes=[];
|
||||
const app=readFileSync(join(__dirname,'app.js'),'utf8');
|
||||
const body=app.slice(app.indexOf('function updatePlayBtn() {'),app.indexOf('// "⚠ Broken"'));
|
||||
const sandbox={Player,TransportIcons:transport,Remote:{changed(){changes++;}},$:id=>buttons[id],document:{querySelector:()=>({classList:{toggle:(...args)=>classes.push(args)}})}};
|
||||
vm.runInNewContext(body,sandbox);
|
||||
for(const paused of [true,false,true]){
|
||||
Player.master.paused=paused;sandbox.updatePlayBtn();
|
||||
for(const b of Object.values(buttons)){assert.match(b.innerHTML,new RegExp(`#transport-${paused?'play':'pause'}`));assert.equal(b['aria-label'],paused?'Play':'Pause');}
|
||||
}
|
||||
assert.equal(changes,3);assert.deepEqual(Object.values(buttons).map(b=>b.onclick),handlers);
|
||||
assert.deepEqual(classes,[['is-paused',true],['is-paused',false],['is-paused',true]]);
|
||||
});
|
||||
test('runtime sources never render legacy transport glyphs',()=>{
|
||||
const failures=[];
|
||||
for(const file of readdirSync(__dirname).filter(f=>/\.(js|html|css)$/.test(f)&&!f.endsWith('.test.js'))){
|
||||
readFileSync(join(__dirname,file),'utf8').split('\n').forEach((line,i)=>{
|
||||
// Legacy input decoder accepts old labels; its output uses shared symbols.
|
||||
if(file==='glass-controls.js'&&line.startsWith(' const glyphs = '))return;
|
||||
if(/[▶⏸⏮⏭⏪⏩⏯◀❚]/u.test(line))failures.push(`${file}:${i+1}`);
|
||||
});
|
||||
}
|
||||
assert.deepEqual(failures,[]);
|
||||
});
|
||||
Reference in New Issue
Block a user