From a3e9c91ce0d8b698cf4cdd23827c4bfe0189ad9f Mon Sep 17 00:00:00 2001 From: undef_26 <110471781+undef-baka@users.noreply.github.com> Date: Tue, 15 Sep 2026 00:05:28 +0800 Subject: [PATCH] chore: stabilize Playwright E2E runs (#2164) #1351 made `styleStore` initialization asynchronous in `componentDidMount`. `setStyle` currently treats `toolbar:link` appearing as the signal that loading is complete, but if the style network request (`empty-style.json` from jsdelivr) takes over ~1s, the `toolbar:link` can appear while `styleStore` is still null (because the request has not finished). Subsequent `saveStyle` calls in tests then silently do nothing, causing test failures (3 in #2157, and often 20+ on my machine). Changes are: 1. Mock the default empty style to avoid slow network E2E failures. 2. Also cap Playwright workers at 4 to avoid overloading Chromium on high-core machines. Fixes #2158. ## Launch Checklist - [x] Briefly describe the changes in this PR. - [x] Link to related issues. - [ ] ~~Include before/after visuals or gifs if this PR includes visual changes.~~ - [ ] ~~Write tests for all new functionality.~~ - [ ] ~~Add an entry to `CHANGELOG.md` under the `## main` section.~~ (only minor test infra fix) Co-authored-by: liuly Co-authored-by: Harel M --- e2e/maputnik-driver.ts | 6 ++++++ playwright.config.ts | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/e2e/maputnik-driver.ts b/e2e/maputnik-driver.ts index 00733f00..6785fe11 100644 --- a/e2e/maputnik-driver.ts +++ b/e2e/maputnik-driver.ts @@ -1,5 +1,6 @@ import { PlaywrightHelper } from "./playwright-helper"; import { ModalDriver } from "./modal-driver"; +import emptyStyle from "../src/config/empty-style.json" with { type: "json" }; const baseUrl = "http://localhost:8888/"; const isMac = process.platform === "darwin"; @@ -56,6 +57,11 @@ export class MaputnikDriver { url: "https://www.glyph-server.com/*", response: ["Font 1", "Font 2", "Font 3"], }); + await this.helper.given.interceptAndMockResponse({ + method: "GET", + url: /cdn\.jsdelivr\.net\/.*\/empty-style\.json$/, + response: emptyStyle, + }); }, }; diff --git a/playwright.config.ts b/playwright.config.ts index a38daa8a..be2ccf2e 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,6 +1,10 @@ +import { cpus } from "node:os"; import { defineConfig, devices } from "@playwright/test"; const isCI = !!process.env.CI; +// Playwright defaults to CPU / 2 workers, +// capping the number of workers to 4 to avoid overloading browsers. +const workers = Math.min(4, Math.max(1, Math.floor(cpus().length / 2))); // When the app is already served elsewhere (e.g. the docker e2e job) set // E2E_NO_WEBSERVER=1 so Playwright does not start its own dev server. const useExternalServer = !!process.env.E2E_NO_WEBSERVER; @@ -13,6 +17,7 @@ export default defineConfig({ globalTeardown: "./e2e/utils/e2e-teardown.ts", fullyParallel: true, forbidOnly: isCI, + workers, retries: isCI ? 2 : 0, reporter: isCI ? [["list"], ["html", { open: "never" }]] : "list", use: {