import { test, expect, devices, type Browser, type Page } from "@playwright/test"; import { MEMBER_STORAGE, gotoPage, openApp } from "./helpers"; // One member on two devices, a desktop and an iPad, each with its own browser storage. A preference is // a choice about the account, so a change on one device shows on the other; a device setting (here // performance mode, for a weak GPU) stays on the device it was set on. Kept in browser storage only, a // preference used to stay on the one device it was changed on. async function device(browser: Browser, descriptor: (typeof devices)[string]): Promise { const context = await browser.newContext({ ...descriptor, baseURL: test.info().project.use.baseURL, locale: "en-US", storageState: MEMBER_STORAGE, }); return context.newPage(); } const savedPrefs = (page: Page) => page.waitForResponse( (r) => r.url().includes("/me/preferences") && r.request().method() === "PUT", ); async function pickLayout(page: Page, from: string, to: string): Promise { await page.getByRole("button", { name: `Layout: ${from}` }).click(); await Promise.all([savedPrefs(page), page.getByRole("menuitemradio", { name: to }).click()]); await expect(page.getByRole("button", { name: `Layout: ${to}` })).toBeVisible(); } test("a preference follows the member to another device, a device setting stays", async ({ browser, }) => { const desktop = await device(browser, devices["Desktop Chrome"]); const ipad = await device(browser, devices["iPad (gen 7) landscape"]); try { await openApp(desktop); await gotoPage(desktop, "channels"); await pickLayout(desktop, "Table", "Cards"); await gotoPage(desktop, "settings"); await desktop.getByRole("switch", { name: "Performance mode" }).click(); await expect(desktop.locator("html")).toHaveAttribute("data-perf", "1"); // The Settings prefs save as one payload: the next one (a hints change) would carry performance // mode if it went to the account. Waited for, so the iPad below cannot simply load first. const hints = desktop.getByRole("switch", { name: "Show hints" }); const [save] = await Promise.all([savedPrefs(desktop), hints.click()]); expect(Object.keys(save.request().postDataJSON() as object)).not.toContain("performanceMode"); await Promise.all([savedPrefs(desktop), hints.click()]); await openApp(ipad); await expect(ipad.locator("html")).not.toHaveAttribute("data-perf", "1"); await gotoPage(ipad, "channels"); await expect(ipad.getByRole("button", { name: "Layout: Cards" })).toBeVisible(); } finally { // The member is shared by the suite: put the layout back (performance mode went with the // desktop's storage). await gotoPage(desktop, "channels"); await pickLayout(desktop, "Cards", "Table"); await desktop.context().close(); await ipad.context().close(); } });