45 lines
6.2 KiB
JavaScript
45 lines
6.2 KiB
JavaScript
/* Mock-only: known image metadata renders real slots; no synthetic skeletons. */
|
|||
|
|
const assert=require('assert'),fs=require('fs'),{chromium}=require('playwright');
|
||
|
|
(async()=>{
|
||
|
|
const base=process.env.FRAME_FLOW_URL;assert(base);
|
||
|
|
const token=fs.readFileSync(process.env.FRAME_FLOW_ENV_FILE,'utf8').split('\n').find(x=>x.startsWith('FRAME_FLOW_TOKEN=')).slice(17);
|
||
|
|
assert((await(await fetch(base+'/api/v1/settings',{headers:{Authorization:'Bearer '+token}})).json()).mock===true);
|
||
|
|
const browser=await chromium.launch({headless:true,executablePath:process.env.CHROME_EXECUTABLE||'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'});
|
||
|
|
try{
|
||
|
|
const page=await browser.newPage();const errors=[];page.on('pageerror',e=>errors.push(e.message));
|
||
|
|
let releaseAccount;await page.route('**/api/v1/auth/me',async r=>{await new Promise(resolve=>releaseAccount=resolve);await r.continue();});
|
||
|
|
await page.goto(base);await page.locator('#nav button').first().waitFor();assert.equal(await page.locator('.image-pending,.placeholder-line,.page-placeholder').count(),0);assert.equal(await page.locator('.page-loading').count(),0);releaseAccount();
|
||
|
|
await page.locator('#username').fill(process.env.FRAME_FLOW_TEST_USERNAME);await page.locator('#password').fill(process.env.FRAME_FLOW_TEST_PASSWORD);await page.locator('#login-form button').click();await page.locator('.hero').waitFor();
|
||
|
|
let checks=1;
|
||
|
|
for(const width of [1440,390]){
|
||
|
|
await page.setViewportSize({width,height:844});await page.evaluate(()=>state.galleryCache?.clear());let releaseMetadata,metadataRequested,releaseImage,imageRequested;
|
||
|
|
await page.route('**/api/v1/devices/*/images',async r=>{metadataRequested();await new Promise(resolve=>releaseMetadata=resolve);await r.fulfill({json:[{image_id:1,name:'Progressive fixture',url:'/progressive-fixture.svg',current:false}]});});
|
||
|
|
await page.route('**/progressive-fixture.svg*',async r=>{assert.equal(await page.locator('#gallery-search').count(),1,'Search must precede image requests');assert(await page.locator('#gallery-search').evaluate(e=>typeof e.oninput==='function'));imageRequested();await new Promise(resolve=>releaseImage=resolve);await r.fulfill({contentType:'image/svg+xml',body:'<svg xmlns="http://www.w3.org/2000/svg" width="300" height="400"/>'});});
|
||
|
|
const metadata=new Promise(resolve=>metadataRequested=resolve);const image=new Promise(resolve=>imageRequested=resolve);
|
||
|
|
await page.evaluate(()=>{window.navigation=navigate('gallery');});await metadata;
|
||
|
|
assert.equal(await page.locator('.image-pending,.placeholder-line,.page-placeholder').count(),0);assert.equal(await page.locator('.image-card').count(),0);assert.equal(await page.locator('.page-loading').count(),0);checks++;
|
||
|
|
releaseMetadata();await image;await page.evaluate(()=>window.navigation);
|
||
|
|
assert(await page.locator('#gallery-upload').isEnabled());assert.equal(await page.locator('.image-loading .spinner').count(),1);assert.equal(await page.locator('.image-pending').count(),0);checks++;
|
||
|
|
assert(await page.locator('.image-loading').evaluate(box=>{const a=box.getBoundingClientRect(),b=box.querySelector('.spinner').getBoundingClientRect();return Math.abs(a.x+a.width/2-b.x-b.width/2)<1&&Math.abs(a.y+a.height/2-b.y-b.height/2)<1;}));checks++;
|
||
|
|
releaseImage();await page.waitForFunction(()=>document.querySelector('.thumb')?.naturalWidth===300&&!document.querySelector('.image-loading'));checks++;
|
||
|
|
await page.evaluate(()=>navigate('upload'));
|
||
|
|
const cachedMetadata=new Promise(resolve=>metadataRequested=resolve);const cachedImage=new Promise(resolve=>imageRequested=resolve);
|
||
|
|
await page.evaluate(()=>{window.navigation=navigate('gallery');});await cachedMetadata;await cachedImage;
|
||
|
|
assert.equal(await page.locator('#gallery-search').count(),1,'Search must exist while cached metadata refresh is pending');assert(await page.locator('#gallery-search').evaluate(e=>typeof e.oninput==='function'),'Search must be interactive');assert.equal(await page.locator('.image-card').count(),1);assert.equal(await page.locator('.image-loading .spinner').count(),1);assert.equal(await page.locator('.image-pending,.placeholder-line,.page-placeholder').count(),0);checks++;
|
||
|
|
releaseMetadata();await page.evaluate(()=>window.navigation);releaseImage();await page.waitForFunction(()=>document.querySelector('.thumb')?.naturalWidth===300&&!document.querySelector('.image-loading'));
|
||
|
|
|
||
|
|
await page.unroute('**/api/v1/devices/*/images');await page.unroute('**/progressive-fixture.svg*');
|
||
|
|
let releaseDevice,deviceRequested;await page.route('**/api/v1/devices/living-room',async r=>{deviceRequested();await new Promise(resolve=>releaseDevice=resolve);await r.continue();});
|
||
|
|
const device=new Promise(resolve=>deviceRequested=resolve);await page.evaluate(()=>{window.navigation=navigate('dashboard');});await device;
|
||
|
|
assert.equal(await page.locator('.image-pending,.placeholder-line,.page-placeholder').count(),0);assert.equal(await page.locator('.page-loading').count(),0);checks++;
|
||
|
|
releaseDevice();await page.evaluate(()=>window.navigation);await page.unroute('**/api/v1/devices/living-room');
|
||
|
|
}
|
||
|
|
let releaseJobs,jobsRequested;await page.route('**/api/v1/jobs',async r=>{jobsRequested();await new Promise(resolve=>releaseJobs=resolve);await r.fulfill({json:[]});});
|
||
|
|
await page.route('**/api/v1/assets?*',r=>r.fulfill({json:[{asset_id:'local-fixture',name:'Local fixture',url:'/local-fixture.svg',origin:'manual',starred:false}]}));
|
||
|
|
await page.route('**/local-fixture.svg',r=>r.fulfill({contentType:'image/svg+xml',body:'<svg xmlns="http://www.w3.org/2000/svg" width="300" height="400"/>'}));
|
||
|
|
const jobs=new Promise(resolve=>jobsRequested=resolve);await page.evaluate(()=>{state.tab='local';return navigate('gallery');});await jobs;
|
||
|
|
assert.equal(await page.locator('.asset-select').count(),1);assert(await page.locator('#gallery-search').evaluate(e=>typeof e.oninput==='function'));await page.locator('#gallery-search').fill('no-match');assert(await page.locator('.image-card').evaluate(e=>e.hidden));releaseJobs();checks++;
|
||
|
|
assert.deepEqual(errors,[]);console.log('Known image positions without skeletons:',checks,'checks PASS; delayed bootstrap, metadata and images; no page errors');
|
||
|
|
}finally{await browser.close();}
|
||
|
|
})().catch(e=>{console.error(e.message);process.exit(1)});
|