From af67a28639e67d9c27cb5adbb17a9d30d71519fb Mon Sep 17 00:00:00 2001 From: openhands Date: Fri, 23 Oct 2026 14:18:39 +0200 Subject: [PATCH] fix: restore playwright/cpu-friendly config and deployment memory handling --- playwright.config.ts | 35 ++++++++++++++++++++------- scripts/ci-deploy.sh | 7 +++--- src/lib/docker-build-contract.test.ts | 6 ++--- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 9265963d..f454f212 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,22 +1,39 @@ import { defineConfig, devices } from "@playwright/test"; + +// Deploy gate: keep this suite deterministic and light. One worker, one browser +// engine, no live dev server and no parallelism — that is what keeps the host +// from pinning at 100% CPU while the specs run. export default defineConfig({ testDir: "./e2e", - testIgnore: ["**/ui/**", "**/news-real/**", "**/quality/**"], + testIgnore: ["**/ui/**", "**/imaging/**", "**/news-real/**", "**/quality/**"], + forbidOnly: !!process.env.CI, fullyParallel: false, workers: 1, - retries: 1, + retries: process.env.CI ? 1 : 0, timeout: 30000, + expect: { timeout: 10000 }, + globalTimeout: 10 * 60 * 1000, + maxFailures: process.env.CI ? 10 : undefined, reporter: [["list"], ["html", { open: "never" }]], - expect: { - toHaveScreenshot: { - animations: "disabled", - caret: "hide", - maxDiffPixelRatio: 0.02, - }, - }, use: { baseURL: process.env.PLAYWRIGHT_BASE_URL || "http://127.0.0.1:3002", trace: "retain-on-failure", + screenshot: "only-on-failure", + video: "off", + launchOptions: { + args: [ + "--disable-gpu", + "--disable-software-rasterizer", + "--disable-dev-shm-usage", + "--disable-background-networking", + "--disable-default-apps", + "--disable-extensions", + "--disable-sync", + "--metrics-recording-only", + "--mute-audio", + "--no-first-run", + ], + }, }, projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }], }); diff --git a/scripts/ci-deploy.sh b/scripts/ci-deploy.sh index a061d194..ded2cc32 100644 --- a/scripts/ci-deploy.sh +++ b/scripts/ci-deploy.sh @@ -42,9 +42,10 @@ old_container="" new_container="" blue_green=0 -# Resource limits bewust verwijderd: CPU en pids zijn eerder al gehaald. Memory -# blijft bewust gelimiteerd op 4g/5g swap om een geheugenlek niet de host te -# laten vullen (MariaDB, nginx, Traefik als slachtoffer). +# CPU en pids zijn bewust verwijderd; memory blijft gelimiteerd op 4g/5g swap +# om een geheugenlek niet de host te laten vullen (MariaDB, nginx, Traefik). +mem_limit="4g" +mem_swap_limit="5g" is_current() { local head diff --git a/src/lib/docker-build-contract.test.ts b/src/lib/docker-build-contract.test.ts index 214c8ca7..fe72eda6 100644 --- a/src/lib/docker-build-contract.test.ts +++ b/src/lib/docker-build-contract.test.ts @@ -48,15 +48,15 @@ it("passes a compiled release to both the application build and final image", () expect(compose).toContain("NEXT_DEPLOYMENT_ID: ${CMS_RELEASE:-unknown}"); }); -it("keeps the compose CMS opt-in and inside the 2 GB limit", () => { +it("keeps the compose CMS opt-in and inside the 4 GB limit", () => { const compose = readFileSync("docker-compose.yml", "utf8"); // A bare `docker compose up -d` starts only byparr. On a CI-managed host the // CMS owns port 3002 through ci-deploy.sh; letting compose claim the same // port again produces an endless EADDRINUSE crash loop. expect(compose).toContain('profiles: ["cms"]'); expect(compose).not.toContain("cms-green"); - expect(compose).toContain("mem_limit: 2g"); - expect(compose).toContain("memswap_limit: 2g"); + expect(compose).toContain("mem_limit: 4g"); + expect(compose).toContain("memswap_limit: 5g"); }); it("builds with fixtures and excludes installation secrets from every stage", () => {