SOURCE / PINNED RELEASE
Made of little things.
Funclet
- Release
- 0b497cfc2f66…
- Author-recorded commit
- 1e531b24f490…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-6b7a37cac1d
Archive hash verified: 71d97a89ed8c40c2…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// Read-only live smoke test. Start soyli dev and pass its printed URL.
import assert from 'node:assert/strict';
import { realpathSync, mkdirSync, writeFileSync } from 'node:fs';
import { createRequire } from 'node:module';
import { execFileSync } from 'node:child_process';
const url=process.argv[2];
assert.ok(url?.startsWith('http://127.0.0.1:'),'Pass the owned soyli dev loopback URL');
const require=createRequire(`${realpathSync('node_modules/@napplet/conformance-cli')}/package.json`);
const {chromium}=require('playwright');
const executables=JSON.parse(execFileSync('soyli',['browser','path','--json'],{encoding:'utf8'})).executables;
const browser=await chromium.launch({executablePath:executables.find(x=>x.installed&&x.name.startsWith('chromium')).path});
mkdirSync('.napplet-space/testing',{recursive:true});
try {
const page=await browser.newPage({viewport:{width:1220,height:950},hasTouch:true});
const errors=[];page.on('pageerror',e=>errors.push(e.message));
await page.goto(url);
const frame=page.frameLocator('iframe').first();
await frame.locator('.station-row').first().waitFor({timeout:20000});
const domains=await frame.locator('body').evaluate(()=>Object.keys(window.napplet));
await frame.locator('#search').fill('Radio Paradise');
await frame.locator('#search-submit').tap();
await frame.locator('#results[aria-busy="false"]').waitFor({timeout:20000});
assert.match(await frame.locator('#results-title').textContent(),/Station search/i);
assert.match(await frame.locator('#results').innerText(),/Radio Paradise/i);
console.log('PASS: live station search');
await frame.locator('#search').fill('Omarchy');await frame.locator('#search').press('Enter');
await frame.getByRole('button',{name:'Listen to Omarchy Radio',exact:true}).waitFor({timeout:20000});
await frame.getByRole('button',{name:'Listen to Omarchy Radio',exact:true}).tap();
await frame.locator('#playback-label').filter({hasText:'ON AIR'}).waitFor({timeout:20000});
// Explicitly authorize the read-only Wavefunc connection requested by this test.
const approvalButton=page.getByRole('button',{name:'Connect',exact:true});
await approvalButton.waitFor({timeout:15000});await approvalButton.click();
const app=page.frames().find(f=>f.url()==='about:srcdoc');
await app.waitForFunction(()=>{const title=document.querySelector('#player-title').textContent;return title&&title!=='Omarchy Radio';},{},{timeout:30000});
const track=await frame.locator('.receiver').innerText();
console.log('PASS: live playback and CVM metadata:',track.replaceAll('\n',' · '));
await frame.locator('#volume').fill('35');await frame.locator('#volume').dispatchEvent('input');
await page.waitForTimeout(500);assert.equal(await frame.locator('#volume').inputValue(),'35');
await frame.locator('#volume').hover();await page.mouse.wheel(0,-100);
await app.waitForFunction(()=>document.querySelector('#volume').value==='40');
await page.mouse.wheel(0,100);
await app.waitForFunction(()=>document.querySelector('#volume').value==='35');
console.log('PASS: native mouse wheel volume commands');
await frame.getByRole('button',{name:'Pause radio',exact:true}).tap();
await frame.locator('#playback-label').filter({hasText:'PAUSED'}).waitFor();
await frame.getByRole('button',{name:'Play radio',exact:true}).tap();
await frame.locator('#playback-label').filter({hasText:'ON AIR'}).waitFor();
console.log('PASS: pause, resume, volume');
await frame.locator('#search').fill('');await frame.locator('#search-submit').tap();
await frame.locator('#results[aria-busy="false"]').waitFor({timeout:20000});
assert.ok(await frame.locator('.station-row').count()>1);
assert.equal(await frame.locator('#receiver-stage').getAttribute('data-renderer'),'webgl');
const dimensions=[];
for(const theme of ['light','dark']) {
await page.emulateMedia({colorScheme:theme});
for(const [width,height] of [[200,160],[320,560],[900,600],[1440,900],[390,844],[360,640],[844,390]]) {
await page.setViewportSize({width:Math.max(width+20,400),height:height+220});
// Override only the manager's iframe geometry; do not alter app layout.
await page.locator('iframe').first().evaluate((el,size)=>{el.style.width=`${size[0]}px`;el.style.height=`${size[1]}px`;el.style.minHeight='0';el.style.flex='none';},[width,height]);
const actual=await app.evaluate(()=>({width:innerWidth,height:innerHeight,overflow:document.documentElement.scrollWidth>innerWidth,bg:getComputedStyle(document.documentElement).backgroundColor}));
assert.equal(actual.width,width);assert.equal(actual.height,height);assert.equal(actual.overflow,false);assert.equal(actual.bg,'rgb(254, 249, 234)');
if(width===200)await frame.locator('#mini-play').waitFor();else await frame.locator('#play-toggle').waitFor();
dimensions.push({theme,...actual});
await page.locator('iframe').first().screenshot({path:`.napplet-space/testing/live-${width}x${height}-${theme}.png`});
}
}
await page.setViewportSize({width:1220,height:970});
await page.locator('iframe').first().evaluate(el=>{el.style.width='1200px';el.style.height='750px';});
await page.locator('iframe').first().screenshot({path:'.napplet-space/testing/live-cover.png'});
await frame.getByRole('button',{name:'Pause radio',exact:true}).tap();
await frame.locator('#search').fill('Nina Simone');await frame.locator('#search-mode').selectOption('artists');
await frame.locator('.music-row').first().waitFor({timeout:30000});
assert.match(await frame.locator('#results').innerText(),/Nina Simone/);
console.log('PASS: live CVM artist search');
await frame.locator('#favourites-tab').tap();
await frame.getByRole('heading',{name:'Bring your favourites along.'}).waitFor();
console.log('PASS: signed-out favourites');
await frame.locator('#settings').click();
await page.getByText('Station artwork',{exact:true}).waitFor({timeout:5000});
const settingsText=await page.locator('body').innerText();
assert.match(settingsText,/Station artwork/);assert.match(settingsText,/Now playing refresh/);
console.log('PASS: host settings schema');
await page.reload();
await frame.locator('#playback-label').filter({hasText:'ON AIR'}).waitFor({timeout:30000});
const restoredApp=page.frames().find(f=>f.url()==='about:srcdoc');
await restoredApp.waitForFunction(()=>document.querySelector('#volume').value==='35');
assert.match(await frame.locator('.detail-name').textContent(),/Omarchy Radio/);
console.log('PASS: station and volume resume after a real host reload');
assert.deepEqual(errors,[]);
writeFileSync('.napplet-space/testing/host-report.json',JSON.stringify({passed:true,domains,track,dimensions,errors},null,2));
console.log('PASS: all hosted checks; geometry/theme evidence in .napplet-space/testing/host-report.json');
} finally {await browser.close();}
