Files

82 lines
6.1 KiB
Python

"""QoL regression against the isolated preview, never a real image directory."""
import asyncio,json,sys
from pathlib import Path
from playwright.async_api import async_playwright,expect
BASE=sys.argv[1] if len(sys.argv)>1 else 'http://127.0.0.1:8189'
OUT=Path(sys.argv[2] if len(sys.argv)>2 else 'artifacts/qol-evidence')
OUT.mkdir(parents=True,exist_ok=True)
async def main():
errors=[];cases=[]
async with async_playwright() as p:
browser=await p.chromium.launch()
for width,height in [(1440,960),(390,844)]:
for locale in ['zh-CN','en']:
page=await browser.new_page(viewport={'width':width,'height':height})
page.on('pageerror',lambda error:errors.append(str(error)))
await page.add_init_script(f'localStorage.setItem("universal-extractor-locale",{json.dumps(locale)});localStorage.setItem("universal-extractor:onboarding-tour-v1-completed","true")')
await page.goto(BASE+'/gallery/',wait_until='networkidle')
async def workspace(index):
await page.locator('[data-tour-id="workspace-switcher"]').click()
await page.locator('.ue-workspace-switcher .ue-topbar-tab').nth(index).click()
for index,name in [(1,'library'),(2,'workbench'),(3,'settings')]:
await workspace(index)
marker=page.locator({'library':'.ue-library-actions','workbench':'.ue-workbench-rail','settings':'.ue-settings-preferences'}[name])
await expect(marker).to_be_visible()
assert not await page.evaluate('document.documentElement.scrollWidth > innerWidth'),(width,locale,name,'horizontal overflow')
await page.screenshot(path=str(OUT/f'{name}-{width}-{locale}.png'),animations='disabled')
if name=='workbench':
await expect(page.locator('.ue-workbench-tool-tab').first).to_have_attribute('aria-pressed','true')
assert await page.locator('.ue-workbench-rail').evaluate('(e)=>getComputedStyle(e).flexDirection')=='row'
assert await page.locator('.ue-qol-disclosure').get_attribute('open') is None
await page.locator('.ue-tool-result').first.fill('Retained prompt draft')
await page.locator('.ue-workbench-tool-tab').last.click()
await expect(page.locator('.ue-inspiration-workspace')).to_be_visible()
await page.screenshot(path=str(OUT/f'inspiration-{width}-{locale}.png'),animations='disabled')
if name=='settings':
# New source must not jump back to default; edits must survive a cancelled tab switch.
await page.locator('.ue-settings-source-list > button').click()
fields=page.locator('.ue-settings-form input')
await fields.nth(0).fill('Unsaved demo')
await fields.nth(1).fill('/not-a-real-source')
await workspace(0)
dialog=page.get_by_role('alertdialog')
await expect(dialog).to_be_visible()
await dialog.get_by_role('button',name='取消' if locale=='zh-CN' else 'Cancel',exact=True).click()
await expect(fields.nth(0)).to_have_value('Unsaved demo')
await workspace(0)
await page.get_by_role('alertdialog').get_by_role('button',name='放弃修改' if locale=='zh-CN' else 'Discard changes',exact=True).click()
await workspace(2)
await page.locator('.ue-workbench-tool-tab').first.click()
await expect(page.locator('.ue-tool-result').first).to_have_value('Retained prompt draft')
await workspace(0)
await expect(page.locator('.ue-gallery-card').first).to_be_visible()
await page.locator('[data-tour-id="gallery-filters"]').click()
menu=page.locator('.ue-filter-menu')
await expect(menu).to_be_visible()
b=await menu.bounding_box()
assert b['x']>=0 and b['x']+b['width']<=width+1,(width,locale,'filter bounds',b)
await page.screenshot(path=str(OUT/f'filters-{width}-{locale}.png'),animations='disabled')
await page.keyboard.press('Escape')
await expect(menu).to_have_count(0)
await expect(page.locator('[data-tour-id="gallery-filters"]')).to_be_focused()
await page.get_by_role('combobox',name='图库模式' if locale=='zh-CN' else 'Gallery mode').select_option('organize')
await expect(page.locator('.ue-dual-pane').first).to_be_visible()
await expect(page.locator('.ue-dual-card').first).to_be_visible()
assert not await page.evaluate('document.documentElement.scrollWidth > innerWidth'),('dual overflow',width,locale)
await page.screenshot(path=str(OUT/f'organizer-{width}-{locale}.png'),animations='disabled')
# Change mode; no files are modified by this browser smoke.
await page.get_by_role('combobox',name='图库模式' if locale=='zh-CN' else 'Gallery mode').select_option('variants')
await expect(page.locator('.ue-variant-tools')).to_be_visible()
await page.locator('.ue-variant-tools input').fill('no-such-group')
await expect(page.locator('.ue-variant-card')).to_have_count(0)
await page.screenshot(path=str(OUT/f'variants-{width}-{locale}.png'),animations='disabled')
cases.append({'width':width,'locale':locale,'passed':True})
await page.close()
await browser.close()
assert not errors,errors
(OUT/'browser-qol.json').write_text(json.dumps({'cases':cases,'page_errors':errors,'environment':'isolated preview, no real ComfyUI'},indent=2))
print('PASS: 4 locale/viewport cases; workspaces, optional tools, unsaved source guard, filter Escape/focus, organizer, variant search. No page errors.')
asyncio.run(main())