82 lines
6.1 KiB
Python
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())
|