diff --git a/package-lock.json b/package-lock.json index c3b1e48..81569a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "eslint-plugin-jest-formatting": "3.1.0", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-n": "17.8.1", + "eslint-plugin-playwright": "1.6.2", "eslint-plugin-prettier": "5.1.3", "eslint-plugin-promise": "6.2.0", "eslint-plugin-react": "7.34.2", @@ -6291,6 +6292,54 @@ "node": ">=10" } }, + "node_modules/eslint-plugin-playwright": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.2.tgz", + "integrity": "sha512-mraN4Em3b5jLt01q7qWPyLg0Q5v3KAWfJSlEWwldyUXoa7DSPrBR4k6B6LROLqipsG8ndkwWMdjl1Ffdh15tag==", + "workspaces": [ + "examples" + ], + "dependencies": { + "globals": "^13.23.0" + }, + "engines": { + "node": ">=16.6.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0", + "eslint-plugin-jest": ">=25" + }, + "peerDependenciesMeta": { + "eslint-plugin-jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-playwright/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-playwright/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-prettier": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", diff --git a/package.json b/package.json index f9f1aa7..8e0fccb 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "main": "src/index.js", "dependencies": { "@graphql-eslint/eslint-plugin": "3.20.1", - "typescript-eslint": "rc-v8", "deepmerge": "4.3.1", "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-cypress": "3.3.0", @@ -35,6 +34,7 @@ "eslint-plugin-jest-formatting": "3.1.0", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-n": "17.8.1", + "eslint-plugin-playwright": "1.6.2", "eslint-plugin-prettier": "5.1.3", "eslint-plugin-promise": "6.2.0", "eslint-plugin-react": "7.34.2", @@ -42,7 +42,8 @@ "eslint-plugin-storybook": "0.8.0", "eslint-plugin-tailwindcss": "3.17.3", "eslint-plugin-vitest": "0.5.4", - "globals": "15.4.0" + "globals": "15.4.0", + "typescript-eslint": "rc-v8" }, "devDependencies": { "@eslint/eslintrc": "3.1.0", diff --git a/src/index.js b/src/index.js index fabaece..6be4d43 100644 --- a/src/index.js +++ b/src/index.js @@ -17,6 +17,7 @@ const strict = require('./modules/strict'); const react = require('./modules/react'); const storybook = require('./modules/storybook'); const typescript = require('./modules/typescript'); +const playwright = require('./modules/playwright'); const testPackages = ['jest', 'vitest', 'cypress', 'playwright']; @@ -40,6 +41,7 @@ const defaultOptions = { prettier: isPackageExists('prettier'), typescript: isPackageExists('typescript') ? { projects: true } : false, unocss: isPackageExists('unocss'), + playwright: isPackageExists('playwright'), }; /** @@ -71,6 +73,7 @@ function init(initOptions, ...extend) { if (options.react) rules.push(react(options)); if (options.storybook) rules.push(storybook(options)); if (options.typescript) rules.push(typescript(options)); + if (options.playwright) rules.push(playwright(options)); // ISSUE: Waiting for FlatConfig support https://github.com/dimaMachina/graphql-eslint/issues/2178 // if (false && options.graphql) rules.push(graphql(options)); diff --git a/src/init.d.ts b/src/init.d.ts index dc0a476..93f911f 100644 --- a/src/init.d.ts +++ b/src/init.d.ts @@ -14,6 +14,7 @@ export interface Options { cypress?: boolean; storybook?: boolean; prettier?: boolean; + playwright?: boolean; typescript?: { projects: string[] | string }; disableExpensiveRules?: boolean; } diff --git a/src/modules/playwright.js b/src/modules/playwright.js new file mode 100644 index 0000000..3d56633 --- /dev/null +++ b/src/modules/playwright.js @@ -0,0 +1,30 @@ +const globals = require('globals'); +const plugin = require('eslint-plugin-playwright'); +const { globs } = require('../utils/globs'); + +/** @return { import('eslint').Linter.FlatConfig } */ +function playwright() { + return { + plugins: { playwright: plugin }, + files: globs.e2e, + rules: { + 'jest/no-standalone-expect': [ + 'error', + { + additionalTestBlockFunctions: [ + 'test.jestPlaywrightDebug', + 'it.jestPlaywrightDebug', + 'test.jestPlaywrightSkip', + 'it.jestPlaywrightSkip', + 'test.jestPlaywrightConfig', + 'it.jestPlaywrightConfig', + ], + }, + ], + 'playwright/missing-playwright-await': 'error', + 'playwright/no-page-pause': 'warn', + }, + }; +} + +module.exports = playwright; diff --git a/src/modules/tests.js b/src/modules/tests.js index 91df110..724ba4d 100644 --- a/src/modules/tests.js +++ b/src/modules/tests.js @@ -1,6 +1,7 @@ const plugin = require('eslint-plugin-jest-formatting'); const { globs } = require('../utils/globs'); const { predicate } = require('../utils/conditions'); +const globals = require('globals'); /** * @param {import('../init').Options} options @@ -10,6 +11,9 @@ function tests(options = {}) { return { plugins: { 'jest-formatting': plugin }, files: [...globs.test, ...globs.e2e], + languageOptions: { + globals: globals['shared-node-browser'], + }, rules: { 'jest-formatting/padding-around-after-all-blocks': 'warn', 'jest-formatting/padding-around-after-each-blocks': 'warn', @@ -35,6 +39,7 @@ function tests(options = {}) { '@typescript-eslint/no-namespace ': 'off', '@typescript-eslint/unbound-method': 'off', '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-floating-promises': 'off', }), }, };