Add coexistence checks to all enqueue methods to prevent loading both React and Grid.js assets simultaneously. Changes: - ReactAdmin.php: Only enqueue React assets when ?react=1 - Init.php: Skip Grid.js when React active on admin pages - Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0 - Customer.php, Product.php, License.php: Add coexistence checks Now the toggle between Classic and React versions works correctly. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
142 lines
4.2 KiB
JavaScript
142 lines
4.2 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const ast_1 = require("../utils/ast");
|
|
const validTypes = new Set([
|
|
'AwaitExpression',
|
|
'ReturnStatement',
|
|
'ArrowFunctionExpression',
|
|
]);
|
|
const expectPlaywrightMatchers = [
|
|
'toBeChecked',
|
|
'toBeDisabled',
|
|
'toBeEnabled',
|
|
'toEqualText',
|
|
'toEqualUrl',
|
|
'toEqualValue',
|
|
'toHaveFocus',
|
|
'toHaveSelector',
|
|
'toHaveSelectorCount',
|
|
'toHaveText',
|
|
'toMatchAttribute',
|
|
'toMatchComputedStyle',
|
|
'toMatchText',
|
|
'toMatchTitle',
|
|
'toMatchURL',
|
|
'toMatchValue',
|
|
];
|
|
const playwrightTestMatchers = [
|
|
'toBeChecked',
|
|
'toBeDisabled',
|
|
'toBeEditable',
|
|
'toBeEmpty',
|
|
'toBeEnabled',
|
|
'toBeFocused',
|
|
'toBeHidden',
|
|
'toBeVisible',
|
|
'toContainText',
|
|
'toHaveAttribute',
|
|
'toHaveClass',
|
|
'toHaveCount',
|
|
'toHaveCSS',
|
|
'toHaveId',
|
|
'toHaveJSProperty',
|
|
'toBeOK',
|
|
'toHaveScreenshot',
|
|
'toHaveText',
|
|
'toHaveTitle',
|
|
'toHaveURL',
|
|
'toHaveValue',
|
|
];
|
|
function getCallType(node, awaitableMatchers) {
|
|
// test.step
|
|
if (node.callee.type === 'MemberExpression' &&
|
|
(0, ast_1.isIdentifier)(node.callee.object, 'test') &&
|
|
(0, ast_1.isPropertyAccessor)(node.callee, 'step')) {
|
|
return { messageId: 'testStep' };
|
|
}
|
|
const expectType = (0, ast_1.getExpectType)(node);
|
|
if (!expectType)
|
|
return;
|
|
// expect.poll
|
|
if (expectType === 'poll') {
|
|
return { messageId: 'expectPoll' };
|
|
}
|
|
// expect with awaitable matcher
|
|
const [lastMatcher] = (0, ast_1.getMatchers)(node).slice(-1);
|
|
const matcherName = (0, ast_1.getStringValue)(lastMatcher);
|
|
if (awaitableMatchers.has(matcherName)) {
|
|
return { data: { matcherName }, messageId: 'expect' };
|
|
}
|
|
}
|
|
function isPromiseAll(node) {
|
|
return node.type === 'ArrayExpression' &&
|
|
node.parent.type === 'CallExpression' &&
|
|
node.parent.callee.type === 'MemberExpression' &&
|
|
(0, ast_1.isIdentifier)(node.parent.callee.object, 'Promise') &&
|
|
(0, ast_1.isIdentifier)(node.parent.callee.property, 'all')
|
|
? node.parent
|
|
: null;
|
|
}
|
|
function checkValidity(node) {
|
|
if (validTypes.has(node.parent.type))
|
|
return;
|
|
const promiseAll = isPromiseAll(node.parent);
|
|
return promiseAll
|
|
? checkValidity(promiseAll)
|
|
: node.parent.type === 'MemberExpression' ||
|
|
(node.parent.type === 'CallExpression' && node.parent.callee === node)
|
|
? checkValidity(node.parent)
|
|
: node;
|
|
}
|
|
exports.default = {
|
|
create(context) {
|
|
const options = context.options[0] || {};
|
|
const awaitableMatchers = new Set([
|
|
...expectPlaywrightMatchers,
|
|
...playwrightTestMatchers,
|
|
// Add any custom matchers to the set
|
|
...(options.customMatchers || []),
|
|
]);
|
|
return {
|
|
CallExpression(node) {
|
|
const result = getCallType(node, awaitableMatchers);
|
|
const reportNode = result ? checkValidity(node) : undefined;
|
|
if (result && reportNode) {
|
|
context.report({
|
|
data: result.data,
|
|
fix: (fixer) => fixer.insertTextBefore(node, 'await '),
|
|
messageId: result.messageId,
|
|
node: node.callee,
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
meta: {
|
|
docs: {
|
|
category: 'Possible Errors',
|
|
description: `Identify false positives when async Playwright APIs are not properly awaited.`,
|
|
recommended: true,
|
|
},
|
|
fixable: 'code',
|
|
messages: {
|
|
expect: "'{{matcherName}}' must be awaited or returned.",
|
|
expectPoll: "'expect.poll' matchers must be awaited or returned.",
|
|
testStep: "'test.step' must be awaited or returned.",
|
|
},
|
|
schema: [
|
|
{
|
|
additionalProperties: false,
|
|
properties: {
|
|
customMatchers: {
|
|
items: { type: 'string' },
|
|
type: 'array',
|
|
},
|
|
},
|
|
type: 'object',
|
|
},
|
|
],
|
|
type: 'problem',
|
|
},
|
|
};
|