Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 113x 56x 5x 51x 113x 77x 103x 103x 103x 103x 103x 41x 171x 62x 56x 56x 56x 56x 109x 56x 56x 56x | /** * @module transformers */ import * as ts from "typescript"; /** becomes `import { executeCyTests } from "orphic-cypress"` */ const createImportStatement = ( factory: ts.NodeFactory, opts: ts.CompilerOptions, executeCyTestsLocation: string ) => { // handle commonjs module type as chosen in tsconfig.json if (opts.module === ts.ModuleKind.CommonJS) { return factory.createVariableStatement( /* modifiers */ undefined, factory.createVariableDeclarationList([ factory.createVariableDeclaration( "executeCyTests", /* exclamation token */ undefined, /* type */ undefined, factory.createPropertyAccessExpression( factory.createCallExpression( factory.createIdentifier("require"), /* type arguments */ undefined, [factory.createStringLiteral(executeCyTestsLocation)] ), factory.createIdentifier("executeCyTests") ) ), ]) ); } return factory.createImportDeclaration( /* modifiers */ undefined, factory.createImportClause( /* isTypeOnly */ false, /* name (so default import) */ undefined, factory.createNamedImports([ factory.createImportSpecifier( /* isTypeOnly */ false, /* name (would mean `export { executeCyTests as })`) */ undefined, factory.createIdentifier("executeCyTests") ), ]) ), factory.createStringLiteral(executeCyTestsLocation) ); }; type Source = ts.SourceFile & { symbol: { exports: Map<string, { declarations: ts.ExportAssignment[] }>; }; }; /** * Transform a typescript stories file by adding `executeCyTests` to the bottom * with all exports explicitly passed in and the default recreated to be passed * in as 'default' prop. * * In webpack, can use with ts-loader like so * ```ts * { * test: /\.[jt]sx?$/, * exclude: [/node_modules/], * use: [ * { * loader: "ts-loader", * options: { * happyPackMode: true, * transpileOnly: true, * ...(useIsolatedComponentFiles && { * getCustomTransformers: () => ({ * before: [transformIsolatedComponentFiles()], * }), * }), * }, * }, * ], * } * ``` * * To include mdx files as tests, add this to module rules * ```ts * { * test: /\.mdx$/, * use: [ * <above ts-loader config>, * { * loader: require.resolve("@storybook/mdx1-csf/loader"), * options: { skipCsf }, * }, * ], * }, * ``` * see {@link bundlers.cypressWebpackConfigMdx} for an abstraction to do just that, * as well as load non-story mdx and md files. */ export const transformIsolatedComponentFiles = ( /** * Location for `executeCyTests`. Defaults to this module, but you could import it elsewhere * and change via pre/post call, or rewrite entirely and point to it from here */ executeCyTestsLocation = "orphic-cypress", /** story filename pattern */ storyPattern: string | RegExp = /\.stories|story\./ ): ts.TransformerFactory<ts.SourceFile> => (context) => (source) => { const exports = (source as Source).symbol?.exports ?? new Map(); const defaultExport = exports.get("default")?.declarations?.[0]; const matches = source.fileName && (storyPattern instanceof RegExp ? storyPattern.test(source.fileName) : source.fileName.includes(storyPattern)); // docs only stories will have a ___page which intentionally throws an error if (!matches || !exports || exports.has("___page") || !defaultExport) { return source; } const exportKeys = [...exports.keys()].filter((name) => name !== "default"); if (!exportKeys.length) return source; const { factory: f, getCompilerOptions } = context; const opts = getCompilerOptions(); const newImport = createImportStatement(f, opts, executeCyTestsLocation); const newExportObject = f.createObjectLiteralExpression([ f.createPropertyAssignment("default", defaultExport.expression), ...exportKeys.map((k) => f.createShorthandPropertyAssignment(k)), ]); /** becomes `executeCyCall({ default: {<default export obj>}, OtherStory, <...> })` */ const executeCyCall = f.createCallExpression( f.createIdentifier("executeCyTests"), [], [newExportObject] ) as any as ts.Statement; const allStatements = [newImport, ...source.statements, executeCyCall]; return f.updateSourceFile(source, allStatements); }; |