2026-10-23 22:33:51 +08:00
|
|
|
/* Mock-only regression for the current source/terminal galleries and unbinding. */
|
|
|
|
|
const assert=require('assert'),fs=require('fs'),{chromium}=require('playwright');
|
|
|
|
|
(async()=>{
|
|
|
|
|
const base=process.env.FRAME_FLOW_URL;assert(base);
|
|
|
|
|
const token=process.env.FRAME_FLOW_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({extraHTTPHeaders:{Authorization:'Bearer '+token}}),errors=[];
|
|
|
|
|
page.on('pageerror',e=>errors.push(e.message));
|
|
|
|
|
await page.route('**/api/v1/auth/me',r=>r.fulfill({json:{username:'fixture',csrf_token:''}}));
|
|
|
|
|
const sources=await(await fetch(base+'/api/v1/source-libraries',{headers:{Authorization:'Bearer '+token}})).json();assert(sources.length);
|
2026-10-23 22:57:53 +08:00
|
|
|
const sourceId=sources[0].id,planId='a'.repeat(32);let bound=true,deletions=0,current=true;
|
2026-10-23 23:10:50 +08:00
|
|
|
let plan={id:planId,name:'Fixture frame',source_id:sourceId,width:1600,height:1200,quality:85,fit:'cover',center_x:0.5,center_y:0.5,caption:true,profile:'color'};
|
|
|
|
|
const version=()=>({asset_id:'fixture-version',source_image_id:'fixture-source',plan_id:planId,name:'Fixture-'+plan.name+'.jpg',stored_name:'Fixture-original.jpg',plan_name:plan.name,matches_current_plan:true,url:'/ui/logo-symbol.svg',created_at:'2026-10-23',plan:{...plan,name:'Original snapshot'},terminal_uses:[],delivery_status:'COMPLETED'});
|
|
|
|
|
await page.route('**/api/v1/library-terminals',r=>r.fulfill({json:[{id:'living-room',name:'Authoritative frame',kind:'frame',transport_supported:true,binding:bound?{source_id:sourceId,plan_id:planId}:null},{id:'watch',kind:'watch',transport_supported:false}]}));
|
|
|
|
|
await page.route('**/api/v1/generation-plans?*',r=>r.fulfill({json:[plan]}));
|
|
|
|
|
await page.route('**/api/v1/generation-plans/'+planId,r=>{assert.equal(r.request().method(),'PUT');plan={...plan,...r.request().postDataJSON()};return r.fulfill({json:plan});});
|
|
|
|
|
await page.route('**/api/v1/source-libraries/'+sourceId+'/images?*',r=>r.fulfill({json:{total:1,items:[{id:'fixture-source',name:'Fixture.jpg',url:'/ui/logo-symbol.svg',created_at:'2026-10-23',versions:[version()]}]}}));
|
|
|
|
|
await page.route('**/api/v1/library-terminals/*/images?*',r=>r.fulfill({json:{total:1,items:[{...version(),current:current&&!r.request().url().includes('/watch/')}]}}));
|
2026-10-23 22:33:51 +08:00
|
|
|
await page.route('**/api/v1/library-terminals/living-room/binding',r=>{assert.equal(r.request().method(),'DELETE');deletions++;bound=false;return r.fulfill({json:{}});});
|
|
|
|
|
await page.route('**/api/v1/source-libraries/*/browse?*',r=>r.fulfill({json:{items:[],next_offset:null,scanned:0,paged_provider:true}}));
|
|
|
|
|
await page.goto(base+'/#gallery');await page.locator('#library-new-plan').waitFor();
|
|
|
|
|
assert.equal(await page.locator('#library-legacy,#library-old-terminal,[data-page="legacy-gallery"],[data-page="legacy-plans"]').count(),0);
|
|
|
|
|
await page.locator('#library-new-plan').click();await page.locator('#generation-form').waitFor();assert.equal(await page.locator('#generation-legacy').count(),0);await page.locator('[data-generation-preset="watch"]').click();assert.equal(await page.locator('#generation-width').inputValue(),'410');await page.locator('#modal-cancel').click();
|
2026-10-23 23:10:50 +08:00
|
|
|
await page.locator('[data-library-plan="'+planId+'"]').click();await page.locator('#library-edit-plan').click();await page.locator('#generation-name').fill('Renamed frame');await page.locator('#generation-form button[type=submit]').click();await page.locator('[data-library-plan="'+planId+'"]').filter({hasText:'Renamed frame'}).waitFor();assert((await page.locator('.source-library-gallery').innerText()).includes('Renamed frame'));
|
|
|
|
|
await page.locator('[data-page="terminal-gallery"]').click();await page.locator('#library-unbind').waitFor();assert.equal(await page.locator('[data-library-terminal="living-room"]').innerText(),'Authoritative frame');assert.equal(await page.locator('#device option:checked').innerText(),'Authoritative frame');assert.equal(await page.locator('.terminal-library-gallery h3').innerText(),'Fixture-Renamed frame.jpg');assert((await page.locator('.terminal-library-gallery').innerText()).includes('Renamed frame'));await page.locator('[data-terminal-settings="0"]').click();assert.equal(await page.locator('#modal-content h2').innerText(),'Renamed frame');assert((await page.locator('#modal-content').innerText()).includes('Original snapshot'));await page.locator('#modal-cancel').click();
|
2026-10-23 22:57:53 +08:00
|
|
|
const send=page.locator('[data-terminal-send="0"]');assert(await send.isDisabled());assert.equal(await send.innerText(),'已在终端显示');
|
|
|
|
|
current=false;await page.locator('#library-refresh').click();await page.waitForFunction(()=>document.querySelector('[data-terminal-send="0"]')?.disabled===false);assert.equal(await send.innerText(),'推送到终端');
|
2026-10-23 22:33:51 +08:00
|
|
|
await page.locator('#library-unbind').click();await page.locator('dialog[open]').waitFor();assert.equal(deletions,0);assert((await page.locator('#modal-content').innerText()).includes('来源图库'));await page.locator('#modal-cancel').click();assert.equal(deletions,0);
|
|
|
|
|
await page.locator('#library-unbind').click();await page.locator('#modal-confirm').click();await page.waitForFunction(()=>!document.querySelector('#library-unbind'));assert.equal(deletions,1);
|
|
|
|
|
for(const width of [1440,390]){await page.setViewportSize({width,height:900});await page.locator('[data-library-terminal="watch"]').click();await page.locator('[data-library-terminal="watch"][aria-pressed=true]').waitFor();assert(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth));await page.locator('[data-library-terminal="living-room"]').click();}
|
|
|
|
|
await page.locator('[data-page="photo-sources"]').click();await page.locator('[data-source-browse]').first().click();await page.locator('#source-browser-filters').waitFor();assert(page.url().endsWith('#source-browser'));
|
|
|
|
|
await page.locator('[data-page="automation"]').click();await page.locator('#new-job').click();await page.locator('#job-library-pipeline').waitFor({state:'attached'});await page.locator('#job-content-type').selectOption('photo_source');await page.locator('#job-library-pipeline').waitFor();assert(await page.locator('#legacy-thumbnail-job-fields').isHidden());await page.locator('#modal-cancel').click();
|
|
|
|
|
const oldPlanId='b'.repeat(32);
|
|
|
|
|
await page.route('**/api/v1/thumbnail-plans',r=>r.fulfill({json:[{id:oldPlanId,name:'Existing task plan',width:410,height:502}]}));
|
|
|
|
|
await page.evaluate(async ({sourceId,oldPlanId})=>jobEditor({id:'fixture-job',name:'Existing task',device_id:'living-room',enabled:false,schedule:{type:'daily',time:'08:00'},source:{type:'photo_source',source_id:sourceId,fit:'contain',profile:'color'},display_duration:0,restore_previous:false,priority:50,generate_thumbnail:true,thumbnail_plan_id:oldPlanId}),{sourceId,oldPlanId});
|
|
|
|
|
assert(await page.locator('#legacy-thumbnail-job-fields').isVisible());assert(await page.locator('#job-thumbnail').isChecked());assert.equal(await page.locator('#job-thumbnail-plan').inputValue(),oldPlanId);await page.locator('#modal-cancel').click();
|
|
|
|
|
assert.deepEqual(errors,[]);console.log('Current galleries, retired entries, generation presets, unbind confirmation, source browser, task editor and responsive layout passed');
|
|
|
|
|
}finally{await browser.close();}
|
|
|
|
|
})();
|