"""Browser-level gallery -> ComfyUI tab protocol compatibility smoke test. Build the gallery, run `python scripts/preview.py --port 8189`, then run `python scripts/browser_lora_stack_channel.py http://127.0.0.1:8189`. The ComfyUI tab is a same-origin message receiver, NOT a ComfyUI installation; separate Node tests execute the pinned upstream LoRA Manager callbacks/setter. """ from __future__ import annotations import asyncio import sys from playwright.async_api import async_playwright, expect BASE = sys.argv[1].rstrip("/") if len(sys.argv) > 1 else "http://127.0.0.1:8189" async def run_case(browser, *, compatible: bool, mode: str = "append"): context = await browser.new_context(viewport={"width": 1440, "height": 800}) try: comfy = await context.new_page() await comfy.route("**/fake-comfy", lambda route: route.fulfill(content_type="text/html", body="
Test ComfyUI tab")) await comfy.goto(BASE + "/fake-comfy") await comfy.evaluate("""(compatible) => { window.__loraStackMessages = []; const channel = new BroadcastChannel('universal-extractor-workflow'); window.__comfyChannel = channel; channel.onmessage = (event) => { const message = event.data; if (message.type === 'universal-extractor:workflow-probe') { channel.postMessage({ type:'universal-extractor:workflow-ack', probeId:message.probeId, instanceId:'test-main-tab', focused:true, visibilityState:'visible', ...(compatible ? {loraStackProtocol:2} : {}), }); } if (message.type === 'universal-extractor:lora-stack-message') { window.__loraStackMessages.push(message); channel.postMessage({ type:'universal-extractor:lora-stack-delivered', instanceId:'test-main-tab', payloadId:message.payload.id, ...(compatible ? {loraStackProtocol:2} : {}), ok:true, summary:{target:'LoRA test node',applied:1,added:1,updated:0,removed:0}, }); } }; }""", compatible) gallery = await context.new_page() await gallery.add_init_script(""" localStorage.setItem('universal-extractor-locale','zh-CN'); localStorage.setItem('universal-extractor:onboarding-tour-v1-completed','true'); localStorage.setItem('universal-extractor:ui-preferences',JSON.stringify({ enableImagePrefetch:false,enableLiveGalleryRefresh:false })); """) async def metadata_with_stack(route): response = await route.fetch() body = await response.json() body["recipe"]["lora_manager"] = { "detected": True, "raw_stack": "