@qaguardian/playwright-score 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/METHODOLOGY.md +11 -1
- package/README.md +38 -1
- package/dist/eslint-runner.js +25 -7
- package/package.json +1 -1
package/METHODOLOGY.md
CHANGED
|
@@ -161,4 +161,14 @@ See package rule docs / source `profiles.ts`. High level:
|
|
|
161
161
|
- **playwrightHygiene:** waits, force, networkidle, missing await, handles, conditionals
|
|
162
162
|
- **assertions:** expect-expect, empty tests, web-first preference
|
|
163
163
|
- **locators:** ratio metric only (for score); raw-locator ESLint in findings
|
|
164
|
-
- **structure:** focused/skipped, oversized file, describe shape
|
|
164
|
+
- **structure:** focused/skipped, oversized file, describe shape
|
|
165
|
+
|
|
166
|
+
### Active rule set (frozen)
|
|
167
|
+
|
|
168
|
+
The exact ESLint rules that produce sqs-v1 findings are enabled explicitly
|
|
169
|
+
in `eslint-runner.ts` with fixed severities — the score never inherits
|
|
170
|
+
eslint-plugin-playwright's `recommended` set at install time, so identical
|
|
171
|
+
code scores identically regardless of which plugin version npm resolves.
|
|
172
|
+
(Versions ≤0.2.0 intended to inherit `recommended` but a config-shape bug
|
|
173
|
+
dropped it entirely; 0.3.0 froze the intended set explicitly. See
|
|
174
|
+
CHANGELOG.)
|
package/README.md
CHANGED
|
@@ -16,7 +16,44 @@ Page Object Model import resolution, ...).
|
|
|
16
16
|
|
|
17
17
|
The score never calls an LLM. AI may *generate* or *repair* code using findings; **rules grade code**.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Real-world results
|
|
20
|
+
|
|
21
|
+
17 public Playwright suites, scored with the published package against each
|
|
22
|
+
project's actual source — chosen to include both well-known,
|
|
23
|
+
heavily-engineered platforms and smaller, less mature projects. Not curated
|
|
24
|
+
to look good: 3 of 17 fail the default threshold, for real, verifiable
|
|
25
|
+
reasons (see [VALIDATION.md](./VALIDATION.md)).
|
|
26
|
+
|
|
27
|
+
**17 suites · 1,228 files · 6,037 tests · 14/17 passed (80% threshold)**
|
|
28
|
+
|
|
29
|
+
| Repo (source scanned) | Score | Grade | Result |
|
|
30
|
+
|---|---:|:-:|:-:|
|
|
31
|
+
| [Playwright (own TodoMVC example)](https://github.com/microsoft/playwright/tree/main/examples/todomvc) | 98/100 | A | PASS |
|
|
32
|
+
| [Supabase](https://github.com/supabase/supabase/tree/master/e2e) | 97/100 | A | PASS |
|
|
33
|
+
| [Documenso](https://github.com/documenso/documenso/tree/main/packages/app-tests) | 96/100 | A | PASS |
|
|
34
|
+
| [Storybook](https://github.com/storybookjs/storybook/tree/next/code/e2e-internal) | 96/100 | A | PASS |
|
|
35
|
+
| [freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/e2e) | 96/100 | A | PASS |
|
|
36
|
+
| [n8n](https://github.com/n8n-io/n8n/tree/master/packages/testing/playwright) | 95/100 | A | PASS |
|
|
37
|
+
| [dub](https://github.com/dubinc/dub/tree/main/apps/web/playwright) | 95/100 | A | PASS |
|
|
38
|
+
| [novu](https://github.com/novuhq/novu/tree/next/apps/dashboard/tests) | 93/100 | A | PASS |
|
|
39
|
+
| [Grafana](https://github.com/grafana/grafana/tree/main/e2e-playwright) | 91/100 | A | PASS |
|
|
40
|
+
| [PostHog](https://github.com/PostHog/posthog/tree/master/playwright) | 90/100 | A | PASS |
|
|
41
|
+
| [sencho](https://github.com/Studio-Saelix/sencho/tree/main/e2e) | 90/100 | A | PASS |
|
|
42
|
+
| [Mattermost](https://github.com/mattermost/mattermost/tree/master/e2e-tests/playwright) | 89/100 | B | PASS |
|
|
43
|
+
| [Immich](https://github.com/immich-app/immich/tree/main/e2e/src/specs) | 89/100 | B | PASS |
|
|
44
|
+
| [cal.com](https://github.com/calcom/cal.com/tree/main/apps/web/playwright) | 84/100 | B | PASS |
|
|
45
|
+
| [livecodes](https://github.com/live-codes/livecodes/tree/develop/e2e) | 78/100 | C | FAIL |
|
|
46
|
+
| [openplayerjs](https://github.com/openplayerjs/openplayerjs/tree/master/e2e) | 77/100 | C | FAIL |
|
|
47
|
+
| [TheCyberHub](https://github.com/th3cyb3rhub/TheCyberHub/tree/dev/e2e) | 68/100 | D | FAIL |
|
|
48
|
+
|
|
49
|
+
Repo names link to the exact source scanned. Full methodology, findings
|
|
50
|
+
breakdown, and `scripts/validate-corpus.sh` to reproduce every number here
|
|
51
|
+
yourself live in [VALIDATION.md](./VALIDATION.md). A self-contained visual
|
|
52
|
+
report of an earlier five-suite audit lives at
|
|
53
|
+
[`docs/scorecard.html`](./docs/scorecard.html) — host it wherever
|
|
54
|
+
(GitHub Pages, qaguardian.com, ...).
|
|
55
|
+
|
|
56
|
+
See [METHODOLOGY.md](./METHODOLOGY.md) for the frozen formula, or the full product write-up on the [landing page](https://qaguardian.com/open-source/playwright-score).
|
|
20
57
|
|
|
21
58
|
## Install
|
|
22
59
|
|
package/dist/eslint-runner.js
CHANGED
|
@@ -5,8 +5,6 @@ import playwright from 'eslint-plugin-playwright';
|
|
|
5
5
|
import { basePlugin } from './rules/base-plugin.js';
|
|
6
6
|
import { mapRule } from './profiles.js';
|
|
7
7
|
function buildConfig(assertFunctionNames) {
|
|
8
|
-
const playwrightRecommended = playwright.configs?.['flat/recommended'] ??
|
|
9
|
-
playwright.configs?.recommended;
|
|
10
8
|
const base = [
|
|
11
9
|
{
|
|
12
10
|
files: ['**/*.{ts,tsx,js,jsx,mjs,cjs}'],
|
|
@@ -89,14 +87,34 @@ function buildConfig(assertFunctionNames) {
|
|
|
89
87
|
'playwright/prefer-native-locators': 'warn',
|
|
90
88
|
// Matches eslint-plugin-playwright's own recommended severity.
|
|
91
89
|
'playwright/prefer-web-first-assertions': 'error',
|
|
90
|
+
// The rules below complete the sqs-v1 rule set from
|
|
91
|
+
// profiles.ts's ESLINT_RULE_MAP. Earlier versions (<=0.2.0)
|
|
92
|
+
// expected them to arrive via eslint-plugin-playwright's
|
|
93
|
+
// flat/recommended config, but the spread only handled an array
|
|
94
|
+
// shape while the plugin exports a single config object — so the
|
|
95
|
+
// entire recommended set was silently dropped and these rules
|
|
96
|
+
// never ran (METHODOLOGY.md's hygiene dimension lists
|
|
97
|
+
// "conditionals" and "handles", yet neither could ever fire).
|
|
98
|
+
// They are enabled explicitly and frozen here on purpose:
|
|
99
|
+
// eslint-plugin-playwright is a ^range dependency, and inheriting
|
|
100
|
+
// whatever its recommended set says at install time would make
|
|
101
|
+
// identical code score differently across installs. Severities
|
|
102
|
+
// mirror upstream flat/recommended as of eslint-plugin-playwright
|
|
103
|
+
// 2.x. require-top-level-describe stays disabled deliberately —
|
|
104
|
+
// it is stylistic, not in upstream recommended, and would
|
|
105
|
+
// penalize idiomatic describe-less suites.
|
|
106
|
+
'playwright/no-conditional-in-test': 'warn',
|
|
107
|
+
'playwright/no-conditional-expect': 'warn',
|
|
108
|
+
'playwright/no-element-handle': 'warn',
|
|
109
|
+
'playwright/no-eval': 'warn',
|
|
110
|
+
'playwright/no-page-pause': 'warn',
|
|
111
|
+
'playwright/no-useless-await': 'warn',
|
|
112
|
+
'playwright/valid-expect': 'error',
|
|
113
|
+
'playwright/no-standalone-expect': 'error',
|
|
114
|
+
'playwright/max-nested-describe': 'warn',
|
|
92
115
|
},
|
|
93
116
|
},
|
|
94
117
|
];
|
|
95
|
-
// Prefer spreading official recommended flat config when available
|
|
96
|
-
if (Array.isArray(playwrightRecommended)) {
|
|
97
|
-
const configs = playwrightRecommended;
|
|
98
|
-
return [...configs, base[0]];
|
|
99
|
-
}
|
|
100
118
|
return base;
|
|
101
119
|
}
|
|
102
120
|
function toSeverity(eslintSeverity, override) {
|