Files

22 lines
7.0 KiB
TypeScript

import React from 'react';
import {createRoot} from 'react-dom/client';
import {FrameFilePicker} from '../ui/src/file-picker';
import {configureLanguage} from '../ui/src/i18n';
import '../ui/src/style.css';
const wait=(ms=40)=>new Promise(r=>setTimeout(r,ms));const until=async(f:()=>any)=>{for(let i=0;i<100;i++){if(f())return;await wait();}throw Error('Timed out '+document.body.innerText);};
const calls:{path:string;params:any}[]=[];
const source=[{name:'Nested',path:'/home/steamos/Downloads/Nested',directory:true,size:0},{name:'Wolvic.apk',path:'/home/steamos/Downloads/Wolvic.apk',directory:false,size:157426910,modified:1791200000},{name:'language.json',path:'/home/steamos/Downloads/language.json',directory:false,size:100}];
window.fetch=async(url,init)=>{const path=String(url),params=JSON.parse(String(init?.body));calls.push({path,params});if(path.endsWith('/complete'))return new Response(JSON.stringify({result:true}));if(!path.endsWith('/list'))throw Error('Unexpected request');await wait(params.query==='slow'?250:20);if(params.path==='/denied')return new Response(JSON.stringify({error:'无法读取目录'}));const directory=params.path||'/home/steamos/Downloads';let entries=directory==='/home/steamos'?[{name:'Downloads',path:'/home/steamos/Downloads',directory:true,size:0},{name:'Documents',path:'/home/steamos/Documents',directory:true,size:0}]:directory.endsWith('/Nested')||directory.endsWith('/Documents')?[]:source.filter(e=>e.directory||(!(params.extensions??[]).length||(params.extensions??[]).some((s:string)=>e.name.endsWith(s))));if(params.directoryOnly)entries=entries.filter(e=>e.directory);entries=entries.filter(e=>e.name.toLowerCase().includes((params.query??'').toLowerCase()));return new Response(JSON.stringify({result:{path:directory,parent:'/home/steamos',roots:[{name:'下载',path:'/home/steamos/Downloads'},{name:'主目录',path:'/home/steamos'},{name:'临时目录',path:'/tmp'}],entries,total:entries.length,offset:0,skipped:0}}));};
const root=createRoot(document.getElementById('root')!);root.render(<><div className="app manager"><button>Underlying page</button></div><FrameFilePicker/></>);
const open=(id:string,multiple=false,accept=['.apk'])=>window.dispatchEvent(new CustomEvent('framely.fileDialog',{detail:{id,multiple,directory:false,accept}}));
const button=(name:string)=>[...document.querySelectorAll<HTMLButtonElement>('.frame-files button')].find(b=>b.textContent?.trim()===name)!;
const row=(name:string)=>[...document.querySelectorAll<HTMLButtonElement>('.frame-file-row')].find(b=>b.textContent?.includes(name))!;
function change(selector:string,value:string){const input=document.querySelector<HTMLInputElement>(selector)!;Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value')!.set!.call(input,value);input.dispatchEvent(new Event('input',{bubbles:true}));}
(async()=>{try{
configureLanguage('en-US',[]);await wait();if(document.querySelector('.frame-files'))throw Error('External browser automatically opened custom picker');open('apk');await until(()=>row('Wolvic.apk'));await until(()=>document.querySelector('[role=treeitem][aria-label=Downloads]'));const treeDownloads=document.querySelector<HTMLElement>('[role=treeitem][aria-label=Downloads]')!;if(treeDownloads.getAttribute('aria-selected')!=='true'||!document.querySelector('[role=treeitem][aria-label=Home] [role=group]'))throw Error('Current folder ancestors are not expanded');document.querySelector<HTMLButtonElement>('[aria-label="Collapse Home"]')!.click();await until(()=>!document.querySelector('[role=treeitem][aria-label=Downloads]'));document.querySelector<HTMLButtonElement>('[aria-label="Expand Home"]')!.click();await until(()=>document.querySelector('[role=treeitem][aria-label=Downloads]'));if(!document.getElementById('root')!.inert||row('language.json'))throw Error('Background or type filter incorrect');if(button('Select').disabled!==true)throw Error('Can select without a file');row('Wolvic.apk').click();await until(()=>!button('Select').disabled);button('Select').click();await until(()=>!document.querySelector('.frame-files'));if(calls.at(-1)?.params.paths[0]!=='/home/steamos/Downloads/Wolvic.apk'||document.getElementById('root')!.inert)throw Error('File selection not completed');
open('multi',true,['.apk','.json']);await until(()=>row('language.json'));row('language.json').click();await wait();row('Wolvic.apk').click();await until(()=>document.querySelectorAll('.frame-file-row.selected').length===2);button('Select').click();await until(()=>!document.querySelector('.frame-files'));if(calls.at(-1)?.params.paths.length!==2)throw Error('Multiple selection lost');
open('cancel');await until(()=>row('Wolvic.apk'));row('Nested').click();await until(()=>document.querySelector('.frame-files-list .empty'));document.querySelector<HTMLButtonElement>('[aria-label="Previous folder"]')!.click();await until(()=>row('Wolvic.apk'));let backgroundBack=false;const behind=()=>backgroundBack=true;window.addEventListener('framely.back',behind);window.dispatchEvent(new Event('framely.back'));await until(()=>!document.querySelector('.frame-files'));window.removeEventListener('framely.back',behind);if(backgroundBack||calls.at(-1)?.params.paths.length)throw Error('Back escaped picker or failed to cancel');
open('errors');await until(()=>row('Wolvic.apk'));document.querySelector<HTMLButtonElement>('[aria-label="View options"]')!.click();await until(()=>document.querySelector('[aria-label="Supported files only"]'));document.querySelector<HTMLButtonElement>('[aria-label="Supported files only"]')!.click();await until(()=>row('language.json'));if(!row('language.json').disabled)throw Error('Unsupported file can be selected');document.querySelector<HTMLButtonElement>('[aria-label="Supported files only"]')!.click();await until(()=>!row('language.json'));document.querySelector<HTMLButtonElement>('[aria-label="View options"]')!.click();change('[aria-label="Folder path"]','/denied');button('Go').click();await until(()=>document.querySelector('[role=alert]'));if(!button('Select').disabled)throw Error('Stale directory remains selectable');button('Downloads').click();await until(()=>row('Wolvic.apk'));change('[aria-label="Search this folder"]','slow');await wait(220);change('[aria-label="Search this folder"]','wolvic');await until(()=>row('Wolvic.apk')&&!row('Nested'));await wait(300);if(!row('Wolvic.apk'))throw Error('Stale search response won');change('[aria-label="Search this folder"]','');await until(()=>row('Nested'));row('Wolvic.apk').click();await until(()=>document.querySelector('.frame-file-row.selected'));await wait(400);console.log('FRAMELY_PREVIEW_INSTALL_FILE_PICKER_EN');await wait(650);button('Cancel').click();await until(()=>!document.querySelector('.frame-files'));
configureLanguage('zh-CN',[]);open('zh');await until(()=>row('Wolvic.apk'));row('Wolvic.apk').click();await until(()=>document.querySelector('.frame-file-row.selected'));await wait(400);console.log('FRAMELY_PREVIEW_INSTALL_FILE_PICKER_ZH');await wait(650);button('取消').click();await until(()=>!document.querySelector('.frame-files'));console.log('FRAMELY_BRIDGE_PASS');
}catch(e){console.log('FRAMELY_BRIDGE_FAIL '+String(e));}})();