Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for custom rule messages #280

Merged
merged 5 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export default [
}
```

## Settings

### Aliased Playwright Globals

If you import Playwright globals (e.g. `test`, `expect`) with a custom name, you
Expand All @@ -129,6 +131,27 @@ can configure this plugin to be aware of these additional names.
}
```

### Custom Messages

You can customize the error messages for rules using the
`settings.playwright.messages` property. This is useful if you would like to
increase the verbosity of error messages or provide additional context.

Only the message ids you define in this setting will be overridden, so any other
messages will use the default message defined by the plugin.

```json
{
"settings": {
"playwright": {
"messages": {
"conditionalExpect": "Avoid conditional expects as they can lead to false positives"
}
}
}
}
```

## Rules

✅ Set in the `recommended` configuration\
Expand Down
6 changes: 3 additions & 3 deletions src/rules/expect-expect.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Rule } from 'eslint'
import ESTree from 'estree'
import { dig } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { parseFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
const options = {
assertFunctionNames: [] as string[],
Expand Down Expand Up @@ -69,4 +69,4 @@ export default {
],
type: 'problem',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/max-expects.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Rule } from 'eslint'
import * as ESTree from 'estree'
import { getParent } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { isTypeOfFnCall, parseFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
const options = {
max: 5,
Expand Down Expand Up @@ -78,4 +78,4 @@ export default {
],
type: 'suggestion',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/max-nested-describe.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Rule } from 'eslint'
import * as ESTree from 'estree'
import { createRule } from '../utils/createRule'
import { isTypeOfFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
const { options } = context
const max: number = options[0]?.max ?? 5
Expand Down Expand Up @@ -57,4 +57,4 @@ export default {
],
type: 'suggestion',
},
} as Rule.RuleModule
})
5 changes: 3 additions & 2 deletions src/rules/missing-playwright-await.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Rule } from 'eslint'
import ESTree from 'estree'
import { getParent, getStringValue, isIdentifier } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { ParsedFnCall, parseFnCall } from '../utils/parseFnCall'

const validTypes = new Set([
Expand Down Expand Up @@ -81,7 +82,7 @@ function getCallType(call: ParsedFnCall, awaitableMatchers: Set<string>) {
}
}

export default {
export default createRule({
create(context) {
const options = context.options[0] || {}
const awaitableMatchers = new Set([
Expand Down Expand Up @@ -182,4 +183,4 @@ export default {
],
type: 'problem',
},
} as Rule.RuleModule
})
5 changes: 3 additions & 2 deletions src/rules/no-commented-out-tests.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Rule } from 'eslint'
import * as ESTree from 'estree'
import { createRule } from '../utils/createRule'

function getTestNames(context: Rule.RuleContext) {
const aliases = context.settings.playwright?.globalAliases?.test ?? []
Expand All @@ -16,7 +17,7 @@ function hasTests(context: Rule.RuleContext, node: ESTree.Comment) {
return regex.test(node.value)
}

export default {
export default createRule({
create(context) {
function checkNode(node: ESTree.Comment) {
if (!hasTests(context, node)) return
Expand Down Expand Up @@ -45,4 +46,4 @@ export default {
},
type: 'problem',
},
} as Rule.RuleModule
})
5 changes: 3 additions & 2 deletions src/rules/no-conditional-expect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Rule, Scope } from 'eslint'
import * as ESTree from 'estree'
import { getParent, isPropertyAccessor } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { isTypeOfFnCall, parseFnCall } from '../utils/parseFnCall'
import { KnownCallExpression } from '../utils/types'

Expand Down Expand Up @@ -30,7 +31,7 @@ const getTestCallExpressionsFromDeclaredVariables = (
)
}

export default {
export default createRule({
create(context) {
let conditionalDepth = 0
let inTestCase = false
Expand Down Expand Up @@ -109,4 +110,4 @@ export default {
},
type: 'problem',
},
} as Rule.RuleModule
})
5 changes: 3 additions & 2 deletions src/rules/no-conditional-in-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Rule } from 'eslint'
import { findParent } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { isTypeOfFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
function checkConditional(node: Rule.Node & Rule.NodeParentExtension) {
const call = findParent(node, 'CallExpression')
Expand Down Expand Up @@ -33,4 +34,4 @@ export default {
schema: [],
type: 'problem',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-duplicate-hooks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Rule } from 'eslint'
import { getStringValue } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { isTypeOfFnCall, parseFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
const hookContexts: Array<Record<string, number>> = [{}]

Expand Down Expand Up @@ -55,4 +55,4 @@ export default {
},
type: 'suggestion',
},
} as Rule.RuleModule
})
7 changes: 4 additions & 3 deletions src/rules/no-element-handle.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { AST, Rule } from 'eslint'
import { AST } from 'eslint'
import ESTree from 'estree'
import { isPageMethod } from '../utils/ast'
import { createRule } from '../utils/createRule'

