@slip-stream-kit/eslint-plugin 0.13.0 → 0.15.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/dist/index.js +762 -35
- package/dist/index.js.map +4 -4
- package/dist/rules/e2e-describe-order/e2e-describe-order.d.ts +6 -0
- package/dist/rules/e2e-describe-order/index.d.ts +1 -0
- package/dist/rules/e2e-file-order/e2e-file-order.d.ts +6 -0
- package/dist/rules/e2e-file-order/index.d.ts +1 -0
- package/dist/rules/e2e-page-object-member-order/e2e-page-object-member-order.d.ts +6 -0
- package/dist/rules/e2e-page-object-member-order/index.d.ts +1 -0
- package/dist/rules/e2e-top-level-describe/e2e-top-level-describe.d.ts +8 -0
- package/dist/rules/e2e-top-level-describe/index.d.ts +1 -0
- package/dist/utils/attached-comments.d.ts +11 -0
- package/dist/utils/playwright-call.d.ts +5 -1
- package/package.json +2 -2
- package/readme.md +123 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { e2eDescribeOrder } from './e2e-describe-order';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { e2eFileOrder } from './e2e-file-order';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { e2ePageObjectMemberOrder } from './e2e-page-object-member-order';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
export interface Options {
|
|
3
|
+
/** Globs; the rule is skipped for matching files. */
|
|
4
|
+
ignore?: string[];
|
|
5
|
+
/** Top-level `test.describe` blocks a spec may hold. */
|
|
6
|
+
max?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const e2eTopLevelDescribe: Rule.RuleModule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { e2eTopLevelDescribe } from './e2e-top-level-describe';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SourceCode } from 'eslint';
|
|
2
|
+
import type * as ESTree from 'estree';
|
|
3
|
+
/**
|
|
4
|
+
* Where `node` starts once its attached leading comments are included: the unbroken run of comments
|
|
5
|
+
* directly above it, each on the line after the previous one ends. A comment separated by a blank
|
|
6
|
+
* line (a file overview, a section banner) stays behind when the node moves.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* attachedStart(sourceCode, node) // => range start of the JSDoc right above `node`, else of `node`
|
|
10
|
+
*/
|
|
11
|
+
export declare const attachedStart: (sourceCode: SourceCode, node: ESTree.Node) => number;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
|
-
import type { CallExpression, ObjectExpression } from 'estree';
|
|
2
|
+
import type { CallExpression, Expression, Node, ObjectExpression } from 'estree';
|
|
3
3
|
export type PlaywrightCallKind = 'test' | 'describe';
|
|
4
|
+
/** `test.describe.serial` → `['test', 'describe', 'serial']`; null for anything but a plain name chain. */
|
|
5
|
+
export declare const calleeNames: (callee: Expression | Node) => string[] | null;
|
|
4
6
|
/**
|
|
5
7
|
* Whether `node` declares a Playwright test or describe block, read from its callee alone.
|
|
6
8
|
*
|
|
@@ -13,4 +15,6 @@ export declare const detailsArgument: (node: CallExpression) => ObjectExpression
|
|
|
13
15
|
/** A title that is a plain string: a literal, or a template without expressions. */
|
|
14
16
|
export declare const staticTitle: (node: CallExpression) => string | null;
|
|
15
17
|
/** True when the linted file belongs to a package whose type resolves to `e2e`. */
|
|
18
|
+
/** The callee chain of a top-level `test.*(…)` statement, e.g. `['test', 'describe', 'configure']`. */
|
|
19
|
+
export declare const testStatementNames: (statement: Node) => string[] | null;
|
|
16
20
|
export declare const isInE2ePackage: (context: Rule.RuleContext) => boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slip-stream-kit/eslint-plugin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ArthurSaenz/infra-kit.git",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"eslint": ">=9"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@slip-stream-kit/config": "0.
|
|
44
|
+
"@slip-stream-kit/config": "0.15.0",
|
|
45
45
|
"@types/node": "^26.5.1",
|
|
46
46
|
"@typescript-eslint/parser": "^8.70.0",
|
|
47
47
|
"@wl/eslint-config": "0.1.0",
|
package/readme.md
CHANGED
|
@@ -698,6 +698,129 @@ resolved the same way `package-structure` resolves it.
|
|
|
698
698
|
| -------- | ---------- | ------- | ---------------------------------------------- |
|
|
699
699
|
| `ignore` | `string[]` | `[]` | Globs; the rule is skipped for matching files. |
|
|
700
700
|
|
|
701
|
+
### `e2e-file-order`
|
|
702
|
+
|
|
703
|
+
Open every **e2e** source file with its main content, so a reader sees it right after the imports:
|
|
704
|
+
`*.page.ts` / `*.component.ts` open with the class, `*.fixture.ts` with the fixtures type and the
|
|
705
|
+
`export const test = base.extend<…>(…)` call, `*.spec.ts` with its first `test.*` call
|
|
706
|
+
(`test.describe`, `test.use`, `test.describe.configure`, …), `*.mock.ts` with its first exported
|
|
707
|
+
function. Constants, helpers and types declared between the imports and that anchor are reported by
|
|
708
|
+
name. A file under a `lib/` folder opens with its exports: a private declaration above any export
|
|
709
|
+
(an `export { … }` list counts) is reported the same way:
|
|
710
|
+
|
|
711
|
+
```
|
|
712
|
+
`CART_URL` sits between the imports and class `CartPage`. Move it below class `CartPage`: a page object file opens with its imports, then the class. The autofix moves it to the end of the file.
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
A `const` is not hoisted, so a binding read **while the module loads** stays above the anchor and is
|
|
716
|
+
not reported: a `describe` title, `test.use({…})`, a loop or `forEach` inside a `describe` body, a
|
|
717
|
+
`static` class field, an `extend` option default like `[DEFAULT_LOCALE, { option: true }]` — and
|
|
718
|
+
anything a kept binding reads. Reads inside `test(…)` bodies, hooks, fixture functions, methods and
|
|
719
|
+
instance fields run later and do not pin a binding. `--fix` moves the reported statements, with
|
|
720
|
+
their attached comments and in their original order, to the end of the file; a comment separated
|
|
721
|
+
from the statement by a blank line (a file overview) stays where it is. `*.data.ts` files and
|
|
722
|
+
packages of any other type are not judged.
|
|
723
|
+
|
|
724
|
+
```js
|
|
725
|
+
{
|
|
726
|
+
rules: {
|
|
727
|
+
'@wl/e2e-file-order': 'error',
|
|
728
|
+
},
|
|
729
|
+
}
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
#### Options
|
|
733
|
+
|
|
734
|
+
| Option | Type | Default | Description |
|
|
735
|
+
| -------- | ---------- | ------- | ---------------------------------------------- |
|
|
736
|
+
| `ignore` | `string[]` | `[]` | Globs; the rule is skipped for matching files. |
|
|
737
|
+
|
|
738
|
+
### `e2e-page-object-member-order`
|
|
739
|
+
|
|
740
|
+
Order the members of an **e2e** page object class (`*.page.ts`, `*.component.ts`): fields, the
|
|
741
|
+
constructor, getters, public methods, then private methods. A private or protected getter counts as a
|
|
742
|
+
private method. A property is a field even when it holds an arrow function, since properties
|
|
743
|
+
initialize in source order. Each member out of place is reported with the one it follows:
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
The public method `goto` comes after the private method `waitForPageList` in class `Catalog2Page`. Order a page object: fields, constructor, getters, public methods, private methods.
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
`--fix` reorders the class body in one pass. The sort is stable, so members of one group keep their
|
|
750
|
+
relative order, and each member moves with its attached comments.
|
|
751
|
+
|
|
752
|
+
```js
|
|
753
|
+
{
|
|
754
|
+
rules: {
|
|
755
|
+
'@wl/e2e-page-object-member-order': 'error',
|
|
756
|
+
},
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
#### Options
|
|
761
|
+
|
|
762
|
+
| Option | Type | Default | Description |
|
|
763
|
+
| -------- | ---------- | ------- | ---------------------------------------------- |
|
|
764
|
+
| `ignore` | `string[]` | `[]` | Globs; the rule is skipped for matching files. |
|
|
765
|
+
|
|
766
|
+
### `e2e-describe-order`
|
|
767
|
+
|
|
768
|
+
Order the body of every `test.describe` in an **e2e** spec: setup first (`test.use`,
|
|
769
|
+
`test.describe.configure`, `test.setTimeout`, `test.slow`, and `test.skip` / `fixme` / `fail` used
|
|
770
|
+
as a condition, not as a test), then hooks `beforeAll` → `beforeEach` → `afterEach` → `afterAll`,
|
|
771
|
+
then tests and nested describes. Statements that are not `test.*` calls are ignored.
|
|
772
|
+
|
|
773
|
+
```
|
|
774
|
+
`test.use` (setup) comes after `test('shows the total')` (test) in describe 'Cart'. Order a describe body: `test.use` / `test.describe.configure` / annotations, then hooks beforeAll → beforeEach → afterEach → afterAll, then tests and nested describes.
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
There is no autofix: moving `test.use({ … })` up past a `const` it reads would put the read in the
|
|
778
|
+
`const`'s TDZ.
|
|
779
|
+
|
|
780
|
+
```js
|
|
781
|
+
{
|
|
782
|
+
rules: {
|
|
783
|
+
'@wl/e2e-describe-order': 'error',
|
|
784
|
+
},
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
#### Options
|
|
789
|
+
|
|
790
|
+
| Option | Type | Default | Description |
|
|
791
|
+
| -------- | ---------- | ------- | ---------------------------------------------- |
|
|
792
|
+
| `ignore` | `string[]` | `[]` | Globs; the rule is skipped for matching files. |
|
|
793
|
+
|
|
794
|
+
### `e2e-top-level-describe`
|
|
795
|
+
|
|
796
|
+
Hold an **e2e** spec to one top-level `test.describe`, with its setup, hooks and tests inside it:
|
|
797
|
+
|
|
798
|
+
```
|
|
799
|
+
`test.describe('Cart Mutations')` is top-level describe number 2 in this spec; the limit is 1. Move it to its own spec file, or nest it inside `test.describe('Cart')`.
|
|
800
|
+
`test.use` sits at the top level of the spec. Move it inside `test.describe('Cart')`: a spec holds one top-level describe, and its setup, hooks and tests live inside it.
|
|
801
|
+
Test 'shows the total' sits at the top level of the spec. Wrap the spec’s tests in a `test.describe` named after the feature they cover.
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
When the spec has exactly one top-level describe, `--fix` moves every top-level `test.use`,
|
|
805
|
+
`test.describe.configure`, hook and annotation to the start of its body, in source order and with
|
|
806
|
+
their attached comments; with one describe they apply to the same tests either way. An extra
|
|
807
|
+
describe or a top-level test needs a person: split the file, nest the describe, or wrap the tests.
|
|
808
|
+
|
|
809
|
+
```js
|
|
810
|
+
{
|
|
811
|
+
rules: {
|
|
812
|
+
'@wl/e2e-top-level-describe': ['error', { max: 1 }],
|
|
813
|
+
},
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
#### Options
|
|
818
|
+
|
|
819
|
+
| Option | Type | Default | Description |
|
|
820
|
+
| -------- | ---------- | ------- | ------------------------------------------------- |
|
|
821
|
+
| `max` | `integer` | `1` | Top-level `test.describe` blocks a spec may hold. |
|
|
822
|
+
| `ignore` | `string[]` | `[]` | Globs; the rule is skipped for matching files. |
|
|
823
|
+
|
|
701
824
|
### `e2e-test-tags`
|
|
702
825
|
|
|
703
826
|
Restrict the tags on Playwright `test(…)` and `test.describe(…)` calls in an **e2e package** to an
|