* ci(playwright): discover plugin frontend specs from node_modules + plugin_packages Adds two new globs to the Playwright testMatch so any installed plugin shipping specs at the conventional location is picked up automatically: - ../node_modules/ep_*/static/tests/frontend-new/specs/**/*.spec.ts (covers `pnpm add -w ep_*` workspace installs, e.g. CI's with-plugins matrix and dev-time pnpm installs) - plugin_packages/ep_*/static/tests/frontend-new/specs/**/*.spec.ts (covers admin-UI / live-plugin-manager installs into src/plugin_packages) Mirrors the equivalent backend pattern (`mocha ... ../node_modules/ep_*/static/tests/backend/specs/**`) which already auto-discovers plugin backend specs. This re-enables coverage that was lost in commit cc80db2d3 (2023-07) when the legacy in-page jQuery test runner was removed without a Playwright replacement. Until now plugin frontend tests have been silently dead: every plugin's CI runs `pnpm run test-ui` but core's testDir scoped only to `tests/frontend-new/`, so plugin specs at `static/tests/frontend/specs/test.js` were never executed and their green badges were misleading. See #7622. doc/PLUGIN_FRONTEND_TESTS.md documents the new convention, the import path for shared helpers (ep_etherpad-lite/tests/...), and a mocha+helper → Playwright translation table for plugin maintainers who want to migrate. Existing core test discovery is unchanged (143 tests in 38 files listed before and after). Closes #7622. **Change type:** patch (test infra; no production behavior change). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(playwright): split into per-project testMatch; address Qodo on #7623 Three real Qodo findings on the previous commit, all fixed: 1) test-ui's positional arg `tests/frontend-new/specs` filtered out plugin spec paths added to testMatch — the very thing the PR was trying to enable. Drop the positional. Discovery is now driven by per-project testMatch. 2) The single project-wide testMatch I added excluded tests/frontend-new/admin-spec, breaking pnpm run test-admin and the frontend-admin-tests workflow. Split into three projects: - chromium : core specs + plugin specs - firefox : core specs + plugin specs - chromium-admin : admin specs only test-admin now runs --project=chromium-admin (no positional). Net coverage unchanged for both workflows. 3) New code re-indented to 2 spaces per .editorconfig. Discovery verified locally: --project=chromium → 143 tests in 38 files (core) --project=firefox → 143 tests in 38 files (core) --project=chromium-admin → 11 tests in 4 files (admin) With a plugin spec installed at the conventional path: --project=chromium → +1 file, +N tests as expected. **Change type:** patch (test infra; no production behavior change). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.3 KiB
Plugin frontend tests
Etherpad core's Playwright runner discovers plugin frontend specs from the conventional path:
node_modules/ep_<plugin>/static/tests/frontend-new/specs/**/*.spec.ts
When the plugin is installed alongside core (e.g. via pnpm add -w ep_<plugin> or in a with-plugins CI variant), the plugin's specs
run as part of pnpm run test-ui. Same pattern backend tests already
use (mocha ... ../node_modules/ep_*/static/tests/backend/specs/**).
This re-enables coverage that was lost in commit cc80db2d3 (2023-07)
when the legacy jQuery test runner (static/tests/frontend/specs/test.js
- in-page mocha+helper) was removed without a Playwright replacement. See #7622.
Layout in your plugin
ep_yourplugin/
├── ep.json
├── package.json
├── static/
│ └── tests/
│ └── frontend-new/
│ └── specs/
│ └── yourplugin.spec.ts
└── ...
A spec is a normal Playwright test file. Import shared helpers from the
core package — ep_etherpad-lite is symlinked into node_modules by
the workspace, so this resolves anywhere the plugin is installed
alongside core:
import {expect, test} from '@playwright/test';
import {clearPadContent, getPadBody, goToNewPad, writeToPad}
from 'ep_etherpad-lite/tests/frontend-new/helper/padHelper';
test.beforeEach(async ({page}) => {
await goToNewPad(page);
});
test.describe('ep_yourplugin', () => {
test('does the thing', async ({page}) => {
const padBody = await getPadBody(page);
await padBody.click();
await clearPadContent(page);
await writeToPad(page, 'hello');
// …assertions…
await expect(padBody.locator('div').first()).toHaveText('hello');
});
});
Migrating from the legacy static/tests/frontend/specs/test.js
The old format used mocha + a jQuery helper global:
// Legacy — does not run anywhere any more.
describe('ep_yourplugin', function () {
beforeEach(function (cb) { helper.newPad(cb); });
it('does the thing', async function () {
const chrome$ = helper.padChrome$;
const inner$ = helper.padInner$;
expect(chrome$('#yourbutton').length).to.be.greaterThan(0);
});
});
Translation table:
| Legacy (mocha + helper) | Playwright |
|---|---|
describe(...) / it(...) |
test.describe(...) / test(...) |
helper.newPad(cb) |
await goToNewPad(page) |
helper.padChrome$('#x') |
page.locator('#x') |
helper.padInner$('div') |
(await getPadBody(page)).locator('div') |
expect(x).to.equal(y) |
expect(x).toBe(y) (Playwright's expect) |
expect($el.length).to.be.greaterThan(0) |
await expect(page.locator('#x')).toBeVisible() |
$el.sendkeys('text') |
await page.keyboard.type('text') |
$el.simulate('click') |
await page.locator(...).click() |
Most legacy specs translate ~mechanically. After migrating, delete the legacy file so the plugin can't accidentally ship stale tests that nothing executes.
Running them
# Inside core, with the plugin installed:
pnpm run test-ui --project=chromium
# Or via core's with-plugins CI job (see frontend-tests.yml).
pnpm run test-ui automatically picks up plugin specs from any
installed ep_* package. To gate per-plugin: use playwright's
--grep against your plugin's describe name.