import { expect, sourceURL, story } from "../../stories/playwright/story" import type { Accessor, ParentProps } from "solid-js" import type { Command, MenuItem } from "@opencode/plugin/gui" import type { Item } from "../src/runtime/plugin/host" const source = (path: string) => sourceURL(new URL(path, import.meta.url)) const modules = { fixture: source("../../gui-plugins/src/browser/panel.fixture.tsx"), host: source("../src/runtime/plugin/host.tsx"), panels: source("../src/runtime/plugin/panels.tsx"), closed: source("../src/runtime/plugin/closed-tabs.ts"), language: source("../src/runtime/i18n/language.tsx"), browser: source("../../gui-plugins/src/browser/index.ts"), browserRenderer: source("../../gui-plugins/src/browser/renderer.tsx"), browserPanel: source("../../gui-plugins/src/browser/panel.tsx"), file: source("../../gui-plugins/src/file/index.ts"), fileRenderer: source("../../gui-plugins/src/file/renderer.tsx"), commands: source("../src/shell/commands/command.tsx"), pluginCommands: source("../src/runtime/plugin/commands.tsx"), sdk: source("../../plugin/src/gui/index.ts"), render: source("../src/runtime/plugin/render.tsx"), settings: source("../src/settings/model.tsx"), platform: source("../src/runtime/platform/platform.tsx"), solid: source("./plugin-host.fixture.tsx"), } story.beforeEach(async ({ mount, page }) => { // Any story loads the app styles; the fixture mounts the real side region and plugins beside it. await mount("ui-line-comment--editor") await page.evaluate(async (modules) => { const [ { mountBrowserRegion }, host, panels, language, browser, file, commands, sdk, renderer, settings, platform, solid, closed, pluginCommands, ] = await Promise.all([ import(modules.fixture), import(modules.host), import(modules.panels), import(modules.language), import(modules.browser), import(modules.file), import(modules.commands), import(modules.sdk), import(modules.render), import(modules.settings), import(modules.platform), import(modules.solid), import(modules.closed), import(modules.pluginCommands), // Load the pane before mounting: Vite must not reload the page to optimize its dependencies mid-fixture. import(modules.browserPanel), ]) const closedTabs = closed.createClosedTabs() mountBrowserRegion({ LanguageProvider: language.LanguageProvider, PluginHostProvider: host.PluginHostProvider, usePluginHost: host.usePluginHost, createRegion: (region: Omit[0], "closed" | "open">) => panels.createRegion({ ...region, closed: closedTabs, open() {} }), definitions: [ { ...browser.default, id: "browser", windowEntry: () => import(modules.browserRenderer) }, { ...file.default, id: "file", windowEntry: () => import(modules.fileRenderer) }, ], Shell: (props: ParentProps) => solid.createComponent(platform.PlatformProvider, { value: { platform: "web", openExternal() {}, restart: async () => undefined, notify: async () => undefined }, get children() { return solid.createComponent(settings.SettingsProvider, { get children() { return solid.createComponent(commands.CommandProvider, { get children() { return props.children }, }) }, }) }, }), Commands: (props: { close: () => void review: () => void newSession: () => void reopenSession: () => void reopenSide: () => void switchSession: () => void side: () => | { keys: () => readonly string[] active: () => string | undefined select: (key: string) => void close: (key: string) => void focus: (event: Event) => boolean openNewTab: () => void closeNewTab: () => boolean } | undefined shortcut: (shortcut: Accessor) => void }) => { const command = commands.useCommand() // As in the app, the session screen's focus listener starts after the shell's key listener. let inSide = (_event: Event) => false const owner = solid.getOwner() queueMicrotask(() => (inSide = solid.runWithOwner(owner, closed.createSideFocus)!)) const pluginHost = host.usePluginHost() // What the side strip's + shows beside the browser item, through the host's own formatter. props.shortcut(() => { const item = pluginHost .items(sdk.MenuItem) .find( (entry: { plugin: string; value: MenuItem }) => entry.plugin === "browser" && entry.value.menu === "session.panel", )?.value return item?.menu === "session.panel" && item.keybind ? command.keybind(item.keybind) : "" }) // As the session's commands: ⌘T and ⌘W inside the side region, unless the focused panel binds the key there. const sideKey = (event: KeyboardEvent) => !!props.side()?.focus(event) && !pluginCommands.pluginClaims(pluginHost.items(sdk.Command), command.matches, event) command.register("fixture-session", () => [ { id: "file.close", title: "Close side tab", keybind: "mod+w", when: sideKey, onSelect: () => { const side = props.side() const key = side?.active() if (side && !side.closeNewTab() && key) side.close(key) }, }, { id: "file.tab.new", title: "", keybind: "mod+t", when: sideKey, onSelect: () => props.side()?.openNewTab(), }, { id: "tab.close", title: "Close session tab", keybind: "mod+w", onSelect: props.close, }, { id: "tab.new", title: "New session", keybind: "mod+t,mod+n", onSelect: props.newSession, }, { id: "tab.reopenClosed", title: "", keybind: "mod+shift+t", onSelect: props.reopenSession }, { id: "file.tab.reopen", title: "", keybind: "mod+shift+t", when: (event: Event) => inSide(event), onSelect: props.reopenSide, }, { id: "tab.2", title: "", keybind: "mod+2", hidden: true, onSelect: props.switchSession }, ...closed.sideTabShortcuts({ keys: () => props.side()?.keys() ?? [], active: () => props.side()?.active(), select: (key: string) => props.side()?.select(key), when: (event: Event) => inSide(event), }), { id: "review.toggle", title: "Toggle review", keybind: "mod+shift+r", onSelect: props.review, }, ]) // The story server aliases the app's command hook to a no-op. Bridge the real plugin contributions // to the real dispatcher imported by source URL, so the shortcut runs rather than its alias. command.register("fixture-plugins", () => pluginHost.items(sdk.Command).map((item: Item) => { const scope = item.value.scope return { id: `${item.plugin}.${item.value.id}`, title: item.value.title, keybind: item.value.bind, disabled: item.value.enabled === false, hidden: item.value.hidden, editable: item.value.editable, when: scope ? (event: KeyboardEvent) => event.target instanceof Element && !!event.target.closest(scope) : undefined, onSelect: () => item.value.run(), } }), ) return null }, Contribution: renderer.Contribution, }) }, modules) }) story("closes a blank browser tab from its address field without closing the session", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const outside = root.getByRole("button", { name: "Beta", exact: true }) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Blank page", exact: true }).click() await expect(root.getByRole("tab", { name: "New tab", exact: true })).toHaveAttribute("aria-selected", "true") // Prove the scope while browser.close is still registered. await outside.focus() await outside.press("ControlOrMeta+w") await expect(root.getByTestId("session-state")).toHaveText("closed") await expect(root.getByTestId("browser-closes")).toHaveText("[]") await expect(root.getByRole("tab", { name: "New tab", exact: true })).toBeVisible() await outside.click() await expect(root.getByTestId("session-state")).toHaveText("open") const address = root.getByRole("combobox", { name: "Browser address", exact: true }) await address.fill("example.com") await expect(address).toBeFocused() await address.press("ControlOrMeta+w") await expect(root.getByRole("tab", { name: "New tab", exact: true })).toHaveCount(0) await expect(root.getByTestId("browser-closes")).toHaveText('["tab_33333333-3333-3333-3333-333333333333"]') await expect(root.getByTestId("session-state")).toHaveText("open") }) story("toggles the element picker from the shortcut only inside the browser pane", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const outside = root.getByRole("button", { name: "Beta", exact: true }) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Blank page", exact: true }).click() const inspect = root.getByRole("button", { name: "Select an element to comment on", exact: true }) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) await expect(inspect).toBeDisabled() await address.click() await address.press("ControlOrMeta+Shift+c") await expect(root.getByTestId("browser-inspects")).toHaveText("[]") await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(inspect).toBeEnabled() await outside.focus() await outside.press("ControlOrMeta+Shift+c") await expect(inspect).toHaveAttribute("aria-pressed", "false") await expect(root.getByTestId("browser-inspects")).toHaveText("[]") await address.click() await expect(address).toBeFocused() await address.press("ControlOrMeta+Shift+c") await expect(inspect).toHaveAttribute("aria-pressed", "true") await expect(root.getByTestId("browser-inspects")).toHaveText( '[{"tabID":"tab_33333333-3333-3333-3333-333333333333","enabled":true}]', ) await address.press("ControlOrMeta+Shift+c") await expect(inspect).toHaveAttribute("aria-pressed", "false") await expect(root.getByTestId("browser-inspects")).toHaveText( '[{"tabID":"tab_33333333-3333-3333-3333-333333333333","enabled":true},{"tabID":"tab_33333333-3333-3333-3333-333333333333","enabled":false}]', ) }) story("keeps in-page shortcuts like ⌘K in the page while forwarding ⌘⇧R and ⌘W to the pane", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const mod = mac ? "Meta" : "Control" const editor = page .frameLocator('iframe[title="Browser page"]') .getByRole("textbox", { name: "Editor page input", exact: true }) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") // In-page shortcuts like ⌘K stay with the focused page. await editor.focus() await editor.press(`${mod}+k`) await expect(editor).toHaveValue("handled:k") // Shell shortcuts like ⌘⇧R and pane-scoped ⌘W are claimed before the page sees them. await editor.press(`${mod}+Shift+r`) await expect(root.getByTestId("review-toggles")).toHaveText("1") await editor.press(`${mod}+w`) await expect(editor).toHaveValue("handled:k") await expect(root.getByTestId("browser-closes")).toHaveText('["tab_33333333-3333-3333-3333-333333333333"]') await expect(root.getByTestId("session-state")).toHaveText("open") }) story( "reopening the side panel focuses a blank tab's address and closing it returns to the composer", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const toggle = mac ? "Meta+Shift+r" : "Control+Shift+r" const address = root.getByRole("combobox", { name: "Browser address", exact: true }) const composer = root.getByRole("textbox", { name: "Composer", exact: true }) const side = root.getByTestId("side-state") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Blank page", exact: true }).click() await expect(root.getByRole("tab", { name: "New tab", exact: true })).toHaveAttribute("aria-selected", "true") await composer.focus() await page.keyboard.press(toggle) await expect(side).toHaveText("closed") await page.keyboard.press(toggle) await expect(side).toHaveText("open") await expect(address).toBeFocused() await page.keyboard.press(toggle) await expect(side).toHaveText("closed") await expect(composer).toBeFocused() }, ) story("opens a browser tab with ⌘T inside the pane and a session everywhere else", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const mod = mac ? "Meta" : "Control" const outside = root.getByRole("button", { name: "Beta", exact: true }) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) const editor = page.frameLocator('iframe[title="Browser page"]').getByRole("textbox", { name: "Editor page input" }) const opens = root.getByTestId("browser-opens") const sessions = root.getByTestId("new-sessions") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() // The + advertises the browser launcher's own shortcut, whichever tab shows; ⌘T stays the pane's. await expect(root.getByTestId("add-shortcut")).toHaveText(mac ? "⌃⌘B" : "Ctrl+Alt+B") await outside.click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") await expect(root.getByTestId("add-shortcut")).toHaveText(mac ? "⌃⌘B" : "Ctrl+Alt+B") // Outside the pane the shell keeps ⌘T. await outside.focus() await outside.press(`${mod}+t`) await expect(sessions).toHaveText("1") await expect(opens).toHaveText("0") // Inside the pane it opens a browser tab instead. await address.focus() await address.press(`${mod}+t`) await expect(opens).toHaveText("1") // Dvorak's T sits on the physical K key: the shortcut follows the character, not the key position. await address.evaluate((element, meta) => { element.dispatchEvent( new KeyboardEvent("keydown", { key: "t", code: "KeyK", metaKey: meta, ctrlKey: !meta, bubbles: true, cancelable: true, }), ) }, mac) await expect(opens).toHaveText("2") // A focused page hands the reserved chord to the pane before it sees it. await editor.focus() await editor.press(`${mod}+t`) await expect(opens).toHaveText("3") await expect(sessions).toHaveText("1") // The Browser launcher's own chord reaches the app from the page too. await editor.focus() await editor.press(mac ? "Control+Meta+b" : "Control+Alt+b") await expect(opens).toHaveText("4") }) story("⌘T and ⌘W follow focus: side tabs inside the side panel, session tabs elsewhere", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mod = (await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform))) ? "Meta" : "Control" const outside = root.getByRole("button", { name: "Beta", exact: true }) const panel = page.locator("#review-panel") const editor = page.frameLocator('iframe[title="Browser page"]').getByRole("textbox", { name: "Editor page input" }) const sessions = root.getByTestId("new-sessions") const opens = root.getByTestId("browser-opens") const newTab = root.getByTestId("side-new-tab") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByTestId("selected")).toHaveText(/^browser:/) // In the main column the chords keep the session's tabs, and the side panel reads as unfocused. await outside.focus() await outside.press(`${mod}+t`) await expect(sessions).toHaveText("1") await expect(panel).not.toHaveAttribute("data-focused") // The page's focus, which reaches the app only as the pane's report, counts as the side panel's. await editor.click() await expect(panel).toHaveAttribute("data-focused") await editor.press(`${mod}+t`) await expect(opens).toHaveText("1") await expect(sessions).toHaveText("1") // A click on the side panel's own surface, nothing focusable, leaves focus on the panel: ⌘T opens its new tab view // and ⌘W closes that view, then the selected tab. await panel.getByTestId("selected").click() await expect(panel).toHaveAttribute("data-focused") await page.keyboard.press(`${mod}+t`) await expect(newTab).toHaveText("shown") await page.keyboard.press(`${mod}+w`) await expect(newTab).toHaveText("none") await expect(root.getByTestId("browser-closes")).toHaveText("[]") await page.keyboard.press(`${mod}+w`) await expect(root.getByTestId("browser-closes")).toHaveText(/^\["tab_/) await expect(root.getByTestId("session-state")).toHaveText("open") await expect(sessions).toHaveText("1") }) story("⌘L selects the browser address from the page and the pane, and nowhere else", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mod = (await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform))) ? "Meta" : "Control" const outside = root.getByRole("button", { name: "Beta", exact: true }) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) const editor = page.frameLocator('iframe[title="Browser page"]').getByRole("textbox", { name: "Editor page input" }) const selected = () => address.evaluate( (input: HTMLInputElement) => document.activeElement === input && input.value.length > 0 && input.selectionStart === 0 && input.selectionEnd === input.value.length, ) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByTestId("selected")).toHaveText(/^browser:/) // In the main column ⌘L does not reach into the side panel. await outside.focus() await outside.press(`${mod}+l`) await expect(address).not.toBeFocused() // A focused page hands ⌘L to the pane, as it does ⌘T and ⌘W, without typing it. await editor.click() await editor.press(`${mod}+l`) await expect.poll(selected).toBe(true) await expect(editor).not.toHaveValue(/l$/) // On the pane's own surface too. await page.locator('#browser-panel [data-component="browser-bar"]').click({ position: { x: 2, y: 2 } }) await expect(address).not.toBeFocused() await page.keyboard.press(`${mod}+l`) await expect.poll(selected).toBe(true) }) story("keeps ⌘T in the browser pane after a click on its loading surface", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mod = (await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform))) ? "Meta" : "Control" await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByTestId("selected")).toHaveText(/^browser:/) // A page still loading shows the pane's own surface where the native page goes; clicking it must not drop focus // to the side panel around the pane, where ⌘T would open the region's new tab view instead of a browser tab. await page.locator('#browser-panel [data-component="browser-bar"]').click({ position: { x: 2, y: 2 } }) await page.keyboard.press(`${mod}+t`) await expect(root.getByTestId("browser-opens")).toHaveText("1") await expect(root.getByTestId("side-new-tab")).toHaveText("none") await expect(root.getByTestId("new-sessions")).toHaveText("0") }) story("reloads the browser tab with ⌘R inside the pane and leaves it to the window elsewhere", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const outside = root.getByRole("button", { name: "Beta", exact: true }) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) const reloads = root.getByTestId("browser-reloads") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") // Returns whether the chord stays unhandled, so it reaches the window's Reload menu item. const press = (target: typeof outside) => target.evaluate( (element, meta) => element.dispatchEvent( new KeyboardEvent("keydown", { key: "r", code: "KeyR", metaKey: meta, ctrlKey: !meta, bubbles: true, cancelable: true, }), ), mac, ) expect(await press(outside)).toBe(true) await expect(reloads).toHaveText("0") expect(await press(address)).toBe(false) await expect(reloads).toHaveText("1") }) story("keeps blank browser tabs when adding tabs and selecting another panel", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Blank page", exact: true }).click() await expect(root.getByRole("tab", { name: "New tab", exact: true })).toHaveAttribute("aria-selected", "true") await address.press(`${mac ? "Meta" : "Control"}+t`) const tabs = root.getByRole("tab", { name: "New tab", exact: true }) await expect(tabs).toHaveCount(2) await expect(tabs.nth(1)).toHaveAttribute("aria-selected", "true") await expect(root.getByTestId("browser-closes")).toHaveText("[]") // Selecting a different panel must not treat blank browser tabs as disposable placeholders. await address.press(`${mac ? "Meta" : "Control"}+1`) await expect(root.getByRole("tab", { name: "beta.ts", exact: true })).toHaveAttribute("aria-selected", "true") await expect(tabs).toHaveCount(2) await expect(root.getByTestId("browser-closes")).toHaveText("[]") }) story("a new tab request that opened no blank tab leaves a later blank page's address alone", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const address = root.getByRole("combobox", { name: "Browser address", exact: true }) const composer = root.getByRole("textbox", { name: "Composer", exact: true }) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") // Main answers this request without a new blank tab. await address.press(`${mac ? "Meta" : "Control"}+t`) await expect(root.getByTestId("browser-opens")).toHaveText("1") // The page the agent blanks later must not take focus from the composer; a dispatched click leaves focus in place. await composer.focus() await root.getByRole("button", { name: "Blank page", exact: true }).dispatchEvent("click") await expect(root.getByRole("tab", { name: "New tab", exact: true })).toHaveAttribute("aria-selected", "true") await expect(composer).toBeFocused() }) story("reopens a closed browser tab with ⌘⇧T after the side panel and a session tab elsewhere", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform)) const outside = root.getByRole("button", { name: "Beta", exact: true }) const editor = page.frameLocator('iframe[title="Browser page"]').getByRole("textbox", { name: "Editor page input" }) const opens = root.getByTestId("browser-opens") // Dvorak's T sits on the K key; the pane dispatches a focused page's keys on its root. const reopen = (target = "body") => page.evaluate( ([selector, meta]) => { const init = { key: "T", code: "KeyK", shiftKey: true, metaKey: meta, ctrlKey: !meta, bubbles: true } document.querySelector(selector)?.dispatchEvent(new KeyboardEvent("keydown", init)) }, [target, mac] as const, ) await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") // A native page takes focus without a DOM event, so the forwarded key itself places ⌘⇧T in the side panel. await outside.click() await reopen("#browser-panel") // The page hands ⌘W to the pane; the pane and the page go, leaving no focus. await editor.press(`${mac ? "Meta" : "Control"}+w`) await expect(root.getByTestId("selected")).toHaveText("file://beta.ts") await reopen() await expect(opens).toHaveText("1") // Once the user is outside the side panel, ⌘⇧T reopens a session tab again. await outside.click() await reopen() await expect(root.getByTestId("session-reopens")).toHaveText("1") await expect(opens).toHaveText("1") }) story("selects side tabs with ⌘1–9 and ⇧⌘[ ] inside the side panel and session tabs elsewhere", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const mod = (await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform))) ? "Meta" : "Control" const outside = root.getByRole("button", { name: "Beta", exact: true }) const panel = page.locator("#review-panel") const editor = page.frameLocator('iframe[title="Browser page"]').getByRole("textbox", { name: "Editor page input" }) const selected = root.getByTestId("selected") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await outside.click() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(selected).toHaveText(/^browser:/) // A native page takes focus without a DOM event; the key it forwards still lands in the side panel. await outside.click() await editor.press(`${mod}+1`) await expect(selected).toHaveText("file://beta.ts") await panel.press(`${mod}+2`) await expect(selected).toHaveText(/^browser:/) await panel.press(`${mod}+1`) await expect(selected).toHaveText("file://beta.ts") await panel.press(`${mod}+9`) await expect(selected).toHaveText(/^browser:/) await editor.press(`${mod}+Shift+BracketLeft`) await expect(selected).toHaveText("file://beta.ts") await panel.press(`${mod}+Shift+BracketRight`) await expect(selected).toHaveText(/^browser:/) await expect(root.getByTestId("session-switches")).toHaveText("0") await outside.focus() await outside.press(`${mod}+2`) await expect(root.getByTestId("session-switches")).toHaveText("1") await expect(selected).toHaveText(/^browser:/) }) story("keeps a restored browser tab selected and undrawn until the desktop's first inventory", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const tabs = root.getByRole("tab") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await expect(tabs).toHaveText(["alpha.ts"]) // Beta was left on its browser tab, which the desktop has not reported yet. await root.getByRole("button", { name: "Beta", exact: true }).click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await expect(root.getByTestId("selected")).toHaveText(/^browser:tab_/) await expect(tabs).toHaveText(["beta.ts"]) await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(tabs).toHaveText(["beta.ts", "Preview"]) await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") }) story( "keeps the browser tabs while the pane's Ipc is away and registers them again when it returns", async ({ page }) => { const root = page.getByTestId("browser-region-fixture") const tabs = root.getByRole("tab") await expect(root.getByText("Registrations: 1", { exact: true })).toBeVisible() await root.getByRole("button", { name: "Beta", exact: true }).click() await expect(root.getByText("Registrations: 2", { exact: true })).toBeVisible() await root.getByRole("button", { name: "First inventory", exact: true }).click() await expect(tabs).toHaveText(["beta.ts", "Preview"]) // The pane's main plugin reloads: every binding goes with it, and the strip keeps the tab it will restore. await root.getByRole("button", { name: "Pane away", exact: true }).click() await expect(tabs).toHaveText(["beta.ts", "Preview"]) await expect(root.getByRole("tab", { name: "Preview", exact: true })).toHaveAttribute("aria-selected", "true") // Both attachments register again at once, without a retry timer; Beta hands main the tab to restore. await root.getByRole("button", { name: "Pane back", exact: true }).click() await expect(root.getByText("Registrations: 4", { exact: true })).toBeVisible() await expect(root.getByText("Beta restores: 1", { exact: true })).toBeVisible() await expect(tabs).toHaveText(["beta.ts", "Preview"]) }, )