@qaguardian/playwright-score 0.1.13 → 0.1.14

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/README.md CHANGED
@@ -16,7 +16,7 @@ Lint + score Playwright tests with:
16
16
 
17
17
  The score never calls an LLM. AI may *generate* or *repair* code using findings; **rules grade code**.
18
18
 
19
- 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).
19
+ See [METHODOLOGY.md](./METHODOLOGY.md) for the frozen formula, [VALIDATION.md](./VALIDATION.md) for real-world results against public repos (cal.com, Grafana, Mattermost, ...) and a re-runnable script to reproduce them, or the full product write-up on the [landing page](https://qaguardian.com/open-source/playwright-score).
20
20
 
21
21
  ## Install
22
22
 
package/dist/cli.js CHANGED
@@ -34,6 +34,14 @@ Website: https://qaguardian.com/open-source/playwright-score
34
34
  Methodology: METHODOLOGY.md (sqs-v1)
35
35
  `);
36
36
  }
37
+ // Deliberately never process.exit() right after a console.log/console.error
38
+ // — for a large enough write (verified against a real suite: a JSON report
39
+ // with 1000+ findings, ~370KB) stdout to a pipe (not a TTY) is asynchronous,
40
+ // and process.exit() can terminate the process before the OS has drained
41
+ // the write, silently truncating the output exactly at the pipe buffer
42
+ // size (64KB on macOS/Linux). Setting process.exitCode and returning lets
43
+ // Node exit naturally once pending I/O actually completes, which is the
44
+ // standard fix for this class of bug.
37
45
  async function main() {
38
46
  const args = process.argv.slice(2);
39
47
  if (args.includes('--version') || args.includes('-v')) {
@@ -46,11 +54,13 @@ async function main() {
46
54
  catch {
47
55
  console.log('0.1.8');
48
56
  }
49
- process.exit(0);
57
+ process.exitCode = 0;
58
+ return;
50
59
  }
51
60
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
52
61
  printHelp();
53
- process.exit(args.length === 0 ? 2 : 0);
62
+ process.exitCode = args.length === 0 ? 2 : 0;
63
+ return;
54
64
  }
55
65
  let profile = 'standard';
56
66
  let threshold;
@@ -63,21 +73,24 @@ async function main() {
63
73
  profile = args[++i];
64
74
  if (profile !== 'standard' && profile !== 'guardian') {
65
75
  console.error(`Invalid profile: ${profile}`);
66
- process.exit(2);
76
+ process.exitCode = 2;
77
+ return;
67
78
  }
68
79
  }
69
80
  else if (a === '--threshold') {
70
81
  threshold = Number(args[++i]);
71
82
  if (Number.isNaN(threshold) || threshold < 0 || threshold > 100) {
72
83
  console.error('threshold must be 0-100');
73
- process.exit(2);
84
+ process.exitCode = 2;
85
+ return;
74
86
  }
75
87
  }
76
88
  else if (a === '--format') {
77
89
  const f = args[++i];
78
90
  if (f !== 'text' && f !== 'json' && f !== 'markdown' && f !== 'sarif') {
79
91
  console.error(`Invalid format: ${f}`);
80
- process.exit(2);
92
+ process.exitCode = 2;
93
+ return;
81
94
  }
82
95
  format = f;
83
96
  }
@@ -89,7 +102,8 @@ async function main() {
89
102
  }
90
103
  else if (a.startsWith('-')) {
91
104
  console.error(`Unknown option: ${a}`);
92
- process.exit(2);
105
+ process.exitCode = 2;
106
+ return;
93
107
  }
94
108
  else {
95
109
  paths.push(a);
@@ -97,7 +111,8 @@ async function main() {
97
111
  }
98
112
  if (paths.length === 0) {
99
113
  console.error('At least one path is required');
100
- process.exit(2);
114
+ process.exitCode = 2;
115
+ return;
101
116
  }
102
117
  try {
103
118
  const result = await scorePaths({ paths, profile, threshold });
@@ -122,11 +137,11 @@ async function main() {
122
137
  else {
123
138
  console.log(body);
124
139
  }
125
- process.exit(result.pass ? 0 : 1);
140
+ process.exitCode = result.pass ? 0 : 1;
126
141
  }
127
142
  catch (err) {
128
143
  console.error(err instanceof Error ? err.message : err);
129
- process.exit(2);
144
+ process.exitCode = 2;
130
145
  }
131
146
  }
132
147
  main();
package/dist/index.js CHANGED
@@ -14,17 +14,17 @@ export { formatJson } from './formatters/json.js';
14
14
  export { formatText } from './formatters/text.js';
15
15
  export { formatMarkdown } from './formatters/markdown.js';
16
16
  export { formatSarif } from './formatters/sarif.js';
17
- // `.e2e.` is a real, common convention for disambiguating end-to-end specs
18
- // from unit tests living in the same tree — verified against a
19
- // well-known, large real-world repo (cal.com: 53 real Playwright specs,
20
- // all named *.e2e.ts, zero *.spec.ts/*.test.ts) where a directory scan
21
- // previously hard-failed with "no files matched" despite a fully healthy,
22
- // populated suite. looksLikeNonPlaywrightTest (see metrics.ts) is the
23
- // safety net for a repo that uses `.e2e.` for a *different* framework —
24
- // Cypress specifically was common enough here to get its own explicit
25
- // check alongside the existing Jest/Vitest/RTL ones.
17
+ // `.e2e.`/`.e2e-spec.`/`.e2e-test.` are real, common conventions for
18
+ // disambiguating end-to-end specs from unit tests living in the same tree
19
+ // — verified against two well-known, large real-world repos where a
20
+ // directory scan previously hard-failed with "no files matched" despite a
21
+ // fully healthy, populated suite: cal.com (53 specs, all *.e2e.ts) and
22
+ // Immich (52 specs, all *.e2e-spec.ts). looksLikeNonPlaywrightTest (see
23
+ // metrics.ts) is the safety net for a repo that uses `.e2e.` for a
24
+ // *different* framework — Cypress specifically was common enough here to
25
+ // get its own explicit check alongside the existing Jest/Vitest/RTL ones.
26
26
  const SPEC_GLOBS = [
27
- '**/*.{spec,test,e2e}.{ts,tsx,js,jsx}',
27
+ '**/*.{spec,test,e2e,e2e-spec,e2e-test}.{ts,tsx,js,jsx}',
28
28
  '**/*.spec.ts',
29
29
  '**/*.test.ts',
30
30
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaguardian/playwright-score",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Deterministic, AI-free Playwright spec quality score (sqs-v1). Lint + score with standard and guardian profiles.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",