UNPKG

eslint-plugin-wdio

Version:
408 lines (394 loc) 10.6 kB
// src/constants.ts var MATCHERS = [ "toBeChecked", "toBeClickable", "toBeDisabled", "toBeDisplayed", "toBeDisplayedInViewport", "toBeElementsArrayOfSize", "toBeEnabled", "toBeExisting", "toBeFocused", "toBePresent", "toBeRequested", "toBeRequestedTimes", "toBeRequestedWith", "toBeRequestedWithResponse", "toBeSelected", "toExist", "toHaveAttr", "toHaveAttribute", "toHaveAttributeAndValue", "toHaveChildren", "toHaveClass", "toHaveClassContaining", "toHaveClipboardText", "toHaveComputedLabel", "toHaveComputedRole", "toHaveElementClass", "toHaveElementProperty", "toHaveHTML", "toHaveHeight", "toHaveHref", "toHaveId", "toHaveLink", "toHaveLocalStorageItem", "toHaveSize", "toHaveStyle", "toHaveText", "toHaveTitle", "toHaveUrl", "toHaveValue", "toHaveWidth" ]; // src/rules/await-expect.ts var rule = { meta: { type: "problem", docs: { description: "expect must be prefixed with await", category: "Possible Errors", url: "https://github.com/webdriverio/webdriverio/blob/main/packages/eslint-plugin-wdio/docs/rules/await-expect.md", recommended: false }, messages: { missingAwait: "Missing await before an expect statement" }, hasSuggestions: true }, create: function(context) { return { CallExpression(node) { if (node.callee.type !== "MemberExpression" || node.callee.object.type !== "CallExpression" || node.callee.object.callee.name !== "expect") { return; } const propertyName = node.callee.property.name; const isWdioMatcher = MATCHERS.includes(propertyName); const isSnapshotMatcher = ["toMatchSnapshot", "toMatchInlineSnapshot"].includes(propertyName); if (!isWdioMatcher && !isSnapshotMatcher) { return; } if (isSnapshotMatcher) { const selectorFunctions = ["$", "$$"]; const expectArg = node.callee.object.arguments[0]; const isLikelyWdioElement = expectArg.type === "CallExpression" && expectArg.callee.type === "Identifier" && selectorFunctions.includes(expectArg.callee.name) || expectArg.type === "CallExpression" && expectArg.callee.type === "MemberExpression" && expectArg.callee.property.name && selectorFunctions.includes(expectArg.callee.property.name); if (!isLikelyWdioElement) { return; } } if ( /** * expect is called without an `await` and as part of an * expression */ node.parent.type === "ExpressionStatement" ) { context.report({ node, messageId: "missingAwait" }); } } }; } }; var await_expect_default = rule; // src/utils/helpers.ts var isCommand = function(expression, command, instances = ["browser"]) { const callee = expression?.callee; return callee && "object" in callee && "name" in callee.object && instances.includes(callee.object?.name) && "property" in callee && "name" in callee.property && callee.property?.name === command; }; // src/rules/no-debug.ts var rule2 = { meta: { type: "problem", docs: { description: "Disallow browser.debug() in tests", category: "Possible Errors", url: "https://github.com/webdriverio/webdriverio/blob/main/packages/eslint-plugin-wdio/docs/rules/no-debug.md", recommended: false }, messages: { unexpectedDebug: "Unexpected browser.debug() not allowed" }, hasSuggestions: true, schema: [{ type: "object", properties: { instances: { type: "array", items: { type: "string" }, description: 'List of browser instances to check (default: ["browser"])', default: ["browser"] } }, additionalProperties: false }] }, create: function(context) { const options = context.options[0] || {}; const instances = options.instances || ["browser"]; return { CallExpression(node) { if (isCommand(node, "debug", instances)) { context.report({ node, messageId: "unexpectedDebug", data: { instance: instances.join(", ") } }); } } }; } }; var no_debug_default = rule2; // src/rules/no-pause.ts var rule3 = { meta: { type: "problem", docs: { description: "Disallow browser.pause() in tests", category: "Possible Errors", url: "https://github.com/webdriverio/webdriverio/blob/main/packages/eslint-plugin-wdio/docs/rules/no-pause.md", recommended: false }, messages: { unexpectedPause: "Unexpected browser.pause() not allowed" }, hasSuggestions: true, schema: [{ type: "object", properties: { instances: { type: "array", items: { type: "string" }, description: 'List of browser instances to check (default: ["browser"])', default: ["browser"] } }, additionalProperties: false }] }, create: function(context) { const options = context.options[0] || {}; const instances = options.instances || ["browser"]; return { CallExpression(node) { if (isCommand(node, "pause", instances)) { context.report({ node, messageId: "unexpectedPause", data: { instance: instances.join(", ") } }); } } }; } }; var no_pause_default = rule3; // src/plugin.ts var index = { configs: {}, rules: { "await-expect": await_expect_default, "no-debug": no_debug_default, "no-pause": no_pause_default } }; var plugin_default = index; // src/globals.ts import globals from "globals"; var sharedGlobals = { $: false, $$: false, browser: false, driver: false, expect: false, multiremotebrowser: false, multiRemoteBrowser: false, // To be more user friendly we add mocha and node globals as well, else the use need to configure themself ...globals.mocha, ...globals.node }; // src/configs/js-recommended.ts var js_recommended_default = { languageOptions: { globals: sharedGlobals }, plugins: { wdio: plugin_default }, rules: { "wdio/await-expect": "error", "wdio/no-debug": "error", "wdio/no-pause": "error" } }; // src/configs/ts-recommended.ts import { createRequire as createRequire3 } from "node:module"; // src/rules/no-floating-promise.ts import { createRequire } from "node:module"; var require2 = createRequire(import.meta.url); var tryRequire = (moduleName) => { try { return require2(moduleName); } catch { return null; } }; var tsEslintPlugin = tryRequire("@typescript-eslint/eslint-plugin"); var tsRule = tsEslintPlugin?.rules["no-floating-promises"]; var error; var rule4 = { meta: tsRule?.meta ?? { type: "problem", docs: { description: "Check for unhandled promises", url: "https://github.com/webdriverio/webdriverio/blob/main/packages/eslint-plugin-wdio/docs/rules/no-floating-promise.md" }, schema: [] }, create: function(context) { try { return tsRule?.create(context) ?? {}; } catch { console.error("Error in no-floating-promise rule:", error); return {}; } } }; var no_floating_promise_default = rule4; // src/utils/typeAware.ts import { createRequire as createRequire2 } from "node:module"; var require3 = createRequire2(import.meta.url); var isTypeAware = (() => { try { require3("typescript-eslint"); return true; } catch { return false; } })(); // src/configs/ts-recommended.ts var require4 = createRequire3(import.meta.url); var tsRecommended = () => { const tseslint = require4("typescript-eslint"); const typescriptPlugin = { ...plugin_default, rules: { ...plugin_default.rules, "no-floating-promise": no_floating_promise_default } }; return { languageOptions: { globals: sharedGlobals, parser: tseslint.parser, parserOptions: { projectService: true } }, plugins: { wdio: typescriptPlugin }, rules: { "wdio/await-expect": "off", "wdio/no-debug": "error", "wdio/no-pause": "error", "wdio/no-floating-promise": "error" }, // Because of the required `projectService: true,` above we see `Parsing error`, doing the below remove that eslint error. ignores: ["eslint.config.js", "eslint.config.cjs", "eslint.config.mjs"] }; }; var rules = { ...plugin_default.rules, "no-floating-promise": no_floating_promise_default }; var ts_recommended_default = isTypeAware ? tsRecommended() : void 0; // package.json var package_default = { name: "eslint-plugin-wdio", version: "9.29.0", description: "Eslint rules for WebdriverIO", author: "Christian Bromann <mail@bromann.dev>", homepage: "https://github.com/webdriverio/webdriverio/tree/main/packages/eslint-plugin-wdio", license: "MIT", main: "./build/index.cjs", module: "./build/index.js", types: "./build/index.d.ts", exports: { ".": { types: "./build/index.d.ts", import: "./build/index.js", require: "./build/index.cjs" } }, type: "module", typeScriptVersion: "3.8.3", engines: { node: ">=18.20.0" }, repository: { type: "git", url: "git+https://github.com/webdriverio/webdriverio.git", directory: "packages/eslint-plugin-wdio" }, keywords: [ "eslint", "eslintplugin", "eslint-plugin", "webdriver", "wdio" ], bugs: { url: "https://github.com/webdriverio/webdriverio/issues" }, devDependencies: { "@types/estree": "^1.0.8", eslint: "^9.39.2", "expect-webdriverio": "^5.6.5", globals: "^16.5.0", "typescript-eslint": "^8.54.0" }, peerDependencies: { eslint: "^9.39.2", globals: "^16.5.0", "typescript-eslint": "^8.54.0" }, peerDependenciesMeta: { "typescript-eslint": { optional: true } } }; // src/index.ts var legacyConfig = { rules: { "wdio/await-expect": "error", "wdio/no-debug": "error", "wdio/no-pause": "error" }, globals: sharedGlobals, plugins: ["wdio"] }; var flatConfig = ts_recommended_default ?? js_recommended_default; var configs = { "flat/recommended": flatConfig, recommended: legacyConfig }; var rules2 = ts_recommended_default?.rules ?? plugin_default.rules; var index_default = { meta: { name: package_default.name, version: package_default.version }, configs, rules: rules2 }; export { configs, index_default as default, rules2 as rules };