Files
archy/tests/lifecycle/cloud-file-actions-browser.cjs
T

12 lines
3.0 KiB
JavaScript
Raw Normal View History

// Local Vite browser regression; creates no real files and performs no network deletions.
const { chromium, expect } = require('../../neode-ui/node_modules/@playwright/test');
(async()=>{const source=await fetch((process.env.LIGHTBOX_TEST_URL||'http://127.0.0.1:5187')+'/src/stores/cloud.ts').then(r=>r.text());const piniaUrl=source.match(/from "([^"]*pinia\.js[^"]*)"/)[1];const b=await chromium.launch({headless:true});try{for(const width of [320,390,1440]){const p=await b.newPage({viewport:{width,height:844},hasTouch:true});
p.on('pageerror',e=>console.error('fixture error',e.message));
await p.route('**/actions-fixture',r=>r.fulfill({contentType:'text/html',body:`<!doctype html><meta name="viewport" content="width=device-width,initial-scale=1"><div id="fixture"></div><script type="module">
import {createApp,h} from '/node_modules/.vite/deps/vue.js';import {createPinia,setActivePinia} from '${piniaUrl}';import Card from '/src/components/cloud/FileCardGrid.vue';import Row from '/src/components/cloud/FileCard.vue';import {useCloudStore} from '/src/stores/cloud.ts';import '/src/style.css';
const pinia=createPinia();setActivePinia(pinia);const cloud=useCloudStore();cloud.downloadUrl=()=>'';window.previews=0;window.shares=0;window.deletes=0;const item={name:'A long video filename which must remain readable.mp4',path:'/clip.mp4',extension:'mp4',isDir:false,size:123,modified:'2026-10-05'};const props={item,onPreview:()=>window.previews++,onShare:()=>window.shares++,onDelete:()=>window.deletes++};createApp({render:()=>h('div',{style:'padding:16px'},[h('div',{class:'cloud-card-grid'},[h(Card,props),h(Card,props)]),h(Row,props)])}).use(pinia).mount('#fixture');</script>`}));
await p.goto((process.env.LIGHTBOX_TEST_URL||'http://127.0.0.1:5187')+'/actions-fixture');const buttons=p.locator('.file-actions-trigger');await expect(buttons).toHaveCount(3,{timeout:30000});
for(let i=0;i<3;i++){const trigger=buttons.nth(i);await expect(trigger).toBeVisible();const rect=await trigger.boundingBox();if(rect.width<44||rect.height<44||rect.x<0||rect.x+rect.width>width)throw Error('Invalid permanent action geometry');await trigger.tap();await expect(p.getByRole('dialog')).toBeVisible();const menu=await p.getByRole('dialog').boundingBox();if(menu.x<0||menu.x+menu.width>width||menu.y<0||menu.y+menu.height>844)throw Error('Menu clipped');await p.getByRole('button',{name:'Share with peers',exact:true}).tap();await expect.poll(()=>p.evaluate(()=>window.previews)).toBe(0);}
await buttons.first().tap();await p.getByRole('button',{name:'Delete…',exact:true}).tap();await expect.poll(()=>p.evaluate(()=>window.deletes)).toBe(0);await p.getByRole('button',{name:'Keep file',exact:true}).tap();await p.getByRole('button',{name:'Close menu',exact:true}).tap();
await p.screenshot({path:'/tmp/archy-file-actions-'+width+'.png'});console.log('PASS',width,'permanent touch menu in grid/list, no accidental open, visible unclipped menu, share, cancel delete');await p.close();}}finally{await b.close()}})().catch(e=>{console.error(e);process.exit(1)});