eslint-plugin-sonarjs
Version:
105 lines (104 loc) • 4.15 kB
JavaScript
;
/*
* SonarQube JavaScript Plugin
* Copyright (C) SonarSource Sàrl
* mailto:info AT sonarsource DOT com
*
* You can redistribute and/or modify this program under the terms of
* the Sonar Source-Available License Version 1, as published by SonarSource Sàrl.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Sonar Source-Available License for more details.
*
* You should have received a copy of the Sonar Source-Available License
* along with this program; if not, see https://sonarsource.com/license/ssal/
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPlaywrightLocatorExpression = isPlaywrightLocatorExpression;
exports.trackPlaywrightLocators = trackPlaywrightLocators;
exports.isLengthAccess = isLengthAccess;
exports.isNullLiteral = isNullLiteral;
exports.isUndefinedExpression = isUndefinedExpression;
exports.isNaNExpression = isNaNExpression;
exports.getBooleanValue = getBooleanValue;
exports.replacement = replacement;
const ast_js_1 = require("../helpers/ast.js");
const PLAYWRIGHT_LOCATOR_FACTORIES = new Set([
'getByRole',
'getByText',
'getByLabel',
'getByPlaceholder',
'getByAltText',
'getByTitle',
'getByTestId',
'locator',
'frameLocator',
]);
function isPlaywrightLocatorExpression(context, node, locatorVariables) {
if ((0, ast_js_1.isIdentifier)(node)) {
const variable = (0, ast_js_1.getVariableFromName)(context, node.name, node);
return variable !== undefined && locatorVariables.has(variable);
}
if (node.type !== 'CallExpression' || !(0, ast_js_1.isMethodCall)(node)) {
return false;
}
const property = node.callee.property;
return ((0, ast_js_1.isIdentifier)(property) &&
PLAYWRIGHT_LOCATOR_FACTORIES.has(property.name) &&
isPlaywrightLocatorRoot(context, node.callee.object, locatorVariables));
}
function isPlaywrightLocatorRoot(context, node, locatorVariables) {
if ((0, ast_js_1.isIdentifier)(node)) {
if (node.name === 'page') {
return true;
}
const variable = (0, ast_js_1.getVariableFromName)(context, node.name, node);
return variable !== undefined && locatorVariables.has(variable);
}
return isPlaywrightLocatorExpression(context, node, locatorVariables);
}
// As soon as a third rule consumes this, promote it out of S5906/ into a
// shared module under helpers/ (e.g. helpers/playwright-locators.ts) so it no
// longer lives under a specific rule's directory.
function trackPlaywrightLocators(context, locators) {
return {
VariableDeclarator(node) {
if (node.type !== 'VariableDeclarator' || !(0, ast_js_1.isIdentifier)(node.id)) {
return;
}
if (node.init && isPlaywrightLocatorExpression(context, node.init, locators)) {
const variable = context.sourceCode.getDeclaredVariables(node)[0];
if (variable) {
locators.add(variable);
}
}
},
};
}
function isLengthAccess(node) {
return (node.type === 'MemberExpression' && !node.computed && (0, ast_js_1.isIdentifier)(node.property, 'length'));
}
function isNullLiteral(node) {
return node.type === 'Literal' && node.value === null;
}
function isUndefinedExpression(node) {
return (0, ast_js_1.isIdentifier)(node, 'undefined');
}
function isNaNExpression(node) {
return ((0, ast_js_1.isIdentifier)(node, 'NaN') ||
(node.type === 'MemberExpression' &&
(0, ast_js_1.isIdentifier)(node.object, 'Number') &&
(0, ast_js_1.isIdentifier)(node.property, 'NaN')));
}
function getBooleanValue(node) {
return node.type === 'Literal' && typeof node.value === 'boolean' ? node.value : undefined;
}
function replacement(replacementText, _node, _sourceCode, messageId) {
return {
assertion: replacementText,
replacement: replacementText,
...(messageId ? { messageId } : {}),
};
}