33 lines
5.6 KiB
JavaScript
33 lines
5.6 KiB
JavaScript
/* Mock-only editor regression: parallel image requests, stable regions and live controls. */
|
|
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));
|
|
await page.route('**/api/v1/assets?*',r=>r.fulfill({json:[{asset_id:'studio-fixture-a',name:'A'},{asset_id:'studio-fixture-b',name:'B'}]}));
|
|
await page.route('**/api/v1/layout/plan',r=>r.fulfill({json:{width:1200,height:1600,regions:[{asset_id:'studio-fixture-a',x:20,y:200,width:550,height:900},{asset_id:'studio-fixture-b',x:620,y:200,width:550,height:900}]}}));
|
|
let requests,releases,failSecond=false;
|
|
await page.route('**/api/v1/assets/studio-fixture-*',async r=>{const key=r.request().url().split('-').pop();requests.add(key);await new Promise(resolve=>releases[key]=resolve);await r.fulfill({contentType:'image/svg+xml',body:failSecond&&key==='b'?'invalid image':'<svg xmlns="http://www.w3.org/2000/svg" width="300" height="400"><rect width="300" height="400" fill="#167253"/></svg>'});});
|
|
await page.goto(base);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=0;
|
|
for(const width of [1440,390])for(const theme of ['light','dark']){
|
|
requests=new Set();releases={};await page.setViewportSize({width,height:900});await page.evaluate(theme=>{document.documentElement.dataset.theme=theme;return navigate('studio');},theme);await page.locator('.manual-collage summary').click();
|
|
await page.locator('#studio-assets input').nth(0).check();await page.locator('#studio-assets input').nth(1).check();await page.locator('#studio-plan').click();
|
|
await page.waitForFunction(()=>document.querySelectorAll('.studio-region .spinner').length===2);for(let n=0;n<100&&requests.size<2;n++)await page.waitForTimeout(20);assert.equal(requests.size,2,'Both requests must start before either finishes');assert(await page.locator('#studio-render').isEnabled());checks++;
|
|
assert(await page.locator('.studio-region').evaluateAll(regions=>regions.every(region=>{const a=region.getBoundingClientRect(),b=region.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++;
|
|
const field=page.locator('[data-region="0"][data-key="x"]');await field.fill('40');await field.dispatchEvent('input');assert(await page.locator('.studio-region').first().evaluate(e=>Math.abs(parseFloat(e.style.left)-40/1200*100)<0.01));checks++;
|
|
const before=await page.locator('.studio-region').nth(1).boundingBox();releases.b();await page.waitForFunction(()=>document.querySelectorAll('.studio-region')[1].querySelector('img').naturalWidth===300&&!document.querySelectorAll('.studio-region')[1].querySelector('.image-loading'));
|
|
assert.equal(await page.locator('.studio-region').first().locator('.spinner').count(),1);assert.deepEqual(await page.locator('.studio-region').nth(1).boundingBox(),before);checks++;
|
|
const region=page.locator('.studio-region').nth(1);await region.scrollIntoViewIfNeeded();const point=await region.boundingBox();const old=await page.locator('[data-region="1"][data-key="x"]').inputValue();await page.mouse.move(point.x+point.width/2,point.y+Math.min(point.height/2,80));await page.mouse.down();await page.mouse.move(point.x+point.width/2-10,point.y+Math.min(point.height/2,80)+5,{steps:3});await page.mouse.up();assert.notEqual(await page.locator('[data-region="1"][data-key="x"]').inputValue(),old);checks++;
|
|
releases.a();await page.waitForFunction(()=>document.querySelectorAll('.studio-region img').length===2&&[...document.querySelectorAll('.studio-region img')].every(img=>img.naturalWidth===300)&&!document.querySelector('.studio-region .image-loading'));checks++;
|
|
assert(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth));checks++;
|
|
}
|
|
requests=new Set();releases={};failSecond=true;await page.locator('#studio-plan').click();for(let n=0;n<100&&requests.size<2;n++)await page.waitForTimeout(20);assert.equal(requests.size,2);
|
|
releases.b();await page.locator('.studio-region .image-load-error').waitFor();assert.equal(await page.locator('.studio-region').first().locator('.spinner').count(),1);assert(await page.locator('#studio-render').isEnabled());checks++;
|
|
const errorField=page.locator('[data-region="1"][data-key="x"]');await errorField.fill('600');await errorField.dispatchEvent('input');assert.equal(await page.locator('.studio-region').nth(1).evaluate(e=>e.style.left),'50%');checks++;
|
|
releases.a();await page.waitForFunction(()=>document.querySelector('.studio-region img')?.naturalWidth===300);assert.equal(await page.locator('.studio-region .spinner').count(),0);checks++;
|
|
assert.deepEqual(errors,[]);console.log('Studio image loading:',checks,'checks PASS; parallel requests, independent completion, local spinners, coordinate editing and dragging; no page errors');
|
|
}finally{await browser.close();}
|
|
})().catch(e=>{console.error(e.message);process.exit(1)});
|