From 1f51d2c3188b3baf4ead8c68a3951de735b37450 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 1 Nov 2026 15:24:41 +0000 Subject: [PATCH] test: run e2e tests in WebKit on Linux (#40152) WebKit was removed from the e2e tests in https://github.com/go-gitea/gitea/pull/37315 because Linux WebKit kept crashing. The crashes came from a use-after-free in the libsoup bundled with WebKit, which killed the network process and surfaced as `WebKit encountered an internal error`. macOS WebKit never had them because it does not use libsoup. Playwright 1.64 bundles libsoup 3.6.6 with the fix (https://github.com/microsoft/playwright/issues/42803), so WebKit now runs on all platforms. Builds on https://github.com/go-gitea/gitea/pull/40140. The e2e job ran 50 times on `ubuntu-latest` with WebKit enabled, and all runs passed without WebKit errors. The third browser adds about 1.5 to 2 minutes per run. 1. Playwright installs its system dependencies on GitHub runners too, which only come with the Chromium and Firefox libraries 1. The passkey test skips Linux WebKit, which has no WebAuthn, Playwright only stubs `PublicKeyCredential` there --------- Signed-off-by: silverwind --- Makefile | 2 +- playwright.config.ts | 6 +++--- tests/e2e/webauthn.test.ts | 5 ++++- tools/playwright.sh | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9a70f903a89..a13950018f6 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ SHELLCHECK_IMAGE ?= docker.io/koalaman/shellcheck:v0.11.0@sha256:61862eba1fcf09a CONTAINER_RUNTIME ?= $(shell hash docker >/dev/null 2>&1 && echo docker || echo podman) -PLAYWRIGHT_BROWSERS ?= chromium firefox $(if $(filter Darwin,$(shell uname -s 2>/dev/null)),webkit) +PLAYWRIGHT_BROWSERS ?= chromium firefox webkit PLAYWRIGHT_FLAGS ?= HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes) diff --git a/playwright.config.ts b/playwright.config.ts index 4e52b123037..fcadecd4f89 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,4 +1,4 @@ -import {env, platform} from 'node:process'; +import {env} from 'node:process'; import {defineConfig, devices} from '@playwright/test'; const timeoutFactor = Number(env.GITEA_TEST_E2E_TIMEOUT_FACTOR) || 1; @@ -41,12 +41,12 @@ export default defineConfig({ }, }, }, - ...(platform === 'darwin' ? [{ // webkit on linux is unstable + { name: 'webkit', use: { ...devices['Desktop Safari'], permissions: ['clipboard-read'], }, - }] : []), + }, ], }); diff --git a/tests/e2e/webauthn.test.ts b/tests/e2e/webauthn.test.ts index 64f6edf935d..9816a4a0048 100644 --- a/tests/e2e/webauthn.test.ts +++ b/tests/e2e/webauthn.test.ts @@ -1,3 +1,4 @@ +import {platform} from 'node:process'; import {test, expect, type Page} from '@playwright/test'; import {apiCreateUser, loginUser, randomString, testUserPassword} from './utils.ts'; @@ -48,7 +49,9 @@ test('security key survives credProtect', async ({page, request, browserName}) = }); // this authenticator has no credProtect, so it cannot replace the test above -test('security key signs in as second factor and as passkey', async ({page, request}) => { +test('security key signs in as second factor and as passkey', async ({page, request, browserName}) => { + test.skip(browserName === 'webkit' && platform === 'linux', 'linux webkit has no webauthn, playwright only stubs PublicKeyCredential'); // eslint-disable-line playwright/no-skipped-test -- conditional skip, the reason is in the message + const username = `e2e-passkey-${randomString(8)}`; await apiCreateUser(request, username); await page.context().credentials.install(); diff --git a/tools/playwright.sh b/tools/playwright.sh index 9148b01481e..90dd7e2b4ca 100755 --- a/tools/playwright.sh +++ b/tools/playwright.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -# playwright only supports ubuntu/debian officially, and on CI VMs its system deps are pre-installed -if [ -z "${GITHUB_ACTIONS:-}" ] && [ "$(uname -s)" = "Linux" ] && grep -qE '^ID(_LIKE)?=.*(ubuntu|debian)' /etc/os-release 2>/dev/null; then +# playwright only supports ubuntu/debian officially +if [ "$(uname -s)" = "Linux" ] && grep -qE '^ID(_LIKE)?=.*(ubuntu|debian)' /etc/os-release 2>/dev/null; then if [ "$(id -u)" = 0 ] || { command -v sudo >/dev/null 2>&1 && sudo -n true >/dev/null 2>&1; }; then # Avoid Playwright's interactive su fallback. pnpm exec playwright install --with-deps "$@" else