@11joselu/cypress-to-playwright
Version:
Automatic migration from cypress to playwright
269 lines • 12.8 kB
JavaScript
import ts from 'typescript';
import { PLAYWRIGHT_PAGE_NAME } from '../playwright.js';
import { fixString } from './fix-string.js';
export const nodeFactory = (factory) => {
return {
callExpressionStatement: createWrappedCallExpressionInStatement(factory),
statement: createStatement(factory),
propertyAccessExpression: createPropertyAccessExpression(factory),
identifier: createIdentifier(factory),
arrowFunction: createArrowFunction(factory),
callExpression: createCallExpression(factory),
destructuringParameter: createDestructuringParameter(factory),
awaitCallExpression: createAwaitCallExpression(factory),
await: createAwait(factory),
emptyBlock: createEmptyBlock(factory),
asyncToken: createAsyncToken(factory),
variable: createVariable(factory),
block: createBlock(factory),
numeric: createNumericLiteral(factory),
string: createStringLiteral(factory),
expect: createPlaywrightExpect(factory),
playwrightCommand: createPlaywrightCommand(factory),
playwrightLocatorProperty: createPlaywrightLocatorProperty(factory),
playwrightIntercept: createPlaywrightIntercept(factory),
functionWithPageParameter: createFunctionWithPageParameter(factory),
parameter: createParameter(factory),
function: createFunction(factory),
exportToken: createExportToken(factory),
};
};
function createWrappedCallExpressionInStatement(factory) {
const statement = createStatement(factory);
return (newExpression, callExpression) => {
return statement(factory.createCallExpression(newExpression, callExpression.typeArguments, callExpression.arguments));
};
}
function createStatement(factory) {
return (statement) => {
return factory.createExpressionStatement(statement);
};
}
function createPropertyAccessExpression(factory) {
const identifier = createIdentifier(factory);
return (expression, name) => {
let newExpression;
if (typeof expression === 'string') {
newExpression = identifier(expression);
}
else {
newExpression = expression;
}
return factory.createPropertyAccessExpression(newExpression, name);
};
}
function createAwaitCallExpression(factory) {
const callExpression = createCallExpression(factory);
return (expression, typeArguments, args) => {
return factory.createAwaitExpression(callExpression(expression, typeArguments, args || []));
};
}
function createAwait(factory) {
return (expression) => {
return factory.createAwaitExpression(expression);
};
}
function createIdentifier(factory) {
return (name) => {
return factory.createIdentifier(name);
};
}
function createArrowFunction(factory) {
return (body, parameters, modifiers) => {
return factory.createArrowFunction(modifiers, undefined, parameters, undefined, factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), body);
};
}
function createCallExpression(factory) {
return (expression, typeArguments, argumentsArray) => {
return factory.createCallExpression(expression, typeArguments, argumentsArray);
};
}
function createDestructuringParameter(factory) {
const identifier = createIdentifier(factory);
return (parameterName) => {
return factory.createParameterDeclaration([], undefined, factory.createObjectBindingPattern([
factory.createBindingElement(undefined, undefined, identifier(parameterName)),
]));
};
}
function createEmptyBlock(factory) {
return () => {
return factory.createBlock([], false);
};
}
function createAsyncToken(factory) {
return () => {
return factory.createToken(ts.SyntaxKind.AsyncKeyword);
};
}
function createVariable(factory) {
const identifier = createIdentifier(factory);
return function (name, value, flag = ts.NodeFlags.Const) {
return factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(identifier(name), undefined, undefined, value)], flag));
};
}
function createBlock(factory) {
return (statements) => {
return factory.createBlock(statements, true);
};
}
function createNumericLiteral(factory) {
return (value) => {
return factory.createNumericLiteral(value);
};
}
function createStringLiteral(factory) {
return (value) => {
return factory.createStringLiteral(value);
};
}
function createPlaywrightExpect(factory) {
return (expression, validationType, validationArgs = [], isNegative = false) => {
const awaitExpression = createAwaitCallExpression(factory);
const identifier = createIdentifier(factory);
const callExpression = createCallExpression(factory);
if (isNegative) {
return awaitExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(callExpression(identifier("expect" /* VALIDATION.EXPECT */), undefined, [expression]), factory.createIdentifier('not')), identifier(validationType)), undefined, validationArgs);
}
return awaitExpression(factory.createPropertyAccessExpression(callExpression(identifier("expect" /* VALIDATION.EXPECT */), undefined, [expression]), identifier(validationType)), undefined, validationArgs);
};
}
function createPlaywrightCommand(factory) {
const propertyAccessExpression = createPropertyAccessExpression(factory);
const identifier = createIdentifier(factory);
return (commandName) => {
return propertyAccessExpression(PLAYWRIGHT_PAGE_NAME, identifier(commandName));
};
}
function createPlaywrightLocatorProperty(factory) {
const callExpression = createCallExpression(factory);
const propertyAccessExpression = createPropertyAccessExpression(factory);
const playwrightCommand = createPlaywrightCommand(factory);
return (property, locatorTypeArgs = undefined, locatorArgs = [], propertyTypeArgs = undefined, propertyArgs = []) => {
return callExpression(propertyAccessExpression(callExpression(playwrightCommand("locator" /* COMMANDS.LOCATOR */), locatorTypeArgs, locatorArgs), property), propertyTypeArgs, propertyArgs);
};
}
function createParameter(factory) {
return function (name) {
return factory.createParameterDeclaration(undefined, undefined, createIdentifier(factory)(name));
};
}
function createObjectLiteral(factory) {
return function (properties) {
return factory.createObjectLiteralExpression(properties);
};
}
function createProperty(factory) {
return function (name, value) {
return factory.createPropertyAssignment(name, value);
};
}
function createIfStatement(factory) {
return function (expression, thenStatement, elseStatement) {
return factory.createIfStatement(expression, thenStatement, elseStatement);
};
}
function createToken(factory) {
return function (kind) {
return factory.createToken(kind);
};
}
function createReturn(factory) {
return function (value) {
return factory.createReturnStatement(value);
};
}
function createBinaryExpression(factory) {
return function (expression, token, stringLiteral) {
return factory.createBinaryExpression(expression, token, stringLiteral);
};
}
function createPlaywrightIntercept(factory) {
function isRest(arg) {
return ['POST', 'GET', 'PUT', 'PATCH', 'DELETE'].includes(fixString(arg.getText().toUpperCase()));
}
const stringLiteral = createStringLiteral(factory);
const identifier = createIdentifier(factory);
const numericLiteral = createNumericLiteral(factory);
const propertyAccessExpression = createPropertyAccessExpression(factory);
const callExpression = createCallExpression(factory);
const arrowFunction = createArrowFunction(factory);
const block = createBlock(factory);
const statement = createStatement(factory);
const objectLiteralExpression = createObjectLiteral(factory);
const propertyAssignment = createProperty(factory);
const parameterDeclaration = createParameter(factory);
const ifStatement = createIfStatement(factory);
const binaryExpression = createBinaryExpression(factory);
const token = createToken(factory);
const returnStatement = createReturn(factory);
const callOfProperty = createCallOfProperty(factory);
return function createRouteIntercept(node) {
const method = node.arguments.find((arg) => isRest(arg));
const urlArg = node.arguments.find((arg) => !isRest(arg) && !ts.isObjectLiteralExpression(arg));
// Convert Cypress-style URL pattern to RegExp
const url = urlArg.text.replace(/\*\*/g, '.*');
const optionsArg = node.arguments.find(ts.isObjectLiteralExpression);
const bodyProp = optionsArg.properties.find((prop) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return ts.isIdentifier(prop.name) && prop.name.text === 'body';
});
const statusCodeProp = optionsArg.properties.find((prop) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return ts.isIdentifier(prop.name) && prop.name.text === 'statusCode';
});
const body = identifier(bodyProp.initializer.getText());
const statusCode = numericLiteral(statusCodeProp.initializer.getText());
const bodyExpressions = [
statement(callOfProperty("route" /* ROUTE.NAME */, "fulfill" /* ROUTE.FULFILL */, [
objectLiteralExpression([propertyAssignment("status" /* ROUTE.STATUS */, statusCode), propertyAssignment("body" /* ROUTE.BODY */, body)]),
])),
];
if (method) {
const requestCallExpression = callExpression(propertyAccessExpression(callOfProperty("route" /* ROUTE.NAME */, "request" /* ROUTE.REQUEST */, []), identifier("method" /* ROUTE.METHOD */)), undefined, []);
const bodyIfStatement = ifStatement(binaryExpression(requestCallExpression, token(ts.SyntaxKind.ExclamationEqualsEqualsToken), stringLiteral(fixString(method.getFullText()))), block([statement(callOfProperty("route" /* ROUTE.NAME */, "fallback" /* ROUTE.FALLBACK */, [])), returnStatement(undefined)]), undefined);
bodyExpressions.unshift(bodyIfStatement);
}
return callOfProperty(PLAYWRIGHT_PAGE_NAME, "route" /* ROUTE.NAME */, [
stringLiteral(url),
arrowFunction(block(bodyExpressions), [parameterDeclaration("route" /* ROUTE.NAME */)]),
]);
};
}
function createCallOfProperty(factory) {
const identifier = createIdentifier(factory);
const propertyAccessExpression = createPropertyAccessExpression(factory);
const callExpression = createCallExpression(factory);
return (objIdentifier, property, objectLiteralExpressions) => {
return callExpression(propertyAccessExpression(identifier(objIdentifier), property), undefined, objectLiteralExpressions);
};
}
function createFunctionWithPageParameter(factory) {
return function (node) {
var _a;
const isVariableDeclaration = ts.isVariableDeclaration(node);
// is there are any possibility to be unknown? How?
const name = isVariableDeclaration ? node.name.getText() : ((_a = node.name) === null || _a === void 0 ? void 0 : _a.escapedText) || 'unknown';
const typeParameters = isVariableDeclaration
? node.initializer.typeParameters
: node.typeParameters;
const parameters = isVariableDeclaration ? node.initializer.parameters : node.parameters;
if (isVariableDeclaration) {
return factory.createVariableDeclaration(name, undefined, undefined, createArrowFunction(factory)(node.initializer.body, [createParameter(factory)(PLAYWRIGHT_PAGE_NAME), ...parameters], [createAsyncToken(factory)()]));
}
return factory.createFunctionDeclaration([createAsyncToken(factory)()], undefined, createIdentifier(factory)(name), typeParameters, [createParameter(factory)(PLAYWRIGHT_PAGE_NAME), ...parameters], undefined, ts.isFunctionDeclaration(node) ? node.body : createEmptyBlock(factory)());
};
}
function createFunction(factory) {
return (name, parameters, body, modifiers = []) => {
return factory.createFunctionDeclaration(modifiers, undefined, createIdentifier(factory)(name), undefined, parameters, undefined, body);
};
}
function createExportToken(factory) {
return () => {
return factory.createToken(ts.SyntaxKind.ExportKeyword);
};
}
//# sourceMappingURL=node-factory.js.map