Skip to content

Commit 71ea488

Browse files
fix(playwright): scope the guardrail rules to TypeScript and enforce it
The playwright rule globs were inherited as {js,jsx,ts,tsx}. Nothing in the corpus is JavaScript — all 245 baselined files are .ts — but the glob pulled in the new CommonJS plugin under eslint-rules/, applying test rules like no-positional-locator to the linter's own source. That is also why the CI bypass-guard grep had to be restricted to .ts/.tsx: the plugin's RuleTester fixtures contain literal eslint-disable strings it would match. Narrow the four rule globs to {ts,tsx}. The plugin keeps its own CommonJS block, so its source is still linted, just not as a Playwright test. The suppressions baseline is byte-identical. Scoping alone would trade one gap for another: Playwright's default testMatch collects *.spec.js, so a JavaScript spec would run with no rules applied at all. Verified directly — a planted .spec.js is collected as '[chromium] > Features/__ExtCheck.spec.js'. So the TypeScript-only property the scoping relies on is now asserted in corpus.test.js rather than assumed, and fails with the offending paths if a .js/.jsx ever lands in the corpus.
1 parent f4838be commit 71ea488

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

openmetadata-ui/src/main/resources/ui/eslint.config.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ export default [
433433

434434
// Playwright tests
435435
{
436-
files: ['**/playwright/**/*.{js,jsx,ts,tsx}'],
436+
files: ['**/playwright/**/*.{ts,tsx}'],
437437
plugins: {
438438
playwright,
439439
'om-playwright': omPlaywright,
@@ -523,7 +523,7 @@ export default [
523523

524524
// Custom rules that only make sense on e2e spec files
525525
{
526-
files: ['playwright/e2e/**/*.spec.{js,jsx,ts,tsx}'],
526+
files: ['playwright/e2e/**/*.spec.{ts,tsx}'],
527527
plugins: {
528528
'om-playwright': omPlaywright,
529529
},
@@ -564,7 +564,7 @@ export default [
564564
// one (admin) perspective?" If yes, switch to the fixture. If no (you need
565565
// a second user), the warning is expected — leave it as-is.
566566
{
567-
files: ['playwright/e2e/**/*.spec.{js,jsx,ts,tsx}'],
567+
files: ['playwright/e2e/**/*.spec.{ts,tsx}'],
568568
rules: {
569569
'no-restricted-syntax': [
570570
'warn',
@@ -594,7 +594,7 @@ export default [
594594
'src/setupTests.js',
595595
'src/**/*.test.{js,jsx,ts,tsx}',
596596
'src/**/*.spec.{js,jsx,ts,tsx}',
597-
'playwright/**/*.spec.{js,jsx,ts,tsx}',
597+
'playwright/**/*.spec.{ts,tsx}',
598598
],
599599
rules: {
600600
'@typescript-eslint/no-require-imports': 'off',

openmetadata-ui/src/main/resources/ui/playwright/eslint-rules/tests/corpus.test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,49 @@ test('suppressions baseline only ever shrinks', () => {
4646
`suppression total ${total} exceeds ceiling ${CEILING} — fix the violations rather than suppressing them`
4747
);
4848
});
49+
50+
// The 18 guardrail rules are scoped to `**/playwright/**/*.{ts,tsx}` in
51+
// eslint.config.mjs, deliberately: the local plugin under `eslint-rules/` is
52+
// CommonJS `.js` and is not a Playwright test, so applying test rules to it is
53+
// meaningless. That scoping only holds as a guardrail while the test corpus
54+
// really is TypeScript-only — Playwright's default `testMatch` DOES collect
55+
// `*.spec.js`, so a JavaScript spec would run with none of the rules applied.
56+
// This test makes the TypeScript-only invariant explicit rather than assumed.
57+
test('the playwright corpus stays TypeScript-only', () => {
58+
const ROOT = path.join(__dirname, '../..');
59+
// eslint-rules/ is the CommonJS plugin itself; doc-generator/ is lint-ignored
60+
// tooling. Neither is a test, and neither is collected by Playwright.
61+
const EXEMPT = new Set([
62+
'eslint-rules',
63+
'doc-generator',
64+
'output',
65+
'test-data',
66+
]);
67+
68+
const offenders = [];
69+
const walk = (dir, relative) => {
70+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
71+
const rel = relative ? `${relative}/${entry.name}` : entry.name;
72+
73+
if (entry.isDirectory()) {
74+
if (!EXEMPT.has(rel)) {
75+
walk(path.join(dir, entry.name), rel);
76+
}
77+
} else if (/\.(js|jsx)$/.test(entry.name)) {
78+
offenders.push(rel);
79+
}
80+
}
81+
};
82+
83+
walk(ROOT, '');
84+
85+
assert.deepStrictEqual(
86+
offenders,
87+
[],
88+
`JavaScript files found in the Playwright corpus: ${offenders.join(
89+
', '
90+
)}. ` +
91+
'Playwright collects *.spec.js but eslint.config.mjs scopes the guardrail ' +
92+
'rules to .ts/.tsx, so these would run unlinted. Convert them to TypeScript.'
93+
);
94+
});

0 commit comments

Comments
 (0)