From 9bac5ed842b4123fe98951ad222e4db1687555ef Mon Sep 17 00:00:00 2001 From: TallblokeUK Date: Thu, 3 Sep 2026 23:40:16 +0100 Subject: [PATCH 1/3] ci: pass one project flag per name and let a failed RTL user delete fail --- .github/workflows/playwright-test.yml | 8 ++++++-- tests/e2e/rtl.teardown.ts | 11 +++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/playwright-test.yml b/.github/workflows/playwright-test.yml index 8b07fbe6a..fc3a57dcc 100644 --- a/.github/workflows/playwright-test.yml +++ b/.github/workflows/playwright-test.yml @@ -245,8 +245,12 @@ jobs: mkdir -p test-results/ci suffix="${{ inputs.project-name }}${{ inputs.multisite && '-multisite' || '' }}" : > "test-results/ci/playwright-${suffix}.log" - # shellcheck disable=SC2086 -- project-name may hold several names. - npm run test:playwright -- --project ${{ inputs.project-name }} 2>&1 | tee -a "test-results/ci/playwright-${suffix}.log" + # One --project flag per name, so several projects can be listed in the input. + project_args=() + for project in ${{ inputs.project-name }}; do + project_args+=(--project "$project") + done + npm run test:playwright -- "${project_args[@]}" 2>&1 | tee -a "test-results/ci/playwright-${suffix}.log" - name: Normalize Playwright report filenames if: always() diff --git a/tests/e2e/rtl.teardown.ts b/tests/e2e/rtl.teardown.ts index 9b6fc00c2..47392185c 100644 --- a/tests/e2e/rtl.teardown.ts +++ b/tests/e2e/rtl.teardown.ts @@ -2,10 +2,17 @@ import { test as teardown } from '@playwright/test' import { wpCli } from './helpers/wpCli' // Remove the right-to-left user the setup created, so the site is left as found. +// Only a user that was never created is tolerated; a failed delete must fail here. teardown('remove the right-to-left user', async () => { + let exists = true + try { - await wpCli(['user', 'delete', 'rtl-admin', '--yes']) + await wpCli(['user', 'get', 'rtl-admin', '--field=ID']) } catch { - // Already gone, or never created because the setup failed early. + exists = false + } + + if (exists) { + await wpCli(['user', 'delete', 'rtl-admin', '--yes']) } }) From 96b5705146eff0b7ae218f79cb8cb5c5cdef9cd9 Mon Sep 17 00:00:00 2001 From: TallblokeUK Date: Thu, 3 Sep 2026 23:53:41 +0100 Subject: [PATCH 2/3] test: use a test-owned RTL login, delete only what the run created, assert the toolbar collapse mode --- tests/e2e/list-toolbar-fit.spec.ts | 4 +++- tests/e2e/rtl.setup.ts | 11 ++++++++++- tests/e2e/rtl.teardown.ts | 21 +++++++++++---------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/e2e/list-toolbar-fit.spec.ts b/tests/e2e/list-toolbar-fit.spec.ts index 37baa34fb..c591483bd 100644 --- a/tests/e2e/list-toolbar-fit.spec.ts +++ b/tests/e2e/list-toolbar-fit.spec.ts @@ -23,10 +23,12 @@ test.describe('Snippets toolbar fit', () => { const t = toggle.getBoundingClientRect() return { pageOverflow: document.documentElement.scrollWidth - document.documentElement.clientWidth, - toggleInsideNav: t.left >= n.left - 1 && t.right <= n.right + 1 + toggleInsideNav: t.left >= n.left - 1 && t.right <= n.right + 1, + wraps: 'wrap' === getComputedStyle(nav).flexWrap } }) + expect(fit.wraps, 'the row collapses onto two lines up to 1400px and not above').toBe(1400 >= width) expect(fit.pageOverflow).toBeLessThanOrEqual(0) expect(fit.toggleInsideNav).toBe(true) }) diff --git a/tests/e2e/rtl.setup.ts b/tests/e2e/rtl.setup.ts index af2a9d3c0..a41e94f6a 100644 --- a/tests/e2e/rtl.setup.ts +++ b/tests/e2e/rtl.setup.ts @@ -1,4 +1,5 @@ import { join } from 'path' +import { writeFileSync } from 'fs' import { expect, test as setup } from '@playwright/test' import { wpCli } from './helpers/wpCli' @@ -8,11 +9,15 @@ import { wpCli } from './helpers/wpCli' // fetched from wordpress.org when missing; if that is impossible (offline), // the specs notice the page is still left-to-right and skip themselves. const RTL_LOCALE = 'he_IL' -const RTL_USER = 'rtl-admin' +const RTL_USER = 'cs-e2e-rtl' const SETUP_TIMEOUT_MS = 180000 export const rtlAuthFile = join(__dirname, '.auth/rtl-user.json') +// Records whether this run created the user, so the teardown only removes an +// account it made and never one that already existed on the site. +export const rtlCreatedMarker = join(__dirname, '.auth/rtl-user-created') + setup('sign in as a right-to-left user', async ({ page }) => { setup.setTimeout(SETUP_TIMEOUT_MS) @@ -23,12 +28,16 @@ setup('sign in as a right-to-left user', async ({ page }) => { } // `user create` takes no locale flag, so the locale is set by a second command. + let created = false + try { await wpCli(['user', 'get', RTL_USER, '--field=ID']) } catch { await wpCli(['user', 'create', RTL_USER, `${RTL_USER}@example.org`, '--role=administrator']) + created = true } + writeFileSync(rtlCreatedMarker, created ? 'created' : 'existing') await wpCli(['user', 'update', RTL_USER, '--user_pass=password', `--locale=${RTL_LOCALE}`]) await page.goto('/wp-login.php') diff --git a/tests/e2e/rtl.teardown.ts b/tests/e2e/rtl.teardown.ts index 47392185c..19b8555c8 100644 --- a/tests/e2e/rtl.teardown.ts +++ b/tests/e2e/rtl.teardown.ts @@ -1,18 +1,19 @@ +import { existsSync, readFileSync, unlinkSync } from 'fs' import { test as teardown } from '@playwright/test' import { wpCli } from './helpers/wpCli' +import { rtlCreatedMarker } from './rtl.setup' -// Remove the right-to-left user the setup created, so the site is left as found. -// Only a user that was never created is tolerated; a failed delete must fail here. +// Remove the right-to-left user only if this run created it; an account that +// already existed on the site is left alone. A failed delete fails the teardown. teardown('remove the right-to-left user', async () => { - let exists = true - - try { - await wpCli(['user', 'get', 'rtl-admin', '--field=ID']) - } catch { - exists = false + if (!existsSync(rtlCreatedMarker)) { + return } - if (exists) { - await wpCli(['user', 'delete', 'rtl-admin', '--yes']) + const created = 'created' === readFileSync(rtlCreatedMarker, 'utf8').trim() + unlinkSync(rtlCreatedMarker) + + if (created) { + await wpCli(['user', 'delete', 'cs-e2e-rtl', '--yes']) } }) From 031f00bdba7854dcd9edb804910dad4980ee2e0e Mon Sep 17 00:00:00 2001 From: TallblokeUK Date: Thu, 3 Sep 2026 23:54:57 +0100 Subject: [PATCH 3/3] test: share the RTL user constants through a helper instead of a test file --- tests/e2e/helpers/rtlUser.ts | 13 +++++++++++++ tests/e2e/rtl.setup.ts | 10 +--------- tests/e2e/rtl.teardown.ts | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 tests/e2e/helpers/rtlUser.ts diff --git a/tests/e2e/helpers/rtlUser.ts b/tests/e2e/helpers/rtlUser.ts new file mode 100644 index 000000000..d847bd78d --- /dev/null +++ b/tests/e2e/helpers/rtlUser.ts @@ -0,0 +1,13 @@ +import { join } from 'path' + +// The right-to-left specs sign in as an account of their own, so the rest of +// the suite never sees the site mirrored. These names are shared by the setup +// that creates the session and the teardown that removes the account. +export const RTL_LOCALE = 'he_IL' +export const RTL_USER = 'cs-e2e-rtl' + +export const rtlAuthFile = join(__dirname, '..', '.auth', 'rtl-user.json') + +// Records whether a run created the user, so the teardown only removes an +// account it made and never one that already existed on the site. +export const rtlCreatedMarker = join(__dirname, '..', '.auth', 'rtl-user-created') diff --git a/tests/e2e/rtl.setup.ts b/tests/e2e/rtl.setup.ts index a41e94f6a..811ebd806 100644 --- a/tests/e2e/rtl.setup.ts +++ b/tests/e2e/rtl.setup.ts @@ -1,6 +1,6 @@ -import { join } from 'path' import { writeFileSync } from 'fs' import { expect, test as setup } from '@playwright/test' +import { RTL_LOCALE, RTL_USER, rtlAuthFile, rtlCreatedMarker } from './helpers/rtlUser' import { wpCli } from './helpers/wpCli' // The RTL specs sign in as a user of their own whose locale is right-to-left, @@ -8,16 +8,8 @@ import { wpCli } from './helpers/wpCli' // site mirrored, whatever order the projects run in. The language pack is // fetched from wordpress.org when missing; if that is impossible (offline), // the specs notice the page is still left-to-right and skip themselves. -const RTL_LOCALE = 'he_IL' -const RTL_USER = 'cs-e2e-rtl' const SETUP_TIMEOUT_MS = 180000 -export const rtlAuthFile = join(__dirname, '.auth/rtl-user.json') - -// Records whether this run created the user, so the teardown only removes an -// account it made and never one that already existed on the site. -export const rtlCreatedMarker = join(__dirname, '.auth/rtl-user-created') - setup('sign in as a right-to-left user', async ({ page }) => { setup.setTimeout(SETUP_TIMEOUT_MS) diff --git a/tests/e2e/rtl.teardown.ts b/tests/e2e/rtl.teardown.ts index 19b8555c8..560ba03c5 100644 --- a/tests/e2e/rtl.teardown.ts +++ b/tests/e2e/rtl.teardown.ts @@ -1,7 +1,7 @@ import { existsSync, readFileSync, unlinkSync } from 'fs' import { test as teardown } from '@playwright/test' +import { RTL_USER, rtlCreatedMarker } from './helpers/rtlUser' import { wpCli } from './helpers/wpCli' -import { rtlCreatedMarker } from './rtl.setup' // Remove the right-to-left user only if this run created it; an account that // already existed on the site is left alone. A failed delete fails the teardown. @@ -14,6 +14,6 @@ teardown('remove the right-to-left user', async () => { unlinkSync(rtlCreatedMarker) if (created) { - await wpCli(['user', 'delete', 'cs-e2e-rtl', '--yes']) + await wpCli(['user', 'delete', RTL_USER, '--yes']) } })