eslint-plugin-test-governance 0.1.0 → 0.2.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/CHANGELOG.md +84 -0
- package/LICENSE +1 -1
- package/README.md +69 -50
- package/dist/index.d.ts +7 -2
- package/dist/index.js +27 -16
- package/dist/rules/marker-matches-state.js +4 -4
- package/dist/rules/no-conflicting-states.js +14 -7
- package/dist/rules/no-orphaned-marker.js +16 -4
- package/dist/rules/require-ticket-in-comments.d.ts +3 -0
- package/dist/rules/require-ticket-in-comments.js +96 -0
- package/dist/rules/require-ticket.d.ts +1 -1
- package/dist/rules/require-ticket.js +5 -3
- package/dist/utils/analyze.d.ts +34 -4
- package/dist/utils/analyze.js +141 -47
- package/dist/utils/constants.d.ts +10 -0
- package/dist/utils/constants.js +18 -0
- package/dist/utils/create-rule.d.ts +10 -5
- package/dist/utils/create-rule.js +3 -4
- package/dist/utils/errors.d.ts +5 -0
- package/dist/utils/errors.js +8 -0
- package/dist/utils/fix.js +4 -2
- package/dist/utils/options.d.ts +36 -23
- package/dist/utils/options.js +28 -36
- package/dist/utils/schema.d.ts +3 -3
- package/dist/utils/schema.js +40 -31
- package/dist/utils/tickets.js +9 -1
- package/dist/utils/validate.d.ts +21 -0
- package/dist/utils/validate.js +122 -0
- package/docs/rules/marker-matches-state.md +4 -1
- package/docs/rules/no-conflicting-states.md +5 -1
- package/docs/rules/no-orphaned-marker.md +24 -2
- package/docs/rules/require-ticket-in-comments.md +80 -0
- package/docs/rules/require-ticket.md +31 -21
- package/package.json +17 -7
|
@@ -13,14 +13,14 @@ at the ticket that explains it, so disabled tests show up in planning instead of
|
|
|
13
13
|
|
|
14
14
|
A test is in a state when it is:
|
|
15
15
|
|
|
16
|
-
| State
|
|
17
|
-
|
|
|
18
|
-
| `skip`
|
|
19
|
-
| `fixme`
|
|
20
|
-
| `new`
|
|
21
|
-
| `unstable`
|
|
22
|
-
| `fail`, `slow` | `test.fail(...)`, `test.slow()`
|
|
23
|
-
| custom
|
|
16
|
+
| State | Put there by | Marker | On by default |
|
|
17
|
+
| -------------- | ------------------------------------------------------------------------------------------ | ---------------------- | -------------------------- |
|
|
18
|
+
| `skip` | `test.skip('title', fn)`, `test.describe.skip`, `test.skip()` in a body, `testInfo.skip()` | `// SKIP:` | yes |
|
|
19
|
+
| `fixme` | `test.fixme(...)`, `test.describe.fixme`, `testInfo.fixme()` | `// FIXME:` | yes |
|
|
20
|
+
| `new` | the `@new` tag | `// NEW:` | with `lifecycleTags: true` |
|
|
21
|
+
| `unstable` | the `@unstable` tag | `// UNSTABLE:` | with `lifecycleTags: true` |
|
|
22
|
+
| `fail`, `slow` | `test.fail(...)`, `test.slow()` | `// FAIL:`, `// SLOW:` | no |
|
|
23
|
+
| custom | any tag you list in `customStates` | your keyword | when configured |
|
|
24
24
|
|
|
25
25
|
Tags are read from the title (`'checkout @new'`) and from `{ tag: '@new' }` or `{ tag: ['@new', '@smoke'] }`.
|
|
26
26
|
Tags on a `describe` apply to every test inside it.
|
|
@@ -47,51 +47,58 @@ Tags on a `describe` apply to every test inside it.
|
|
|
47
47
|
|
|
48
48
|
How ticket lists are read:
|
|
49
49
|
|
|
50
|
-
| Marker
|
|
51
|
-
|
|
|
52
|
-
| `// SKIP: WEB-1, WEB-2` or `// SKIP: WEB-1,WEB-2`
|
|
53
|
-
| `// SKIP: WEB-1 , WEB-2 `
|
|
50
|
+
| Marker | Result |
|
|
51
|
+
| ------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
52
|
+
| `// SKIP: WEB-1, WEB-2` or `// SKIP: WEB-1,WEB-2` | two tickets |
|
|
53
|
+
| `// SKIP: WEB-1 , WEB-2 ` | two tickets; extra spaces are fine |
|
|
54
54
|
| `// SKIP: https://acme.atlassian.net/browse/WEB-1?focusedCommentId=5#comment-5` | one ticket; query strings and fragments are part of a URL |
|
|
55
|
-
| `// SKIP: WEB-1 flaky on CI`, `// SKIP: WEB-1: flaky`
|
|
56
|
-
| `// SKIP: WEB-1,` or `// SKIP: WEB-1.`
|
|
57
|
-
| `// SKIP: WEB-1 and WEB-2`
|
|
58
|
-
| `// SKIP: WEB-1;WEB-2`, `// SKIP: WEB-1/WEB-2`
|
|
59
|
-
| `// SKIP: flaky on CI`
|
|
55
|
+
| `// SKIP: WEB-1 flaky on CI`, `// SKIP: WEB-1: flaky` | extra text `flaky on CI` / `: flaky` |
|
|
56
|
+
| `// SKIP: WEB-1,` or `// SKIP: WEB-1.` | extra text `,` / `.` |
|
|
57
|
+
| `// SKIP: WEB-1 and WEB-2` | extra text `and WEB-2`; separate tickets with commas |
|
|
58
|
+
| `// SKIP: WEB-1;WEB-2`, `// SKIP: WEB-1/WEB-2` | invalid ticket, since only commas separate tickets |
|
|
59
|
+
| `// SKIP: flaky on CI` | invalid ticket `flaky`: the first word must be a ticket |
|
|
60
60
|
|
|
61
61
|
In a block comment, only the marker line is checked, so a JSDoc block can explain the skip on other
|
|
62
62
|
lines. Extra text is reported only once the tickets on that line are valid.
|
|
63
63
|
|
|
64
64
|
Conditional skips such as `test.skip(browserName === 'webkit', 'Not supported')` usually describe a
|
|
65
65
|
permanent platform limit, so they need no ticket unless you set `requireTicketForConditional: true`.
|
|
66
|
+
A runtime skip under an `if`, a `switch` case, a ternary or `&&` counts as conditional too, since
|
|
67
|
+
`if (!enabled) test.skip()` does the same as `test.skip(!enabled)`.
|
|
66
68
|
|
|
67
69
|
## Examples
|
|
68
70
|
|
|
69
71
|
Incorrect:
|
|
70
72
|
|
|
71
73
|
<!-- example: invalid -->
|
|
74
|
+
|
|
72
75
|
```js
|
|
73
76
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
74
77
|
```
|
|
75
78
|
|
|
76
79
|
<!-- example: invalid -->
|
|
80
|
+
|
|
77
81
|
```js
|
|
78
82
|
// SKIP: flaky on CI
|
|
79
83
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
<!-- example: invalid -->
|
|
87
|
+
|
|
83
88
|
```js
|
|
84
89
|
// SKIP: TODO
|
|
85
90
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
86
91
|
```
|
|
87
92
|
|
|
88
93
|
<!-- example: invalid -->
|
|
94
|
+
|
|
89
95
|
```js
|
|
90
96
|
// SKIP: WEB-481 payment sandbox is down
|
|
91
97
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
92
98
|
```
|
|
93
99
|
|
|
94
100
|
<!-- example: invalid settings={"lifecycleTags":true} -->
|
|
101
|
+
|
|
95
102
|
```js
|
|
96
103
|
test('one-click reorder @new', async ({ page }) => {});
|
|
97
104
|
```
|
|
@@ -99,12 +106,14 @@ test('one-click reorder @new', async ({ page }) => {});
|
|
|
99
106
|
Correct:
|
|
100
107
|
|
|
101
108
|
<!-- example: valid -->
|
|
109
|
+
|
|
102
110
|
```js
|
|
103
111
|
// SKIP: WEB-481
|
|
104
112
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
105
113
|
```
|
|
106
114
|
|
|
107
115
|
<!-- example: valid -->
|
|
116
|
+
|
|
108
117
|
```js
|
|
109
118
|
// FIXME: WEB-12
|
|
110
119
|
test.describe.fixme('tax rules', () => {
|
|
@@ -114,6 +123,7 @@ test.describe.fixme('tax rules', () => {
|
|
|
114
123
|
```
|
|
115
124
|
|
|
116
125
|
<!-- example: valid -->
|
|
126
|
+
|
|
117
127
|
```js
|
|
118
128
|
test('opens the dashboard', async ({ page, browserName }) => {
|
|
119
129
|
test.skip(browserName === 'webkit', 'Layout differs on WebKit by design');
|
|
@@ -121,12 +131,14 @@ test('opens the dashboard', async ({ page, browserName }) => {
|
|
|
121
131
|
```
|
|
122
132
|
|
|
123
133
|
<!-- example: valid settings={"allowNotes":true} -->
|
|
134
|
+
|
|
124
135
|
```js
|
|
125
136
|
// SKIP: WEB-481 payment sandbox is down
|
|
126
137
|
test.skip('pays with PayPal', async ({ page }) => {});
|
|
127
138
|
```
|
|
128
139
|
|
|
129
140
|
<!-- example: valid settings={"lifecycleTags":true} -->
|
|
141
|
+
|
|
130
142
|
```js
|
|
131
143
|
// NEW: WEB-77
|
|
132
144
|
test('one-click reorder', { tag: '@new' }, async ({ page }) => {});
|
|
@@ -134,7 +146,5 @@ test('one-click reorder', { tag: '@new' }, async ({ page }) => {});
|
|
|
134
146
|
|
|
135
147
|
## Options
|
|
136
148
|
|
|
137
|
-
This rule reads the shared options described in the
|
|
138
|
-
with `testGovernance.configure({...})`.
|
|
139
|
-
overrides the shared settings for this rule only.
|
|
140
|
-
|
|
149
|
+
This rule has no options of its own. It reads the shared options described in the
|
|
150
|
+
[README](../../README.md#options), usually set once with `testGovernance.configure({...})`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-test-governance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "ESLint rules that require a ticket comment above skipped, fixme and tagged Playwright tests.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"url": "git+https://github.com/Huldoser/eslint-plugin-test-governance.git"
|
|
19
19
|
},
|
|
20
20
|
"license": "MIT",
|
|
21
|
-
"author": "Andrey",
|
|
21
|
+
"author": "Andrey Rychkov",
|
|
22
22
|
"type": "module",
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
@@ -32,20 +32,25 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
34
|
"!dist/**/*.map",
|
|
35
|
-
"docs"
|
|
35
|
+
"docs",
|
|
36
|
+
"CHANGELOG.md"
|
|
36
37
|
],
|
|
37
38
|
"engines": {
|
|
38
|
-
"node": ">=22"
|
|
39
|
+
"node": ">=22.12"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|
|
41
|
-
"build": "
|
|
42
|
-
"typecheck": "tsc -p tsconfig.
|
|
42
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
43
44
|
"test": "vitest run",
|
|
44
45
|
"test:coverage": "vitest run --coverage",
|
|
45
46
|
"test:pack": "node scripts/pack-smoke.mjs",
|
|
46
47
|
"docs": "npm run build && eslint-doc-generator",
|
|
47
48
|
"docs:check": "npm run build && eslint-doc-generator --check",
|
|
48
|
-
"prepack": "npm run build"
|
|
49
|
+
"prepack": "npm run build",
|
|
50
|
+
"lint": "eslint .",
|
|
51
|
+
"lint:fix": "eslint . --fix",
|
|
52
|
+
"format": "prettier --write .",
|
|
53
|
+
"format:check": "prettier --check ."
|
|
49
54
|
},
|
|
50
55
|
"peerDependencies": {
|
|
51
56
|
"eslint": "^9.0.0 || ^10.0.0"
|
|
@@ -56,8 +61,13 @@
|
|
|
56
61
|
"@typescript-eslint/utils": "^8.71.0",
|
|
57
62
|
"@vitest/coverage-v8": "^5.0.2",
|
|
58
63
|
"eslint": "^10.11.0",
|
|
64
|
+
"eslint-config-prettier": "^10.1.8",
|
|
59
65
|
"eslint-doc-generator": "^3.7.1",
|
|
66
|
+
"eslint-plugin-eslint-plugin": "^7.6.2",
|
|
67
|
+
"globals": "^17.13.0",
|
|
68
|
+
"prettier": "^3.9.9",
|
|
60
69
|
"typescript": "6.0",
|
|
70
|
+
"typescript-eslint": "^8.71.0",
|
|
61
71
|
"vitest": "^5.0.2"
|
|
62
72
|
}
|
|
63
73
|
}
|