Skip to content

Commit 956fe62

Browse files
authored
feat: Add support for Playwright 1.50 (#347)
1 parent c269371 commit 956fe62

10 files changed

+180
-19
lines changed

src/rules/expect-expect.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ runRuleTester('expect-expect', rule, {
8383
});
8484
`,
8585
},
86+
{
87+
code: javascript`
88+
test.only('steps', async ({ page }) => {
89+
await test.step.skip('first tab', async () => {
90+
await expect(page.getByText('Hello')).toBeVisible();
91+
});
92+
});
93+
`,
94+
},
8695
{
8796
code: javascript`
8897
test('should fail', async ({ page }) => {

src/rules/missing-playwright-await.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,31 @@ const expectPlaywrightMatchers = [
3131
]
3232

3333
const playwrightTestMatchers = [
34+
'toBeAttached',
3435
'toBeChecked',
3536
'toBeDisabled',
3637
'toBeEditable',
3738
'toBeEmpty',
3839
'toBeEnabled',
3940
'toBeFocused',
4041
'toBeHidden',
42+
'toBeInViewport',
43+
'toBeOK',
4144
'toBeVisible',
4245
'toContainText',
46+
'toHaveAccessibleErrorMessage',
4347
'toHaveAttribute',
48+
'toHaveCSS',
4449
'toHaveClass',
4550
'toHaveCount',
46-
'toHaveCSS',
4751
'toHaveId',
4852
'toHaveJSProperty',
49-
'toBeOK',
5053
'toHaveScreenshot',
5154
'toHaveText',
5255
'toHaveTitle',
5356
'toHaveURL',
5457
'toHaveValue',
5558
'toHaveValues',
56-
'toBeAttached',
57-
'toBeInViewport',
5859
]
5960

6061
function getReportNode(node: ESTree.Node) {

src/rules/no-conditional-in-test.test.ts

+10
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ runRuleTester('no-conditional-in-test', rule, {
181181
`,
182182
errors: [{ column: 5, endColumn: 17, endLine: 3, line: 3, messageId }],
183183
},
184+
{
185+
code: javascript`
186+
test('test', async ({ page }) => {
187+
await test.step.skip('step', async () => {
188+
if (true) {}
189+
});
190+
});
191+
`,
192+
errors: [{ column: 5, endColumn: 17, endLine: 3, line: 3, messageId }],
193+
},
184194
{
185195
code: 'it("foo", () => { if (true) { expect(1).toBe(1); } });',
186196
errors: [{ column: 19, endColumn: 51, endLine: 1, line: 1, messageId }],

src/rules/no-nested-step.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ runRuleTester('max-nested-step', rule, {
3535
{ column: 11, endColumn: 20, endLine: 6, line: 6, messageId },
3636
],
3737
},
38+
{
39+
code: javascript`
40+
test('foo', async () => {
41+
await test.step("step1", async () => {
42+
await test.step("nested step1", async () => {
43+
await expect(true).toBe(true);
44+
});
45+
await test.step.skip("nested step2", async () => {
46+
await expect(true).toBe(true);
47+
});
48+
});
49+
});
50+
`,
51+
errors: [
52+
{ column: 11, endColumn: 20, endLine: 3, line: 3, messageId },
53+
{ column: 11, endColumn: 25, endLine: 6, line: 6, messageId },
54+
],
55+
},
3856
// Global aliases
3957
{
4058
code: javascript`
@@ -57,6 +75,7 @@ runRuleTester('max-nested-step', rule, {
5775
valid: [
5876
'await test.step("step1", () => {});',
5977
'await test.step("step1", async () => {});',
78+
'await test.step.skip("step1", async () => {});',
6079
{
6180
code: javascript`
6281
test('foo', async () => {
@@ -85,6 +104,18 @@ runRuleTester('max-nested-step', rule, {
85104
});
86105
`,
87106
},
107+
{
108+
code: javascript`
109+
test('foo', async () => {
110+
await test.step("step1", async () => {
111+
await expect(true).toBe(true);
112+
});
113+
await test.step.skip("step2", async () => {
114+
await expect(true).toBe(true);
115+
});
116+
});
117+
`,
118+
},
88119
// Global aliases
89120
{
90121
code: 'await it.step("step1", () => {});',

src/rules/no-nested-step.ts

+9-14
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
import { Rule } from 'eslint'
2-
import ESTree from 'estree'
3-
import { isPropertyAccessor } from '../utils/ast.js'
42
import { createRule } from '../utils/createRule.js'
5-
6-
function isStepCall(node: ESTree.Node): boolean {
7-
const inner = node.type === 'CallExpression' ? node.callee : node
8-
9-
if (inner.type !== 'MemberExpression') {
10-
return false
11-
}
12-
13-
return isPropertyAccessor(inner, 'step')
14-
}
3+
import { isTypeOfFnCall } from '../utils/parseFnCall.js'
154

165
export default createRule({
176
create(context) {
187
const stack: number[] = []
198

209
function pushStepCallback(node: Rule.Node) {
21-
if (node.parent.type !== 'CallExpression' || !isStepCall(node.parent)) {
10+
if (
11+
node.parent.type !== 'CallExpression' ||
12+
!isTypeOfFnCall(context, node.parent, ['step'])
13+
) {
2214
return
2315
}
2416

@@ -35,7 +27,10 @@ export default createRule({
3527
function popStepCallback(node: Rule.Node) {
3628
const { parent } = node
3729

38-
if (parent.type === 'CallExpression' && isStepCall(parent)) {
30+
if (
31+
parent.type === 'CallExpression' &&
32+
isTypeOfFnCall(context, parent, ['step'])
33+
) {
3934
stack.pop()
4035
}
4136
}

src/rules/no-skipped-test.test.ts

+56
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,62 @@ runRuleTester('no-skipped-test', rule, {
247247
},
248248
},
249249
},
250+
{
251+
code: 'test.step.skip("a step", async () => {});',
252+
errors: [
253+
{
254+
column: 11,
255+
endColumn: 15,
256+
line: 1,
257+
messageId: 'noSkippedTest',
258+
suggestions: [
259+
{
260+
messageId,
261+
output: 'test.step("a step", async () => {});',
262+
},
263+
],
264+
},
265+
],
266+
},
267+
{
268+
code: 'test.step.skip("a step", async () => {}, { timeout: 1000 });',
269+
errors: [
270+
{
271+
column: 11,
272+
endColumn: 15,
273+
line: 1,
274+
messageId: 'noSkippedTest',
275+
suggestions: [
276+
{
277+
messageId,
278+
output: 'test.step("a step", async () => {}, { timeout: 1000 });',
279+
},
280+
],
281+
},
282+
],
283+
},
284+
{
285+
code: 'it.step.skip("a step", async () => {});',
286+
errors: [
287+
{
288+
column: 9,
289+
endColumn: 13,
290+
line: 1,
291+
messageId: 'noSkippedTest',
292+
suggestions: [
293+
{
294+
messageId,
295+
output: 'it.step("a step", async () => {});',
296+
},
297+
],
298+
},
299+
],
300+
settings: {
301+
playwright: {
302+
globalAliases: { test: ['it'] },
303+
},
304+
},
305+
},
250306
],
251307
valid: [
252308
'test("a test", () => {});',

src/rules/no-skipped-test.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ export default createRule({
1010
const allowConditional = !!options.allowConditional
1111

1212
const call = parseFnCall(context, node)
13-
if (call?.group !== 'test' && call?.group !== 'describe') {
13+
if (
14+
call?.group !== 'test' &&
15+
call?.group !== 'describe' &&
16+
call?.group !== 'step'
17+
) {
1418
return
1519
}
1620

src/rules/valid-title.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ runRuleTester('valid-title', rule, {
7575
],
7676
options: [{ disallowedWords: ['properly'] }],
7777
},
78+
{
79+
code: 'test.step.skip(`that the value is set properly`, function () {})',
80+
errors: [
81+
{
82+
column: 16,
83+
data: { word: 'properly' },
84+
line: 1,
85+
messageId: 'disallowedWord',
86+
},
87+
],
88+
options: [{ disallowedWords: ['properly'] }],
89+
},
7890
// Global aliases
7991
{
8092
code: 'it("the correct way to properly handle all things", () => {});',

src/utils/parseFnCall.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,48 @@ runRuleTester('test', rule, {
511511
},
512512
],
513513
},
514+
{
515+
code: 'test.step.skip("a step", () => {});',
516+
errors: [
517+
{
518+
column: 1,
519+
data: expectedParsedFnCallResultData({
520+
group: 'step',
521+
head: {
522+
local: 'test',
523+
node: 'test',
524+
original: null,
525+
},
526+
members: ['step', 'skip'],
527+
name: 'step',
528+
type: 'step',
529+
}),
530+
line: 1,
531+
messageId: 'details',
532+
},
533+
],
534+
},
535+
{
536+
code: 'test.step("a step", () => {}, { timeout: 1000 });',
537+
errors: [
538+
{
539+
column: 1,
540+
data: expectedParsedFnCallResultData({
541+
group: 'step',
542+
head: {
543+
local: 'test',
544+
node: 'test',
545+
original: null,
546+
},
547+
members: ['step'],
548+
name: 'step',
549+
type: 'step',
550+
}),
551+
line: 1,
552+
messageId: 'details',
553+
},
554+
],
555+
},
514556
{
515557
code: 'test.only("a test", () => {});',
516558
errors: [

src/utils/parseFnCall.ts

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const VALID_CHAINS = new Set([
6363
'test.only',
6464
'test.skip',
6565
'test.step',
66+
'test.step.skip',
6667
'test.slow',
6768
'test.use',
6869
])

0 commit comments

Comments
 (0)