From 452bf6b050bf29ee400f9e1c9647073a2ddebd3d Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 28 Mar 2026 11:20:22 +0100 Subject: [PATCH 1/4] Fix relative-time RangeError in headless browsers Add 'en' fallback for navigator.language which can be undefined in headless browsers (e.g. Playwright Firefox), causing RangeError in Intl.DateTimeFormat. Add e2e test and shared assertNoJsError helper. Co-Authored-By: Claude (Opus 4.6) --- modules/setting/setting.go | 4 ++++ routers/web/web.go | 2 +- templates/devtest/relative-time.tmpl | 2 +- tests/e2e/relative-time.test.ts | 10 ++++++++++ tests/e2e/utils.ts | 4 ++++ tools/test-e2e.sh | 1 + web_src/js/webcomponents/relative-time.ts | 10 +++++----- 7 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/e2e/relative-time.test.ts diff --git a/modules/setting/setting.go b/modules/setting/setting.go index f2b6274edca22..dca5ece75af23 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -31,6 +31,10 @@ var ( // IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing // TODO: this is only a temporary solution, we should make the test code more reliable IsInTesting = false + + // IsE2ETest indicates whether the server is running for e2e tests, set via GITEA_E2E_TEST env var. + // IsInTesting is unsuitable because it has many side effects for in-process unit/integration tests. + IsE2ETest = os.Getenv("GITEA_E2E_TEST") == "true" ) func init() { diff --git a/routers/web/web.go b/routers/web/web.go index 75cc437b43ef7..d1b68bfc9cadc 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1740,7 +1740,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) { m.Get("/swagger.v1.json", SwaggerV1Json) } - if !setting.IsProd { + if !setting.IsProd || setting.IsE2ETest { m.Group("/devtest", func() { m.Any("", devtest.List) m.Any("/fetch-action-test", devtest.FetchActionTest) diff --git a/templates/devtest/relative-time.tmpl b/templates/devtest/relative-time.tmpl index ff2485ac01458..041ce49f09f3d 100644 --- a/templates/devtest/relative-time.tmpl +++ b/templates/devtest/relative-time.tmpl @@ -3,7 +3,7 @@

Relative (auto)

-
now:
+
now:
3m ago:
3h ago:
1d ago:
diff --git a/tests/e2e/relative-time.test.ts b/tests/e2e/relative-time.test.ts new file mode 100644 index 0000000000000..a22fad0e4ae93 --- /dev/null +++ b/tests/e2e/relative-time.test.ts @@ -0,0 +1,10 @@ +import {test, expect} from '@playwright/test'; +import {assertNoJsError} from './utils.ts'; + +test('relative-time renders without errors', async ({page}) => { + await page.goto('/devtest/relative-time'); + const relativeTime = page.getByTestId('relative-time-now'); + await expect(relativeTime).toHaveAttribute('data-tooltip-content', /.+/); + await expect(relativeTime).toHaveText('now'); + await assertNoJsError(page); +}); diff --git a/tests/e2e/utils.ts b/tests/e2e/utils.ts index aded858600253..1c3b33be90216 100644 --- a/tests/e2e/utils.ts +++ b/tests/e2e/utils.ts @@ -104,6 +104,10 @@ export async function login(page: Page, username = env.GITEA_TEST_E2E_USER, pass await expect(page.getByRole('link', {name: 'Sign In'})).toBeHidden(); } +export async function assertNoJsError(page: Page) { + await expect(page.locator('.js-global-error')).toHaveCount(0); +} + export async function logout(page: Page) { await page.context().clearCookies(); // workaround issues related to fomantic dropdown await page.goto('/'); diff --git a/tools/test-e2e.sh b/tools/test-e2e.sh index 1ee513c1093b9..2edc1c2ff9dc5 100755 --- a/tools/test-e2e.sh +++ b/tools/test-e2e.sh @@ -43,6 +43,7 @@ LEVEL = Warn EOF export GITEA_WORK_DIR="$WORK_DIR" +export GITEA_E2E_TEST=true # Start Gitea server echo "Starting Gitea server on port $FREE_PORT (workdir: $WORK_DIR)..." diff --git a/web_src/js/webcomponents/relative-time.ts b/web_src/js/webcomponents/relative-time.ts index fdff909c2f2d0..8a5d98873371f 100644 --- a/web_src/js/webcomponents/relative-time.ts +++ b/web_src/js/webcomponents/relative-time.ts @@ -259,12 +259,12 @@ class RelativeTime extends HTMLElement { get #lang(): string { const lang = this.closest('[lang]')?.getAttribute('lang'); - if (!lang) return navigator.language; - try { - return new Intl.Locale(lang).toString(); - } catch { - return navigator.language; + if (lang) { + try { + return new Intl.Locale(lang).toString(); + } catch { /* invalid locale, fall through */ } } + return navigator.language ?? 'en'; } get second(): 'numeric' | '2-digit' | undefined { From 76817f1a1b050adf5632b8a87597e32d9e1de26f Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 28 Mar 2026 18:59:19 +0800 Subject: [PATCH 2/4] fix GITEA_TEST_E2E --- modules/setting/setting.go | 11 ++++++----- routers/web/web.go | 2 +- tools/test-e2e.sh | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index dca5ece75af23..e50c971a1ae3b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -28,13 +28,10 @@ var ( CfgProvider ConfigProvider IsWindows bool - // IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing + // IsInTesting indicates whether the testing is running (unit test or integration test). + // A lot of unreliable code causes a lot of nonsense error logs during testing // TODO: this is only a temporary solution, we should make the test code more reliable IsInTesting = false - - // IsE2ETest indicates whether the server is running for e2e tests, set via GITEA_E2E_TEST env var. - // IsInTesting is unsuitable because it has many side effects for in-process unit/integration tests. - IsE2ETest = os.Getenv("GITEA_E2E_TEST") == "true" ) func init() { @@ -61,6 +58,10 @@ func IsRunUserMatchCurrentUser(runUser string) (string, bool) { return currentUser, runUser == currentUser } +func IsInE2eTesting() bool { + return os.Getenv("GITEA_TEST_E2E") == "true" +} + // PrepareAppDataPath creates app data directory if necessary func PrepareAppDataPath() error { // FIXME: There are too many calls to MkdirAll in old code. It is incorrect. diff --git a/routers/web/web.go b/routers/web/web.go index d1b68bfc9cadc..dec5f73b01ed6 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1740,7 +1740,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) { m.Get("/swagger.v1.json", SwaggerV1Json) } - if !setting.IsProd || setting.IsE2ETest { + if !setting.IsProd || setting.IsInE2eTesting() { m.Group("/devtest", func() { m.Any("", devtest.List) m.Any("/fetch-action-test", devtest.FetchActionTest) diff --git a/tools/test-e2e.sh b/tools/test-e2e.sh index 2edc1c2ff9dc5..e11c788fdfcbf 100755 --- a/tools/test-e2e.sh +++ b/tools/test-e2e.sh @@ -43,7 +43,7 @@ LEVEL = Warn EOF export GITEA_WORK_DIR="$WORK_DIR" -export GITEA_E2E_TEST=true +export GITEA_TEST_E2E=true # Start Gitea server echo "Starting Gitea server on port $FREE_PORT (workdir: $WORK_DIR)..." From 870a41fe6f32bd48b21a398674eda3538ce3a726 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 28 Mar 2026 19:02:26 +0800 Subject: [PATCH 3/4] fine tune comments --- modules/setting/setting.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index e50c971a1ae3b..0914498b1f700 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -28,8 +28,10 @@ var ( CfgProvider ConfigProvider IsWindows bool - // IsInTesting indicates whether the testing is running (unit test or integration test). - // A lot of unreliable code causes a lot of nonsense error logs during testing + // IsInTesting indicates whether the testing is running (unit test or integration test). It can be used for: + // * Skip nonsense error logs during testing caused by unreliable code + // * Panic in dev or testing mode to make the problem more obvious and easier to debug + // * Mock some functions or options to make testing easier (eg: session store, time, URL detection, etc.) // TODO: this is only a temporary solution, we should make the test code more reliable IsInTesting = false ) From 3ac561eed61f69574a616a6cf9553fc392b812da Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 28 Mar 2026 19:07:44 +0800 Subject: [PATCH 4/4] fix comment --- modules/setting/setting.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 0914498b1f700..2918ef11a1a5d 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -29,10 +29,9 @@ var ( IsWindows bool // IsInTesting indicates whether the testing is running (unit test or integration test). It can be used for: - // * Skip nonsense error logs during testing caused by unreliable code + // * Skip nonsense error logs during testing caused by unreliable code (TODO: this is only a temporary solution, we should make the test code more reliable) // * Panic in dev or testing mode to make the problem more obvious and easier to debug // * Mock some functions or options to make testing easier (eg: session store, time, URL detection, etc.) - // TODO: this is only a temporary solution, we should make the test code more reliable IsInTesting = false )