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 <me@silverwind.io>
This commit is contained in:
silverwind
2026-11-01 15:24:41 +00:00
committed by GitHub
parent d3021b69ee
commit 1f51d2c318
4 changed files with 10 additions and 7 deletions

View File

@@ -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) 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 ?= PLAYWRIGHT_FLAGS ?=
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes) HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)

View File

@@ -1,4 +1,4 @@
import {env, platform} from 'node:process'; import {env} from 'node:process';
import {defineConfig, devices} from '@playwright/test'; import {defineConfig, devices} from '@playwright/test';
const timeoutFactor = Number(env.GITEA_TEST_E2E_TIMEOUT_FACTOR) || 1; 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', name: 'webkit',
use: { use: {
...devices['Desktop Safari'], ...devices['Desktop Safari'],
permissions: ['clipboard-read'], permissions: ['clipboard-read'],
}, },
}] : []), },
], ],
}); });

View File

@@ -1,3 +1,4 @@
import {platform} from 'node:process';
import {test, expect, type Page} from '@playwright/test'; import {test, expect, type Page} from '@playwright/test';
import {apiCreateUser, loginUser, randomString, testUserPassword} from './utils.ts'; 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 // 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)}`; const username = `e2e-passkey-${randomString(8)}`;
await apiCreateUser(request, username); await apiCreateUser(request, username);
await page.context().credentials.install(); await page.context().credentials.install();

View File

@@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
set -euo pipefail set -euo pipefail
# playwright only supports ubuntu/debian officially, and on CI VMs its system deps are pre-installed # playwright only supports ubuntu/debian officially
if [ -z "${GITHUB_ACTIONS:-}" ] && [ "$(uname -s)" = "Linux" ] && grep -qE '^ID(_LIKE)?=.*(ubuntu|debian)' /etc/os-release 2>/dev/null; then 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. 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 "$@" pnpm exec playwright install --with-deps "$@"
else else