mjolnir-qa 0.4.0 → 0.5.2
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/CHANGELOG.md +1199 -28
- package/README.ar.md +667 -0
- package/README.bn.md +678 -0
- package/README.br.md +706 -0
- package/README.bs.md +690 -0
- package/README.da.md +698 -0
- package/README.de.md +711 -0
- package/README.es.md +709 -0
- package/README.fr.md +714 -0
- package/README.gr.md +705 -0
- package/README.he.md +664 -0
- package/README.it.md +709 -0
- package/README.ja.md +692 -0
- package/README.ko.md +681 -0
- package/README.md +425 -152
- package/README.no.md +696 -0
- package/README.pl.md +699 -0
- package/README.ru.md +701 -0
- package/README.th.md +672 -0
- package/README.tr.md +699 -0
- package/README.uk.md +693 -0
- package/README.vi.md +680 -0
- package/README.zh.md +652 -0
- package/README.zht.md +652 -0
- package/dist/cli.d.mts +469 -22
- package/dist/cli.mjs +9780 -5230
- package/package.json +25 -7
package/README.pl.md
ADDED
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="assets/readme/logo.png" alt="Mjölnir — Verification Trust Engine" width="800" />
|
|
4
|
+
|
|
5
|
+
### Twoje testy kłamią. My to dowodzimy.
|
|
6
|
+
|
|
7
|
+
**Verification Trust Engine dla QA.** Mjölnir audytuje suite testowe i
|
|
8
|
+
pipeline'y CI, raportuje wskaźnik wiarygodności i pokazuje dokładnie,
|
|
9
|
+
gdzie zaufanie się łamie.
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
12
|
+
[](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
[](https://nodejs.org)
|
|
15
|
+
|
|
16
|
+
[English](README.md) | [简体中文](README.zh.md) | [繁體中文](README.zht.md) | [한국어](README.ko.md) | [Deutsch](README.de.md) | [Español](README.es.md) | [Français](README.fr.md) | [Italiano](README.it.md) | [Dansk](README.da.md) | [日本語](README.ja.md) | Polski | [Русский](README.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | [Türkçe](README.tr.md) | [Українська](README.uk.md) | [বাংলা](README.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
|
|
17
|
+
|
|
18
|
+
> 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-04.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx mjolnir-qa@latest
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Czy twoje testy zasługują na zaufanie?**
|
|
25
|
+
|
|
26
|
+
[Zobacz w akcji](#-zobacz-w-akcji) ·
|
|
27
|
+
[Szybki start](#-szybki-start) ·
|
|
28
|
+
[Co sprawdza](#-co-sprawdza-mjölnir) ·
|
|
29
|
+
[Punktacja](#jak-działa-punktacja) ·
|
|
30
|
+
[CI](#-integracja-ci) · [Konfiguracja](#konfiguracja) ·
|
|
31
|
+
[Dokumentacja](#-dokumentacja)
|
|
32
|
+
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🎬 Zobacz w akcji
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="assets/readme/demo.svg" alt="Pełny raport --verbose Mjölnir na demo repo: WORTHINESS 75/100 NEEDS WORK, rozbicie diagnostyki wg kategorii, lista FIX THIS FIRST i każde znalezisko z ID reguły i numerem linii — CI, Playwright, higiena testów i reguły Pythona" width="900" />
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<sub>Kompletny wynik `npx mjolnir-qa ./examples/demo-repo --verbose`,
|
|
44
|
+
wyrenderowany przez prawdziwy reporter — nic nie ucięto. Regenerowany
|
|
45
|
+
przez `npm run docs:demo`;
|
|
46
|
+
[`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
|
|
47
|
+
wywala CI, jeśli artefakt odjechał od tego, co wypisuje narzędzie.</sub>
|
|
48
|
+
|
|
49
|
+
**Co właśnie się stało:**
|
|
50
|
+
|
|
51
|
+
1. Mjölnir znalazł specyfikacje Playwright, swoją konfigurację,
|
|
52
|
+
workflow CI i plik testowy Pythona — cztery języki/formaty, jeden
|
|
53
|
+
przebieg.
|
|
54
|
+
2. Znalazł dowody osłabiające zaufanie do suity — `continue-on-error`
|
|
55
|
+
maskujący job, `|| true` połykający kod wyjścia, twarde sleepy,
|
|
56
|
+
kruchy selektor, zaszyte na sztywno URL-e stagingu, czekanie
|
|
57
|
+
`networkidle`.
|
|
58
|
+
3. Każdy z nich zamienił w konkretne znalezisko z ID reguły, miejscem
|
|
59
|
+
i fixem — oraz w jedną punktację, na której można gate'ować PR.
|
|
60
|
+
|
|
61
|
+
### Jedno znalezisko z bliska
|
|
62
|
+
|
|
63
|
+
Uruchom `mjolnir explain QA-CI-001` na pierwszym znalezisku powyżej, a
|
|
64
|
+
otrzymasz:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
▚▞ QA-CI-001 — continue-on-error masks a failing verification gate
|
|
68
|
+
|
|
69
|
+
Severity: error
|
|
70
|
+
Confidence: high
|
|
71
|
+
Evidence: E2
|
|
72
|
+
Measured FP: not yet measured — this rule ships on assumption (see docs/FP-AUDIT.md)
|
|
73
|
+
|
|
74
|
+
WHAT WAS FOUND (real detector output, not a mockup)
|
|
75
|
+
Job `security-scan` runs a verification gate under `continue-on-error: true`.
|
|
76
|
+
|
|
77
|
+
WHY IT MATTERS
|
|
78
|
+
This job can fail every day and CI will still show green. The checkmark
|
|
79
|
+
on this workflow cannot be trusted.
|
|
80
|
+
|
|
81
|
+
HOW TO FIX
|
|
82
|
+
Remove continue-on-error, or scope it to individual non-blocking steps only.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
To jest jednostka wartości: nie czepialstwo stylistyczne, lecz miejsce,
|
|
86
|
+
gdzie twój CI mówi ci, że coś przeszło, choć nie przeszło.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## ⚡ Szybki start
|
|
91
|
+
|
|
92
|
+
Uruchom na repozytorium — dostaniesz pełny raport i wskaźnik
|
|
93
|
+
wiarygodności:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx mjolnir-qa@latest
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**W CI produktem jest jedna komenda.** Skanuje tylko to, czego dotknął
|
|
100
|
+
branch, i kończy się kodem niezerowym przy nowych problemach:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx mjolnir-qa@latest --scope changed
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Wrzuć to jako check w PR — `mjolnir ci install` pisze workflow — i
|
|
107
|
+
gotowe. Wszystko inne jest opcjonalne.
|
|
108
|
+
|
|
109
|
+
| Komenda | Co robi |
|
|
110
|
+
| ----------------------------------- | -------------------------------------------------------- |
|
|
111
|
+
| `mjolnir` | Skan całego repo + wskaźnik wiarygodności |
|
|
112
|
+
| `mjolnir --scope changed` | Tylko to, co wprowadził twój branch — wariant CI |
|
|
113
|
+
| `mjolnir ci install` | Generuje doradczy workflow PR |
|
|
114
|
+
| `mjolnir explain QA-CI-001` | Co / dlaczego / fix + zmierzona stopa FP dla reguły |
|
|
115
|
+
| `mjolnir rules --unmeasured` | Reguły działające na założeniu, nie na pomiarze |
|
|
116
|
+
| `mjolnir --json` / `--format sarif` | Czytelne maszynowo / GitHub Code Scanning |
|
|
117
|
+
| `mjolnir --strict` | Uruchamia też reguły tieru quarantine (wyższe ryzyko FP) |
|
|
118
|
+
|
|
119
|
+
<details>
|
|
120
|
+
<summary><strong>Gdy coś jest flaky</strong></summary>
|
|
121
|
+
|
|
122
|
+
| Komenda | Co robi |
|
|
123
|
+
| ----------------------------------- | ----------------------------------------------------------------- |
|
|
124
|
+
| `mjolnir forensics ./test-results/` | Prawdziwe dane przebiegów → werdykty `TRUE-FLAKE`, `FLAKY.md` |
|
|
125
|
+
| `mjolnir triage ./test-results/` | Propozycja kwarantanny z historii wykonania |
|
|
126
|
+
| `mjolnir pw-report ./test-results/` | Podsumowanie przebiegu Playwright — retry / flaki / najwolniejsze |
|
|
127
|
+
| `mjolnir doctor:playwright` | Głęboki skan tylko Playwright + Selector Health Score |
|
|
128
|
+
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary><strong>Okazjonalnie / raporty</strong></summary>
|
|
133
|
+
|
|
134
|
+
| Komenda | Co robi |
|
|
135
|
+
| ------------------------------- | --------------------------------------------------------- |
|
|
136
|
+
| `mjolnir fix --dry-run` / `fix` | Bezpieczne autofiksy z dowodem |
|
|
137
|
+
| `mjolnir baseline` / `diff` | Migawka znalezisk, potem raport tylko nowych/pogorszonych |
|
|
138
|
+
| `mjolnir impact --since <ref>` | Co się zmieniło od wcześniejszego commita |
|
|
139
|
+
| `mjolnir debt` | Rejestr długu testowego z modelem kosztów |
|
|
140
|
+
| `mjolnir handover` | Mapa onboardingu suity dla nowego QA |
|
|
141
|
+
| `mjolnir stats` | Lokalne liczniki wszystkich widzianych fixów |
|
|
142
|
+
| `mjolnir badge` | JSON endpointu shields.io + snippet |
|
|
143
|
+
| `mjolnir rules --md` | Pełny katalog reguł (JSON albo Markdown) |
|
|
144
|
+
| `mjolnir doctor` | Samoaudyt własnej bazy reguł Mjölnir |
|
|
145
|
+
| `mjolnir create-rule <ID>` | Szkielet nowej reguły + fixture |
|
|
146
|
+
| `mjolnir --format mermaid` | Diagram architektury testów do komentarza PR |
|
|
147
|
+
|
|
148
|
+
</details>
|
|
149
|
+
|
|
150
|
+
Zainstaluj globalnie zamiast `npx`, jeśli wolisz: `npm i -g mjolnir-qa`.
|
|
151
|
+
Wymaga Node.js ≥ 22.18. Działa na Windows, macOS i Linux.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 👥 Dla kogo to jest?
|
|
156
|
+
|
|
157
|
+
- **QA / SDET** posiadający suitę e2e lub integracyjną, którzy
|
|
158
|
+
potrzebują dowodów, że suita naprawdę zasługuje na zielony check,
|
|
159
|
+
jaki wystawia.
|
|
160
|
+
- **Zespoły Platform / DevEx** odpowiedzialne za integralność CI i
|
|
161
|
+
release gate'y — ludzie, dla których `continue-on-error` nie może
|
|
162
|
+
nigdy po cichu przemalować czerwonego pipeline'u na zielono.
|
|
163
|
+
- **Maintainerzy OSS**, którzy chcą taniego, zawsze włączonego gate'a
|
|
164
|
+
weryfikacyjnego, działającego lokalnie i w CI bez wywołań sieciowych.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🔨 Co sprawdza Mjölnir
|
|
169
|
+
|
|
170
|
+
| | |
|
|
171
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
172
|
+
| ⚖️ | **Wskaźnik wiarygodności** — jedna liczba, przejrzysta tabela potrąceń, żadna czarna skrzynka |
|
|
173
|
+
| 🎭 | **Selector Health Score** — ocenia twoje lokatory Playwright, a nie tylko pass rate |
|
|
174
|
+
| 🔬 | **Kryminalistyka runtime** — czyta prawdziwe dane przebiegów Playwright/JUnit, by złapać `TRUE-FLAKE`, nie tylko statyczne zgadywanki |
|
|
175
|
+
| 🚨 | **Reguły integralności CI** — łapie `continue-on-error`, `\|\| true` i inne triki na fałszywą zieleń |
|
|
176
|
+
| 🐍 | **Wszystkie cztery bindingi Playwright** — TypeScript, Python, Java, C#/.NET — plus pytest, JUnit/TestNG i workflow CI |
|
|
177
|
+
| 🔒 | **Local-first** — zero wywołań sieciowych podczas skanu, zero telemetrii, działa w sekundy |
|
|
178
|
+
|
|
179
|
+
### Reguły
|
|
180
|
+
|
|
181
|
+
Każda reguła jest dostarczana z fixture'ami must-fire **i**
|
|
182
|
+
must-not-fire. Reguła, która odpala na własnej negatywnej fixture,
|
|
183
|
+
nie może się wydać — to zapora na fałszywe pozytywy.
|
|
184
|
+
|
|
185
|
+
<details>
|
|
186
|
+
<summary><strong>Higiena testów</strong></summary>
|
|
187
|
+
|
|
188
|
+
| ID | Reguła | Severity |
|
|
189
|
+
| ----------- | ----------------------------------------------------- | -------- |
|
|
190
|
+
| QA-TEST-001 | Committowany test z fokusem (`.only`, `fit`) | error |
|
|
191
|
+
| QA-TEST-002 | Pominięty test bez uzasadnienia | error |
|
|
192
|
+
| QA-TEST-002 | Pominięty test z zarejestrowanym uzasadnieniem | warning |
|
|
193
|
+
| QA-TEST-003 | Test bez asercji | error |
|
|
194
|
+
| QA-TEST-004 | Twardy sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning |
|
|
195
|
+
| QA-TEST-006 | Nadużywanie retry, ukrywające flakiness | warning |
|
|
196
|
+
| QA-TEST-010 | Puste ciało testu | error |
|
|
197
|
+
|
|
198
|
+
</details>
|
|
199
|
+
|
|
200
|
+
<details>
|
|
201
|
+
<summary><strong>Jakość testów</strong></summary>
|
|
202
|
+
|
|
203
|
+
| ID | Reguła | Severity |
|
|
204
|
+
| ------------ | ----------------------------- | -------- |
|
|
205
|
+
| QA-TQUAL-001 | Weryfikacja wyłącznie mockami | info |
|
|
206
|
+
| QA-TQUAL-002 | Asercja tautologiczna | error |
|
|
207
|
+
| QA-TQUAL-009 | Asercja promise bez await | error |
|
|
208
|
+
| QA-TQUAL-011 | Zakomentowane testy | warning |
|
|
209
|
+
|
|
210
|
+
</details>
|
|
211
|
+
|
|
212
|
+
<details>
|
|
213
|
+
<summary><strong>Playwright 🎭</strong></summary>
|
|
214
|
+
|
|
215
|
+
| ID | Reguła | Severity |
|
|
216
|
+
| --------- | ------------------------------------------- | -------- |
|
|
217
|
+
| QA-PW-002 | Asercja lokatora bez await | error |
|
|
218
|
+
| QA-PW-003 | `page.pause()` / `test.only()` committowane | error |
|
|
219
|
+
| QA-PW-004 | Kruche selektory CSS/XPath | warning |
|
|
220
|
+
| QA-PW-005 | Logika biznesowa wewnątrz `page.evaluate()` | info |
|
|
221
|
+
| QA-PW-114 | Legacy element handles (`page.$`) | info |
|
|
222
|
+
| QA-PW-118 | Czekanie `networkidle` (flaky by design) | info |
|
|
223
|
+
| QA-PW-123 | Zaszyte na sztywno URL-e środowisk | warning |
|
|
224
|
+
|
|
225
|
+
</details>
|
|
226
|
+
|
|
227
|
+
<details>
|
|
228
|
+
<summary><strong>Integralność CI</strong></summary>
|
|
229
|
+
|
|
230
|
+
| ID | Reguła | Severity |
|
|
231
|
+
| --------- | ------------------------------------------------------------------ | -------- |
|
|
232
|
+
| QA-CI-001 | `continue-on-error` maskuje porażki | error |
|
|
233
|
+
| QA-CI-002 | `\|\| true` połyka kody wyjścia | error |
|
|
234
|
+
| QA-CI-005 | Raport konsumowany, ale nigdy nie generowany | error |
|
|
235
|
+
| QA-CI-007 | Wrapper'y retry wokół testów | warning |
|
|
236
|
+
| QA-CI-008 | Zawsze udany step maskuje porażki | error |
|
|
237
|
+
| QA-CI-009 | Kod wyjścia testu niepropagowany (`\|` bez pipefail, łańcuchy `;`) | error |
|
|
238
|
+
| QA-CI-010 | Testy pomijane tam, gdzie muszą blokować (strażniki skip-on-PR) | error |
|
|
239
|
+
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
<details>
|
|
243
|
+
<summary><strong>Python / pytest 🐍</strong></summary>
|
|
244
|
+
|
|
245
|
+
| ID | Reguła | Severity |
|
|
246
|
+
| --------- | ------------------------------------------ | -------- |
|
|
247
|
+
| QA-PY-002 | Pominięty test (`skip`, niestrykt `xfail`) | warning |
|
|
248
|
+
| QA-PY-003 | Funkcja testowa bez asercji | error |
|
|
249
|
+
| QA-PY-005 | `time.sleep()` w testach | warning |
|
|
250
|
+
| QA-PY-006 | Puste ciało testu (`pass`) | info |
|
|
251
|
+
| QA-PY-010 | Zależność od losowości/czasu bez freeze | info |
|
|
252
|
+
| QA-PY-012 | Asercja tautologiczna | error |
|
|
253
|
+
|
|
254
|
+
Łącznie 20 reguł Pythona (QA-PY-001…012 higiena pytest + QA-PY-101…108 Playwright-Python).
|
|
255
|
+
|
|
256
|
+
</details>
|
|
257
|
+
|
|
258
|
+
<details>
|
|
259
|
+
<summary><strong>Java / JUnit · TestNG ☕</strong></summary>
|
|
260
|
+
|
|
261
|
+
| ID | Reguła | Severity |
|
|
262
|
+
| --------- | ------------------------------------------ | -------- |
|
|
263
|
+
| QA-JV-101 | Wyłączony test (`@Disabled`) | warning |
|
|
264
|
+
| QA-JV-102 | Twardy sleep (`Thread.sleep()`) | warning |
|
|
265
|
+
| QA-JV-103 | Metoda testowa bez asercji | error |
|
|
266
|
+
| QA-JV-105 | Twardy sleep Playwright `waitForTimeout()` | warning |
|
|
267
|
+
| QA-JV-106 | Kruchy selektor zamiast role lokatora | warning |
|
|
268
|
+
| QA-JV-108 | Zaszyty na sztywno URL środowiska w teście | info |
|
|
269
|
+
| QA-JV-111 | Blanketowy mock `page.route("**")` | info |
|
|
270
|
+
|
|
271
|
+
</details>
|
|
272
|
+
|
|
273
|
+
<details>
|
|
274
|
+
<summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
|
|
275
|
+
|
|
276
|
+
| ID | Reguła | Severity |
|
|
277
|
+
| --------- | -------------------------------------------- | -------- |
|
|
278
|
+
| QA-CS-101 | Pominięty test (`[Ignore]`, `[Fact(Skip=)]`) | warning |
|
|
279
|
+
| QA-CS-102 | Twardy sleep (`Thread.Sleep` / `Task.Delay`) | warning |
|
|
280
|
+
| QA-CS-103 | Metoda testowa bez asercji | error |
|
|
281
|
+
| QA-CS-105 | Twardy sleep `WaitForTimeoutAsync()` | warning |
|
|
282
|
+
| QA-CS-106 | Kruchy selektor zamiast role lokatora | warning |
|
|
283
|
+
| QA-CS-108 | Zaszyty na sztywno URL środowiska w teście | info |
|
|
284
|
+
| QA-CS-111 | Blanketowy mock `page.RouteAsync("**")` | info |
|
|
285
|
+
|
|
286
|
+
</details>
|
|
287
|
+
|
|
288
|
+
> Pełny, żywy katalog — każda reguła z tierem, confidence, ryzykiem
|
|
289
|
+
> fałszywych pozytywów i dostępnością autofixa — jest generowany z
|
|
290
|
+
> rejestru:
|
|
291
|
+
>
|
|
292
|
+
> ```bash
|
|
293
|
+
> mjolnir rules --md
|
|
294
|
+
> ```
|
|
295
|
+
>
|
|
296
|
+
> Strony pojedynczych reguł mieszkają w [`docs/rules/`](docs/rules/).
|
|
297
|
+
|
|
298
|
+
### Ile z tego jest zmierzone
|
|
299
|
+
|
|
300
|
+
**74 z 99 reguł niesie stopę fałszywych pozytywów zmierzoną na
|
|
301
|
+
prawdziwym kodzie OSS** (≥ 10 ręcznie zaklasyfikowanych znalezisk każda;
|
|
302
|
+
zob. [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Pozostałe 19 wychodzi na
|
|
303
|
+
oszacowaniu autora. Stopka każdego skanu mówi, ile z _odpalonych_
|
|
304
|
+
reguł jest zmierzonych; `mjolnir rules --unmeasured` wypisuje
|
|
305
|
+
niezmierzone; strona `mjolnir explain` każdej reguły deklaruje jej
|
|
306
|
+
status. Publikujemy stopę, nawet gdy jest brzydka — QA-CS-103 audytuje
|
|
307
|
+
się na 95 % i za to trafia do kwarantanny. Powiększanie tej 78-ki to
|
|
308
|
+
stale trwająca praca projektu.
|
|
309
|
+
|
|
310
|
+
### Tiery reguł i dojrzałość językowa
|
|
311
|
+
|
|
312
|
+
Każda reguła to `core`, `extended` albo `quarantine`, przypisane z jej
|
|
313
|
+
**zmierzoną** stopą fałszywych pozytywów:
|
|
314
|
+
|
|
315
|
+
| Tier | Znaczenie | Skan domyślny | `--strict` |
|
|
316
|
+
| ------------ | ------------------------------------------------ | :-----------: | :--------: |
|
|
317
|
+
| `core` | ≤ 10 % zmierzonych FP | ✅ | ✅ |
|
|
318
|
+
| `extended` | ≤ 30 % zmierzonych FP | ✅ | ✅ |
|
|
319
|
+
| `quarantine` | powyżej 30 %, albo jeszcze niezmierzone (n < 10) | ❌ | ✅ |
|
|
320
|
+
|
|
321
|
+
| Język | Adapter | Pokrycie dziś |
|
|
322
|
+
| --------------- | --------------- | ------------------------------------------------------------ |
|
|
323
|
+
| TypeScript / JS | AST kompilatora | najszersze, najmocniej mierzone — głównie `core`/`extended` |
|
|
324
|
+
| Python / pytest | Warstwa regex | szerokie, audytowane na korpusie — głównie `core`/`extended` |
|
|
325
|
+
| Java | Warstwa regex | nowsze — głównie `extended`/`quarantine` |
|
|
326
|
+
| C# / .NET | Warstwa regex | nowsze — głównie `extended`/`quarantine` |
|
|
327
|
+
|
|
328
|
+
TypeScript i Python mają najszersze zmierzone pokrycie. Java i C#
|
|
329
|
+
się wydały, są udokumentowane i pozostają poza nagłówkową liczbą,
|
|
330
|
+
aż prawdziwa konsumująca suita (nie własne testy biblioteki bindingu)
|
|
331
|
+
zostanie audytowana.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Jak działa punktacja
|
|
336
|
+
|
|
337
|
+
<p align="center">
|
|
338
|
+
<img src="assets/readme/terminal-hero.svg" alt="Wynik terminala Mjölnir — WORTHINESS 75/100 NEEDS WORK, rozbicie diagnostyki wg kategorii i lista FIX THIS FIRST" width="820" />
|
|
339
|
+
</p>
|
|
340
|
+
|
|
341
|
+
<sub>Regenerowany przez `npm run docs:hero`;
|
|
342
|
+
[`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
|
|
343
|
+
wywala CI, jeśli artefakt odjechał od tego, co reporter naprawdę
|
|
344
|
+
wypisuje.</sub>
|
|
345
|
+
|
|
346
|
+
Punktacja jest przejrzysta: **error −8, warning −3, info −1**, potem
|
|
347
|
+
normalizacja o ekspozycję suity (potrącenia na deklarację testu).
|
|
348
|
+
Potrącenia ważone dowodami znaczą, że słabe sygnały kosztują mniej.
|
|
349
|
+
Terminal pokazuje te same zdyskontowane liczby, których używa
|
|
350
|
+
punktacja — żadnej czarnej skrzynki. Pełna metoda:
|
|
351
|
+
[docs/SCORING.md](docs/SCORING.md).
|
|
352
|
+
|
|
353
|
+
**Werdykty**
|
|
354
|
+
|
|
355
|
+
| Score | Werdykt |
|
|
356
|
+
| ------- | ---------------- |
|
|
357
|
+
| ≥ 80 | ✓ **WORTHY** |
|
|
358
|
+
| 50 – 79 | ⚠ **NEEDS WORK** |
|
|
359
|
+
| < 50 | ✖ **UNWORTHY** |
|
|
360
|
+
|
|
361
|
+
**Poziomy dowodów** — każde znalezisko niesie jeden; ustawia wagę
|
|
362
|
+
znaleziska w punktacji:
|
|
363
|
+
|
|
364
|
+
| Poziom | Znaczenie | Wpływ na punktację | Przykład |
|
|
365
|
+
| ------ | --------------------- | ------------------ | ------------------------------------------------------ |
|
|
366
|
+
| E2 | Deterministyczna wada | Pełne potrącenie | Committowany `.only` — dowodliwe strukturalnie |
|
|
367
|
+
| E1 | Heurystyczny wzorzec | Połowa potrącenia | Regex-owo trafiony `sleep()` — mocny sygnał, nie dowód |
|
|
368
|
+
| E0 | Obserwacja | Zero (tylko info) | Raportowane, ale nigdy nie gate'uje CI i nie potrąca |
|
|
369
|
+
|
|
370
|
+
Większość reguł to **E1**. Slogan „we prove it" odnosi się do tego
|
|
371
|
+
systemu: znaleziska E2 to dowód strukturalny; znaleziska E1 to
|
|
372
|
+
poprawnie pozycjonowane ostrzeżenia, nie formalne dowody.
|
|
373
|
+
|
|
374
|
+
Puste repo punktuje `null`, nigdy fałszywą setkę — zob.
|
|
375
|
+
[Model zaufania](#model-zaufania).
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## 🎭 Selector Health Score
|
|
380
|
+
|
|
381
|
+
Flagowa metryka dla suite'ów Playwright — jak odporne są twoje
|
|
382
|
+
lokatory:
|
|
383
|
+
|
|
384
|
+
```text
|
|
385
|
+
▚▞ SELECTOR HEALTH — e2e/checkout.spec.ts
|
|
386
|
+
|
|
387
|
+
[█████████████████░░░] 83 / 100
|
|
388
|
+
role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Lokatory oparte na rolach dostają pełną punktację. Łańcuchy klas CSS i
|
|
392
|
+
XPath toną w punktacji — łamią się przy każdym refactorze DOM, nie
|
|
393
|
+
mówiąc, które zachowanie zregresowało.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## 🔬 Dowody z runtime
|
|
398
|
+
|
|
399
|
+
Statyczna detekcja flakiness to zgadywanie. Mjölnir czyta **prawdziwe
|
|
400
|
+
dane wykonania** — raporty JSON Playwright i XML JUnit z dowolnego
|
|
401
|
+
runnera:
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
mjolnir forensics ./test-results/
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
```text
|
|
408
|
+
▚▞ FLAKINESS LEADERBOARD
|
|
409
|
+
|
|
410
|
+
3 tests · 1 failed · 1 flaky · 1 retried
|
|
411
|
+
|
|
412
|
+
TRUE-FLAKE completes checkout with saved card (e2e/checkout.spec.ts)
|
|
413
|
+
████████████████████ 6.0s · 2 attempts
|
|
414
|
+
FAILING declines an expired card (e2e/checkout.spec.ts)
|
|
415
|
+
████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Test, który przechodzi dopiero od próby ≥ 2, nie jest testem
|
|
419
|
+
przechodzącym — to szczęśliwy test. Zostaje oznaczony `TRUE-FLAKE`
|
|
420
|
+
niezależnie od finalnego zielonego checka.
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## ⚡ Mjölnir nie jest kolejnym linterem
|
|
425
|
+
|
|
426
|
+
Lintery mówią ci, czy kod trzyma się reguł. Mjölnir mówi ci, czy twoja
|
|
427
|
+
weryfikacja da się uznać za wiarygodną.
|
|
428
|
+
|
|
429
|
+
| | ESLint / SonarQube | Narzędzia coverage | Ręczny review | **Mjölnir** |
|
|
430
|
+
| ----------------------------------------------------------- | :----------------: | :----------------: | :-----------: | :---------: |
|
|
431
|
+
| Integralność workflow CI (`continue-on-error`, `\|\| true`) | ❌ | ❌ | rzadko | ✅ |
|
|
432
|
+
| Cross-językowo (TS, Python, Java, C#) z jednego narzędzia | ❌ | ❌ | ❌ | ✅ |
|
|
433
|
+
| Ocenia odporność lokatorów Playwright (Selector Health) | ❌ | ❌ | rzadko | ✅ |
|
|
434
|
+
| Wyłapuje testy bez prawdziwych asercji | ✅ (plugin)\* | ❌ | czasem | ✅ |
|
|
435
|
+
| Łapie twarde sleepy (`waitForTimeout`, `time.sleep`) | ✅ (plugin)\* | ❌ | czasem | ✅ |
|
|
436
|
+
| Działa w sekundy, zero wywołań sieciowych podczas skanu | ✅ | ✅ | — | ✅ |
|
|
437
|
+
|
|
438
|
+
\*`eslint-plugin-jest` (`expect-expect`) i `eslint-plugin-playwright`
|
|
439
|
+
(`expect-expect`, `no-wait-for-timeout`) pokrywają to dla swoich
|
|
440
|
+
frameworków.
|
|
441
|
+
|
|
442
|
+
**Analiza runtime** to osobna kategoria obok statycznego lintowania:
|
|
443
|
+
|
|
444
|
+
| | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
|
|
445
|
+
| ---------------------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
|
|
446
|
+
| Czyta prawdziwe dane przebiegów dla werdyktów `TRUE-FLAKE` | częściowo\* | częściowo (tag) | ✅ |
|
|
447
|
+
| Raport triażu flakiness z historii wykonania | ❌ | ✅ | ✅ |
|
|
448
|
+
| Integruje się ze statycznym wskaźnikiem wiarygodności | ❌ | ❌ | ✅ |
|
|
449
|
+
|
|
450
|
+
\*Playwright śledzi retry wewnętrznie, ale nie produkuje samodzielnego
|
|
451
|
+
raportu flakiness z etykietami werdyktów.
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 🤖 Czemu nie użyć po prostu AI code review?
|
|
456
|
+
|
|
457
|
+
Inny problem, inna warstwa. AI review może dostrzec podejrzaną zmianę
|
|
458
|
+
testu w diffie; nie dowodzi, że system weryfikacji jako całość jest
|
|
459
|
+
godny zaufania — i widzi tylko diff, który mu pokażesz.
|
|
460
|
+
|
|
461
|
+
| | AI code review (Copilot i in.) | **Mjölnir** |
|
|
462
|
+
| ------------------------------------------------- | :-------------------------------: | :-------------------------------: |
|
|
463
|
+
| Koszt na skan | Tokeny (rośnie z rozmiarem diffа) | **Zero** (lokalny, zainstalowany) |
|
|
464
|
+
| Widzi całą suitę + wszystkie configi CI | Tylko diff PR, który mu pokażesz | **Wszystko, za każdym razem** |
|
|
465
|
+
| Deterministyczny (ten sam input → ten sam output) | ❌ (niedeterministyczny) | **✅** |
|
|
466
|
+
| Łapie wzorce śpiące miesiącami | Tylko jeśli jest w kontekście | **✅** (skanuje wszystkie pliki) |
|
|
467
|
+
| Pamięta znaleziska między przebiegami | ❌ (brak pamięci między sesjami) | **✅** (baseline + diff) |
|
|
468
|
+
| Działa bez ludzkiego wyzwalacza | Potrzebuje PR-a albo promptu | **✅** (hak CI, 3 sekundy) |
|
|
469
|
+
|
|
470
|
+
**Używaj obu.** AI łapie niuans, intencję i wady projektowe, których
|
|
471
|
+
żaden regex nie znajdzie. Mjölnir łapie strukturalne wzorce, które AI
|
|
472
|
+
pomija, bo wyglądają „intencjonalnie" — committowany `.only`,
|
|
473
|
+
połknięty kod wyjścia, `continue-on-error` na jobie testowym. To nie
|
|
474
|
+
są bugi wymagające rozumowania; to fakty wymagające skanowania.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## 🤖 Integracja CI
|
|
479
|
+
|
|
480
|
+
Jedna komenda generuje workflow PR — domyślnie doradczy, nigdy
|
|
481
|
+
blokujący:
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
mjolnir ci install
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Albo podepnij go natywnie pod GitHub Code Scanning przez SARIF:
|
|
488
|
+
|
|
489
|
+
```yaml
|
|
490
|
+
- run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
|
|
491
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
492
|
+
with:
|
|
493
|
+
sarif_file: mjolnir.sarif
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Konfiguracja edytora i pipeline'u dla SARIF:
|
|
497
|
+
[docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
|
|
498
|
+
|
|
499
|
+
### Pokrycie changed-scope
|
|
500
|
+
|
|
501
|
+
`--scope changed` przypisuje znaleziska liniom dodanym w twoim branchu
|
|
502
|
+
względem merge-base z `main`. Pokrywa pliki testowe (`*.spec.*`,
|
|
503
|
+
`*.test.*`) plus pliki workflow GitHub i konfiguracje Playwright w
|
|
504
|
+
diffie. Gdy merge-base nie da się rozwiązać — shallow clone, detached
|
|
505
|
+
HEAD, cel spoza git, inny domyślny branch — degraduje się uczciwie:
|
|
506
|
+
znaleziska wracają do atrybucji na cały plik, a raport mówi o tym.
|
|
507
|
+
Nadpisz bazową ref przez `--base <ref>`.
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Konfiguracja
|
|
512
|
+
|
|
513
|
+
Mjölnir jest zero-config. Opcjonalny `mjolnir.config.json` (lub
|
|
514
|
+
`.mjolnir.json`) w korzeniu repo dostraja severity, gating i scope —
|
|
515
|
+
nigdy nie zmienia semantyki detekcji.
|
|
516
|
+
|
|
517
|
+
| Key | Typ | Działanie |
|
|
518
|
+
| ------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
519
|
+
| `exclude` | `string[]` | Dodatkowe globy ignorowania (podzbiór gitignore), na wierzchu wbudowanych domyślnych |
|
|
520
|
+
| `gate` | `"advisory" \| "error" \| "warning"` | Które severity kończą się kodem niezerowym (domyślnie `error`; `advisory` nigdy nie blokuje) |
|
|
521
|
+
| `severityOverrides` | `{ "<RULE-ID>": severity }` | Przerankowuje znaleziska reguły dla twojego repo |
|
|
522
|
+
| `ignore` | `IgnoreEntry[]` | Wycisza znaleziska — **`reason` jest wymagany**; wpisy wygasają po 90 dniach (jawna data `expires`, albo czas ostatniej modyfikacji pliku konfiga dla wpisów bez niej) |
|
|
523
|
+
| `plugins` | `string[]` | Zewnętrzne pakiety reguł (zob. [Model zaufania](#model-zaufania)) |
|
|
524
|
+
|
|
525
|
+
```json
|
|
526
|
+
{
|
|
527
|
+
"gate": "error",
|
|
528
|
+
"exclude": ["legacy/**"],
|
|
529
|
+
"severityOverrides": { "QA-PW-118": "warning" },
|
|
530
|
+
"ignore": [
|
|
531
|
+
{
|
|
532
|
+
"ruleId": "QA-TEST-004",
|
|
533
|
+
"files": ["e2e/legacy-login.spec.ts"],
|
|
534
|
+
"reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
|
|
535
|
+
"expires": "2026-12-31"
|
|
536
|
+
}
|
|
537
|
+
]
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
- **`.mjolnirignore`** — prosty plik w stylu gitignore dla wykluczeń
|
|
542
|
+
ścieżek, ten sam dialekt co `exclude`. Użyj go na szum maszynowy; użyj
|
|
543
|
+
`exclude`, gdy lista należy do kontroli wersji, obok reszty configa.
|
|
544
|
+
- **Override'y CLI** — `--strict` (dołącz reguły kwarantanny),
|
|
545
|
+
`--width <cols>` i `--ascii` / `--no-ascii` (render terminala),
|
|
546
|
+
`--tone blunt` (ostrejsze komunikaty), `--max-duration <sec>`
|
|
547
|
+
(ograniczony skan częściowy).
|
|
548
|
+
- Wyciszanie reguł i cykl życia deprecacji:
|
|
549
|
+
[docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
|
|
550
|
+
|
|
551
|
+
Wpisy `ignore` zasilają też samodzielną komendę `mjolnir suppressions`,
|
|
552
|
+
która wypisuje, co jest aktualnie wyciszone i kiedy wygasa każdy wpis.
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 📐 Kody wyjścia i kontrakty
|
|
557
|
+
|
|
558
|
+
Zamrożone — bezpieczna baza do budowania logiki CI:
|
|
559
|
+
|
|
560
|
+
| Kod wyjścia | Znaczenie |
|
|
561
|
+
| ----------- | ------------------------------------------------------------------------------- |
|
|
562
|
+
| `0` | Czysto — brak znalezisk na poziomie gate'a lub wyżej |
|
|
563
|
+
| `1` | Znaleziska na poziomie gate'a lub wyżej |
|
|
564
|
+
| `2` | Skan częściowy (wyczerpany budżet czasu, nieczytelne pliki) — nigdy nie blokuje |
|
|
565
|
+
| `10` | Błąd użycia (zły flag, brakujący cel) |
|
|
566
|
+
| `20` | Błąd wewnętrzny |
|
|
567
|
+
|
|
568
|
+
Raport JSON/SARIF to `schemaVersion: 1`. ID reguł (`QA-<FAMILY>-NNN`)
|
|
569
|
+
są niezmienne po wydaniu i nigdy nie są używane ponownie.
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Model zaufania
|
|
574
|
+
|
|
575
|
+
- **Local-first** — zero wywołań sieciowych podczas skanowania. Nigdy.
|
|
576
|
+
Zero telemetrii.
|
|
577
|
+
- **Żadnych fałszywych dowodów** — wolimy powiedzieć „nieznane" niż
|
|
578
|
+
„zweryfikowane". Puste repo dostaje `score: null`, nigdy fałszywej
|
|
579
|
+
setki.
|
|
580
|
+
- **Częściowa uczciwość** — jeśli analizę ucięto, wynik to mówi. Nigdy
|
|
581
|
+
„complete", gdy to nieprawda.
|
|
582
|
+
- **Zapora FP** — detekcja działa na widoku kodu wolnym od komentarzy i
|
|
583
|
+
stringów (reguły TypeScript używają AST kompilatora): wzorzec w
|
|
584
|
+
komentarzu prozatorskim czy doc- przykładzie-stringu to dokumentacja,
|
|
585
|
+
nie znalezisko.
|
|
586
|
+
- **Zmierzone, nie założone** — do tierów nagłówkowych trafiają tylko
|
|
587
|
+
reguły ze stopą fałszywych pozytywów z prawdziwego kodu OSS (zob.
|
|
588
|
+
[Ile z tego jest zmierzone](#ile-z-tego-jest-zmierzone)); stopka
|
|
589
|
+
skanu i `mjolnir rules --unmeasured` powiedzą ci, które które.
|
|
590
|
+
- **Zaufanie do pluginów** — pluginy to pakiety npm deklarowane pod
|
|
591
|
+
`"plugins"`. **Nie ma sandboxa**: kod pluginu działa z pełnymi
|
|
592
|
+
uprawnieniami Node, ten sam model zaufania co pluginy ESLint czy
|
|
593
|
+
Vitest. Prefiksy ID reguł core są zarezerwowane i odrzucane od
|
|
594
|
+
pluginów przeciw spoofingowi.
|
|
595
|
+
- **Zewnętrzne reguły lokalne wobec workspace'u** (folderowe, zero
|
|
596
|
+
sieci) — katalog `mjolnir-rules/` obok celu skanu ładuje własne
|
|
597
|
+
reguły: pliki JSON deklarują wzorce regex (żaden kod nie jest
|
|
598
|
+
wykonywany), moduły `.mjs`/`.js` eksportują `rules` (pełne zaufanie
|
|
599
|
+
Node, jak pluginy). Zewnętrzne reguły niosą te same metadane zaufania
|
|
600
|
+
co core; nie mogą nigdy wyjść w tierze core (core wymaga zmierzonej
|
|
601
|
+
stopy FP z sidecara korpusu — deklarowane `tier: "core"` jest
|
|
602
|
+
ściągane do `extended`), przestrzegają limitów tierów i są
|
|
603
|
+
sprawdzane na dryft: `mjolnir rules --md --external` renderuje
|
|
604
|
+
katalog z załadowanych plików (pochodzenie `external`), a generator
|
|
605
|
+
macierzy przyjmuje `--external <root>`.
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
## 🏗️ Architektura
|
|
610
|
+
|
|
611
|
+
<details>
|
|
612
|
+
<summary>Rozwiń drzewo</summary>
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
mjolnir/
|
|
616
|
+
├── src/
|
|
617
|
+
│ ├── engine/ # LanguageAdapter interface + rule runner
|
|
618
|
+
│ ├── adapters/ # typescript · python · java · csharp · github-actions
|
|
619
|
+
│ ├── rules/ # rules across 8 families + the measured-FP table
|
|
620
|
+
│ ├── playwright/ # Selector Health Score engine
|
|
621
|
+
│ ├── discovery/ # workspace, frameworks, ignore resolution
|
|
622
|
+
│ ├── scope/ # git merge-base changed-scope engine
|
|
623
|
+
│ ├── scorer/ # transparent deduction table + prioritization
|
|
624
|
+
│ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
|
|
625
|
+
│ ├── forensics/ # run-data ingestion · flake verdicts · triage
|
|
626
|
+
│ ├── config/ # mjolnir.config.json + suppressions
|
|
627
|
+
│ ├── plugins/ # third-party rule loading (no sandbox)
|
|
628
|
+
│ └── commands/ # every subcommand
|
|
629
|
+
└── tests/
|
|
630
|
+
├── fixtures/ # must-fire / must-not-fire per rule
|
|
631
|
+
└── golden/ # frozen score regression locks
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
</details>
|
|
635
|
+
|
|
636
|
+
- **Reguły to czyste funkcje** — `(SourceFileContext) → Finding[]`,
|
|
637
|
+
bez I/O, bez globali. Nowy ekosystem = jeden adapter + jego reguły.
|
|
638
|
+
- **TypeScript/Playwright używa AST kompilatora** (ts-morph). Python,
|
|
639
|
+
Java i C# działają na wspólnej warstwie regex z maskowaniem
|
|
640
|
+
komentarzy i stringów.
|
|
641
|
+
- Warstwa AST tree-sitter WASM dla Javy i C# istnieje i jest
|
|
642
|
+
następnym krokiem precyzji — nie jest jeszcze podpięta do
|
|
643
|
+
synchronicznego pipeline'u skanu.
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
## 📚 Dokumentacja
|
|
648
|
+
|
|
649
|
+
| Dokument | Co zawiera |
|
|
650
|
+
| ------------------------------------------------------ | ----------------------------------------------- |
|
|
651
|
+
| [docs/SCORING.md](docs/SCORING.md) | Normalizacja punktacji + ważenie dowodami |
|
|
652
|
+
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Zmierzone stopy fałszywych pozytywów + metodyka |
|
|
653
|
+
| [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Stany reguł, wyciszanie, deprecacja |
|
|
654
|
+
| [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Wyjście SARIF + konfiguracja edytora/CI |
|
|
655
|
+
| [docs/rules/](docs/rules/) | Generowany katalog per reguła |
|
|
656
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | Setup dev + workflow kontrybucji |
|
|
657
|
+
| [CHANGELOG.md](CHANGELOG.md) | Historia wydań |
|
|
658
|
+
| [SECURITY.md](SECURITY.md) | Zgłaszanie podatności |
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
## 📈 Status
|
|
663
|
+
|
|
664
|
+
**v0.5.x · otwarta beta.** Schemat JSON i kody wyjścia to zamrożone
|
|
665
|
+
kontrakty. TypeScript i Python mają najszersze zmierzone pokrycie; Java
|
|
666
|
+
i C# są nowsze — czytaj o nich przez
|
|
667
|
+
[tabelę tierów](#tiery-reguł-i-dojrzałość-językowa).
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## 🤝 Kontrybucja
|
|
672
|
+
|
|
673
|
+
Nowe reguły to najłatwiejszy pierwszy wkład — jedna komenda wystawia
|
|
674
|
+
szkielet reguły plus jej fixture must-fire **i** must-not-fire
|
|
675
|
+
(wygenerowana reguła celowo wypada na fixture'ach, dopóki nie
|
|
676
|
+
zaimplementujesz prawdziwej detekcji — stub nie może się wydać):
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
Pełny setup dev, komendy stałego gate'a oraz prawa anti-creep /
|
|
683
|
+
zapory fixture'owej są w [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
<div align="center">
|
|
688
|
+
|
|
689
|
+
**Przestań wydawać testy, którym nie możesz ufać.**
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
npx mjolnir-qa@latest
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
**Star ⭐ · Watch 👀 · Contribute 🤝**
|
|
696
|
+
|
|
697
|
+
Zbudowane przez [Sergeya Bara](https://www.linkedin.com/in/sergeybar/)
|
|
698
|
+
|
|
699
|
+
</div>
|