function getPropertyRange(node: ESTree.Node): AST.Range {
return node.type === 'Identifier'
? node.range!
: [node.range![0] + 1, node.range![1] - 1]
}

export default {
export default createRule({
create(context) {
return {
CallExpression(node) {
Expand Down Expand Up @@ -68,4 +69,4 @@ export default {
},
type: 'suggestion',
},
} as Rule.RuleModule
})
24 changes: 24 additions & 0 deletions src/rules/no-eval.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dedent from 'dedent'
import rule from '../../src/rules/no-eval'
import { runRuleTester, test } from '../utils/rule-tester'

Expand Down Expand Up @@ -63,6 +64,29 @@ runRuleTester('no-eval', rule, {
),
errors: [{ column: 52, endColumn: 63, line: 1, messageId: 'noEvalAll' }],
},

// Custom messages
// Note: This is one of the only test in the project to tests custom
// messages since it's implementation is global in the `createRule` method.
{
code: dedent`
page.$eval("#search", el => el.value);
page.$$eval("#search", el => el.value);
`,
errors: [
{ column: 1, endColumn: 11, line: 1, message: 'no eval' },
{ column: 1, endColumn: 12, line: 2, message: 'no eval all' },
],
name: 'Custom messages',
settings: {
playwright: {
messages: {
noEval: 'no eval',
noEvalAll: 'no eval all',
},
},
},
},
],
valid: [
test('await page.locator(".tweet").evaluate(node => node.innerText)'),
Expand Down
6 changes: 3 additions & 3 deletions src/rules/no-eval.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Rule } from 'eslint'
import { isPageMethod } from '../utils/ast'
import { createRule } from '../utils/createRule'

export default {
export default createRule({
create(context) {
return {
CallExpression(node) {
Expand Down Expand Up @@ -30,4 +30,4 @@ export default {
},
type: 'problem',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-focused-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Rule } from 'eslint'
import { getStringValue } from '../utils/ast'
import { createRule } from '../utils/createRule'
import { parseFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
return {
CallExpression(node) {
Expand Down Expand Up @@ -47,4 +47,4 @@ export default {
},
type: 'problem',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-force-option.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Rule } from 'eslint'
import ESTree from 'estree'
import { getStringValue, isBooleanLiteral } from '../utils/ast'
import { createRule } from '../utils/createRule'

function isForceOptionEnabled(node: ESTree.CallExpression) {
const arg = node.arguments.at(-1)
Expand Down Expand Up @@ -31,7 +31,7 @@ const methodsWithForceOption = new Set([
'tap',
])

export default {
export default createRule({
create(context) {
return {
MemberExpression(node) {
Expand Down Expand Up @@ -60,4 +60,4 @@ export default {
},
type: 'suggestion',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-get-by-title.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Rule } from 'eslint'
import { isPageMethod } from '../utils/ast'
import { createRule } from '../utils/createRule'

export default {
export default createRule({
create(context) {
return {
CallExpression(node) {
Expand All @@ -24,4 +24,4 @@ export default {
},
type: 'suggestion',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Rule } from 'eslint'
import { createRule } from '../utils/createRule'
import { parseFnCall } from '../utils/parseFnCall'

export default {
export default createRule({
create(context) {
const options = {
allow: [] as string[],
Expand Down Expand Up @@ -47,4 +47,4 @@ export default {
],
type: 'suggestion',
},
} as Rule.RuleModule
})
5 changes: 3 additions & 2 deletions src/rules/no-nested-step.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Rule } from 'eslint'
import ESTree from 'estree'
import { isPropertyAccessor } from '../utils/ast'
import { createRule } from '../utils/createRule'

function isStepCall(node: ESTree.Node): boolean {
const inner = node.type === 'CallExpression' ? node.callee : node
Expand All @@ -12,7 +13,7 @@ function isStepCall(node: ESTree.Node): boolean {
return isPropertyAccessor(inner, 'step')
}

export default {
export default createRule({
create(context) {
const stack: number[] = []

Expand Down Expand Up @@ -59,4 +60,4 @@ export default {
schema: [],
type: 'problem',
},
} as Rule.RuleModule
})
6 changes: 3 additions & 3 deletions src/rules/no-networkidle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Rule } from 'eslint'
import ESTree from 'estree'
import { getStringValue, isStringLiteral } from '../utils/ast'
import { createRule } from '../utils/createRule'

const messageId = 'noNetworkidle'
const methods = new Set([
Expand All @@ -13,7 +13,7 @@ const methods = new Set([
'waitForURL',
])

export default {
export default createRule({
create(context) {
return {
CallExpression(node) {
Expand Down Expand Up @@ -61,4 +61,4 @@ export default {
},
type: 'problem',
},
} as Rule.RuleModule
})
Loading