Best JavaScript code snippet using storybook-test-runner
mdx-compiler-plugin.js
Source:mdx-compiler-plugin.js
1const mdxToJsx = require('@mdx-js/mdx/mdx-hast-to-jsx');2const parser = require('@babel/parser');3const generate = require('@babel/generator').default;4const camelCase = require('lodash/camelCase');5const jsStringEscape = require('js-string-escape');6const { toId, storyNameFromExport } = require('@storybook/router/utils');7// Generate the MDX as is, but append named exports for every8// story in the contents9const STORY_REGEX = /^<Story[\s>]/;10const PREVIEW_REGEX = /^<Preview[\s>]/;11const META_REGEX = /^<Meta[\s>]/;12const RESERVED = /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|await|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/;13function getAttr(elt, what) {14 const attr = elt.attributes.find(n => n.name.name === what);15 return attr && attr.value;16}17const isReserved = name => RESERVED.exec(name);18const sanitizeName = name => {19 let key = camelCase(name);20 if (isReserved(key)) {21 key = `${key}Story`;22 }23 return key;24};25const getStoryKey = (name, counter) => (name ? sanitizeName(name) : `story${counter}`);26function genStoryExport(ast, context) {27 let storyName = getAttr(ast.openingElement, 'name');28 let storyId = getAttr(ast.openingElement, 'id');29 storyName = storyName && storyName.value;30 storyId = storyId && storyId.value;31 if (!storyId && !storyName) {32 throw new Error('Expected a story name or ID attribute');33 }34 // We don't generate exports for story references or the smart "current story"35 if (storyId || !storyName) {36 return null;37 }38 // console.log('genStoryExport', JSON.stringify(ast, null, 2));39 const statements = [];40 const storyKey = getStoryKey(storyName, context.counter);41 let body = ast.children.find(n => n.type !== 'JSXText');42 let storyCode = null;43 let isJsx = false;44 if (!body) {45 // plain text node46 const { code } = generate(ast.children[0], {});47 storyCode = `'${code}'`;48 } else {49 if (body.type === 'JSXExpressionContainer') {50 // FIXME: handle fragments51 body = body.expression;52 } else {53 isJsx = true;54 }55 const { code } = generate(body, {});56 storyCode = code;57 }58 if (isJsx) {59 statements.push(60 `export const ${storyKey} = () => (61 ${storyCode}62 );`63 );64 } else {65 statements.push(`export const ${storyKey} = makeStoryFn(${storyCode});`);66 }67 statements.push(`${storyKey}.story = {};`);68 // always preserve the name, since CSF exports can get modified by displayName69 statements.push(`${storyKey}.story.name = '${storyName}';`);70 let parameters = getAttr(ast.openingElement, 'parameters');71 parameters = parameters && parameters.expression;72 const source = jsStringEscape(storyCode);73 if (parameters) {74 const { code: params } = generate(parameters, {});75 // FIXME: hack in the story's source as a parameter76 statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}', ...${params} };`);77 } else {78 statements.push(`${storyKey}.story.parameters = { mdxSource: '${source}' };`);79 }80 let decorators = getAttr(ast.openingElement, 'decorators');81 decorators = decorators && decorators.expression;82 if (decorators) {83 const { code: decos } = generate(decorators, {});84 statements.push(`${storyKey}.story.decorators = ${decos};`);85 }86 // eslint-disable-next-line no-param-reassign87 context.storyNameToKey[storyName] = storyKey;88 return {89 [storyKey]: statements.join('\n'),90 };91}92function genPreviewExports(ast, context) {93 // console.log('genPreviewExports', JSON.stringify(ast, null, 2));94 const previewExports = {};95 for (let i = 0; i < ast.children.length; i += 1) {96 const child = ast.children[i];97 if (child.type === 'JSXElement' && child.openingElement.name.name === 'Story') {98 const storyExport = genStoryExport(child, context);99 if (storyExport) {100 Object.assign(previewExports, storyExport);101 // eslint-disable-next-line no-param-reassign102 context.counter += 1;103 }104 }105 }106 return previewExports;107}108function genMeta(ast) {109 let title = getAttr(ast.openingElement, 'title');110 let parameters = getAttr(ast.openingElement, 'parameters');111 let decorators = getAttr(ast.openingElement, 'decorators');112 title = title && `'${title.value}'`;113 if (parameters && parameters.expression) {114 const { code: params } = generate(parameters.expression, {});115 parameters = params;116 }117 if (decorators && decorators.expression) {118 const { code: decos } = generate(decorators.expression, {});119 decorators = decos;120 }121 return {122 title,123 parameters,124 decorators,125 };126}127function getExports(node, counter) {128 const { value, type } = node;129 if (type === 'jsx') {130 if (STORY_REGEX.exec(value)) {131 // Single story132 const ast = parser.parseExpression(value, { plugins: ['jsx'] });133 const storyExport = genStoryExport(ast, counter);134 return storyExport && { stories: storyExport };135 }136 if (PREVIEW_REGEX.exec(value)) {137 // Preview, possibly containing multiple stories138 const ast = parser.parseExpression(value, { plugins: ['jsx'] });139 return { stories: genPreviewExports(ast, counter) };140 }141 if (META_REGEX.exec(value)) {142 // Preview, possibly containing multiple stories143 const ast = parser.parseExpression(value, { plugins: ['jsx'] });144 return { meta: genMeta(ast) };145 }146 }147 return null;148}149// insert `mdxKind` into the context so that we can know what "kind" we're rendering into150// when we render <Story name="xxx">...</Story>, since this MDX can be attached to any `selectedKind`!151const wrapperJs = `152componentMeta.parameters = componentMeta.parameters || {};153componentMeta.parameters.docs = {154 container: ({ context, children }) => <DocsContainer context={{...context, mdxStoryNameToId}}>{children}</DocsContainer>,155 page: MDXContent,156};157`.trim();158// Use this rather than JSON.stringify because `Meta`'s attributes159// are already valid code strings, so we want to insert them raw160// rather than add an extra set of quotes161function stringifyMeta(meta) {162 let result = '{ ';163 Object.entries(meta).forEach(([key, val]) => {164 if (val) {165 result += `${key}: ${val}, `;166 }167 });168 result += ' }';169 return result;170}171function extractExports(node, options) {172 // we're overriding default export173 const defaultJsx = mdxToJsx.toJSX(node, {}, { ...options, skipExport: true });174 const storyExports = [];175 const includeStories = [];176 let metaExport = null;177 const context = {178 counter: 0,179 storyNameToKey: {},180 };181 node.children.forEach(n => {182 const exports = getExports(n, context);183 if (exports) {184 const { stories, meta } = exports;185 if (stories) {186 Object.entries(stories).forEach(([key, story]) => {187 includeStories.push(key);188 storyExports.push(story);189 });190 }191 if (meta) {192 if (metaExport) {193 throw new Error('Meta can only be declared once');194 }195 metaExport = meta;196 }197 }198 });199 if (metaExport) {200 if (!storyExports.length) {201 storyExports.push('export const __page = () => { throw new Error("Docs-only story"); };');202 storyExports.push('__page.story = { parameters: { docsOnly: true } };');203 includeStories.push('__page');204 }205 } else {206 metaExport = {};207 }208 metaExport.includeStories = JSON.stringify(includeStories);209 const { title } = metaExport;210 const mdxStoryNameToId = Object.entries(context.storyNameToKey).reduce(211 (acc, [storyName, storyKey]) => {212 if (title) {213 acc[storyName] = toId(title, storyNameFromExport(storyKey));214 }215 return acc;216 },217 {}218 );219 const fullJsx = [220 'import { DocsContainer, makeStoryFn } from "@storybook/addon-docs/blocks";',221 defaultJsx,222 ...storyExports,223 `const componentMeta = ${stringifyMeta(metaExport)};`,224 `const mdxStoryNameToId = ${JSON.stringify(mdxStoryNameToId)};`,225 wrapperJs,226 'export default componentMeta;',227 ].join('\n\n');228 return fullJsx;229}230function createCompiler(mdxOptions) {231 return function compiler(options = {}) {232 this.Compiler = tree => extractExports(tree, options, mdxOptions);233 };234}...
mdx2.ts
Source:mdx2.ts
1import generate from '@babel/generator';2import * as t from '@babel/types';3import cloneDeep from 'lodash/cloneDeep';4import toBabel from 'estree-to-babel';5// Keeping as much code as possible from the original compiler to avoid breaking changes6import {7 genCanvasExports,8 genStoryExport,9 genMeta,10 CompilerOptions,11 Context,12 MetaExport,13 wrapperJs,14 stringifyMeta,15} from './sb-mdx-plugin';16export const SEPARATOR = '// =========';17export { wrapperJs };18function extractExports(root: t.File, options: CompilerOptions) {19 const context: Context = {20 counter: 0,21 storyNameToKey: {},22 namedExports: {},23 };24 const storyExports = [];25 const includeStories = [];26 let metaExport: MetaExport | null = null;27 const { code } = generate(root, {});28 let contents: t.ExpressionStatement;29 root.program.body.forEach((child) => {30 if (t.isExpressionStatement(child) && t.isJSXFragment(child.expression)) {31 if (contents) throw new Error('duplicate contents');32 contents = child;33 } else if (34 t.isExportNamedDeclaration(child) &&35 t.isVariableDeclaration(child.declaration) &&36 child.declaration.declarations.length === 137 ) {38 const declaration = child.declaration.declarations[0];39 if (t.isVariableDeclarator(declaration) && t.isIdentifier(declaration.id)) {40 const { name } = declaration.id;41 context.namedExports[name] = declaration.init;42 }43 }44 });45 if (contents) {46 const jsx = contents.expression as t.JSXFragment;47 jsx.children.forEach((child) => {48 if (t.isJSXElement(child)) {49 if (t.isJSXIdentifier(child.openingElement.name)) {50 const name = child.openingElement.name.name;51 let stories;52 if (['Canvas', 'Preview'].includes(name)) {53 stories = genCanvasExports(child, context);54 } else if (name === 'Story') {55 stories = genStoryExport(child, context);56 } else if (name === 'Meta') {57 const meta = genMeta(child, options);58 if (meta) {59 if (metaExport) {60 throw new Error('Meta can only be declared once');61 }62 metaExport = meta;63 }64 }65 if (stories) {66 Object.entries(stories).forEach(([key, story]) => {67 includeStories.push(key);68 storyExports.push(story);69 });70 }71 }72 } else if (t.isJSXExpressionContainer(child)) {73 // Skip string literals & other JSX expressions74 } else {75 throw new Error(`Unexpected JSX child: ${child.type}`);76 }77 });78 }79 if (metaExport) {80 if (!storyExports.length) {81 storyExports.push('export const __page = () => { throw new Error("Docs-only story"); };');82 storyExports.push('__page.parameters = { docsOnly: true };');83 includeStories.push('__page');84 }85 } else {86 metaExport = {};87 }88 metaExport.includeStories = JSON.stringify(includeStories);89 const fullJsx = [90 ...storyExports,91 `const componentMeta = ${stringifyMeta(metaExport)};`,92 `const mdxStoryNameToKey = ${JSON.stringify(context.storyNameToKey)};`,93 wrapperJs,94 'export default componentMeta;',95 ].join('\n\n');96 return fullJsx;97}98export const plugin = (store: any) => (root: any) => {99 const estree = store.toEstree(root);100 // toBabel mutates root, so we need to clone it101 const clone = cloneDeep(estree);102 const babel = toBabel(clone);103 store.exports = extractExports(babel, {});104 return root;105};106export const postprocess = (code: string, extractedExports: string) => {107 const lines = code.toString().trim().split('\n');108 // /*@jsxRuntime automatic @jsxImportSource react*/109 const first = lines.shift();110 return [111 first,112 'import { assertIsFn, AddContext } from "@storybook/addon-docs";',113 ...lines.filter((line) => !line.match(/^export default/)),114 SEPARATOR,115 extractedExports,116 ].join('\n');117};118export const mdxSync = (code: string) => {119 const { compileSync } = require('@mdx-js/mdx');120 const { toEstree } = require('hast-util-to-estree');121 const store = { exports: '', toEstree };122 const output = compileSync(code, {123 rehypePlugins: [[plugin, store]],124 });125 return postprocess(output.toString(), store.exports);126};...
loadCsfFile.js
Source:loadCsfFile.js
1import { toId } from '@storybook/csf';2export function loadCsfFile({ default: meta, ...storyExports }) {3 return {4 meta,5 ...Object.fromEntries(6 Object.entries(storyExports).map(([exportName, story]) => [7 toId(meta.title, exportName),8 story,9 ])10 ),11 };...
Using AI Code Generation
1const { storyExports } = require('storybook-test-runner');2const stories = storyExports(require.context('../src', true, /\.stories\.js$/));3const storybookTestRunner = require('storybook-test-runner');4const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/));5const storybookTestRunner = require('storybook-test-runner');6const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {7});8const storybookTestRunner = require('storybook-test-runner');9const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {10});11const storybookTestRunner = require('storybook-test-runner');12const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {13});14const storybookTestRunner = require('storybook-test-runner');15const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {16});17const storybookTestRunner = require('storybook-test-runner');18const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {19});20const storybookTestRunner = require('storybook-test-runner');21const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {22});23const storybookTestRunner = require('storybook-test-runner');24const stories = storybookTestRunner(require.context('../src', true, /\.stories\.js$/), {25});26const storybookTestRunner = require('storybook-test-runner');27const stories = storybookTestRunner(require
Using AI Code Generation
1import { storyExports } from 'storybook-test-runner'2import { storiesOf } from '@storybook/react'3const stories = storyExports(require.context('../src', true, /stories\.js$/))4stories.forEach(story => {5 storiesOf(story.kind, module).add(story.name, story.story)6})7import React from 'react'8import { storiesOf } from '@storybook/react'9storiesOf('Button', module).add('with text', () => (10import React from 'react'11import { storiesOf } from '@storybook/react'12storiesOf('Link', module).add('with text', () => (13import React from 'react'14import { storiesOf } from '@storybook/react'15storiesOf('Label', module).add('with text', () => (16import React from 'react'17import { storiesOf } from '@storybook/react'18storiesOf('Text', module).add('with text', () => (19import React from 'react'20import { storiesOf } from '@storybook/react'21storiesOf('Heading', module).add('with text', () => (22import React from 'react'23import { storiesOf } from '@storybook/react'24storiesOf('Paragraph', module).add('with text', () => (25import React from 'react'26import { storiesOf } from '@storybook/react'27storiesOf('Box', module).add('with text', () => (28import React from 'react'29import { storiesOf } from '@storybook/react'30storiesOf('Container', module).add('with text', () => (31import React from 'react'32import { storiesOf } from '@storybook
Using AI Code Generation
1const { storyExports } = require('storybook-test-runner');2const { storybookTestRunner } = require('storybook-test-runner');3const { storybookTestRunner } = require('storybook-test-runner');4const storyExports = require('storybook-test-runner').storyExports;5const storybookTestRunner = require('storybook-test-runner').storybookTestRunner;6const storybookTestRunner = require('storybook-test-runner').storybookTestRunner;7const storybookTestRunner = require('storybook-test-runner');8const storyExports = storybookTestRunner.storyExports;9const storybookTestRunner = require('storybook-test-runner');10const storybookTestRunner = require('storybook-test-runner');11const storybookTestRunner = storybookTestRunner.storybookTestRunner;12const { storyExports } = require('storybook-test-runner');13const { storybookTestRunner } = require('storybook-test-runner');14const { storybookTestRunner } = require('storybook-test-runner');15const storyExports = require('storybook-test-runner').storyExports;16const storybookTestRunner = require('storybook-test-runner').storybookTestRunner;17const storybookTestRunner = require('storybook-test-runner').storybookTestRunner;18const storybookTestRunner = require('storybook-test-runner');19const storyExports = storybookTestRunner.storyExports;20const storybookTestRunner = require('storybook-test-runner');
Using AI Code Generation
1const { storyExports } = require('storybook-test-runner');2const stories = storyExports(require.context('../stories', true, /\.stories\.(js|mdx)$/));3const { storybookTestRunner } = require('storybook-test-runner');4const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(js|mdx)$/));5const { storybookTestRunner } = require('storybook-test-runner');6const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(js|mdx)$/), {7});8const { storybookTestRunner } = require('storybook-test-runner');9const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(js|mdx)$/), {10});11const { storybookTestRunner } = require('storybook-test-runner');12const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(js|mdx)$/), {13});14const { storybookTestRunner } = require('storybook-test-runner');15const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(js|mdx)$/), {16});17const { storybookTestRunner } = require('storybook-test-runner');18const stories = storybookTestRunner(require.context('../stories', true, /\.stories\.(
Using AI Code Generation
1const storyExports = require('storybook-test-runner').storyExports;2const storyExports = require('storybook-test-runner').storyExports;3module.exports = storyExports('stories/*.stories.js');4module.exports = {5 output: {6 },7 module: {8 {9 {10 loader: require.resolve('@storybook/addon-storyshots/loader'),11 options: {12 storyKindRegex: /^((?!.*?DontTest).)*$/,13 },14 },15 },16 },17};18const storyExports = require('storybook-test-runner').storyExports;19module.exports = storyExports('stories/*.stories.js');20const storyExports = require('storybook-test-runner').storyExports;21module.exports = storyExports('stories/*.stories.js');22const storyExports = require('storybook-test-runner').storyExports;23module.exports = storyExports('stories/*.stories.js');24const storyExports = require('storybook-test-runner').storyExports;25module.exports = storyExports('stories/*.stories.js');26const storyExports = require('storybook-test-runner').storyExports;27module.exports = storyExports('stories/*.stories.js');28const storyExports = require('storybook-test-runner').storyExports;29module.exports = storyExports('stories/*.stories.js');30const storyExports = require('storybook-test-runner').storyExports;31module.exports = storyExports('stories/*.stories.js');32const storyExports = require('storybook-test-runner').storyExports;33module.exports = storyExports('stories/*.stories.js');
Using AI Code Generation
1const { storyExports } = require('storybook-test-runner')2const stories = storyExports(require('../stories'))3import { storiesOf } from '@storybook/react'4import { withKnobs, text, boolean, number } from '@storybook/addon-knobs/react'5import { withInfo } from '@storybook/addon-info'6import MyComponent from './MyComponent'7storiesOf('MyComponent', module)8 .addDecorator(withKnobs)9 .addDecorator(withInfo)10 .add('with text', () => (11 <MyComponent text={text('text', 'hello')} />12 .add('with numbers', () => (13 <MyComponent number={number('number', 5)} />14 .add('with booleans', () => (15 <MyComponent boolean={boolean('boolean', true)} />16import React from 'react'17import { shallow } from 'enzyme'18import { storyExports } from 'storybook-test-runner'19import { stories } from '../stories'20const story = storyExports(stories)[0].story21const component = shallow(story())22test('should render the text', () => {23 expect(component.text()).toBe('hello')24})25import React from 'react'26import { shallow } from 'enzyme'27import { storyExports } from 'storybook-test-runner'28import { stories } from '../stories'29const story = storyExports(stories)[1].story30const component = shallow(story())31test('should render the number', () => {32 expect(component.text()).toBe('5')33})34import React from 'react'35import { shallow } from '
Using AI Code Generation
1import { storyExports } from 'storybook-test-runner';2export default storyExports;3import stories from './test.js';4import { testStories } from 'storybook-test-runner';5testStories(stories, {6});
Using AI Code Generation
1import storyExports from 'storybook-test-runner';2import { stories } from '../src/components/MyComponent.stories.js';3storyExports.runStory(stories, 'MyComponent', 'MyComponent');4import storyExports from 'storybook-test-runner';5import { stories } from '../src/components/MyComponent.stories.js';6storyExports.runStories(stories);7import storyExports from 'storybook-test-runner';8import * as stories from '../src/components';9storyExports.runStories(stories);10import storyExports from 'storybook-test-runner';11import * as stories from '../src/components';12storyExports.runStories(stories, /MyComponent/);13import storyExports from 'storybook-test-runner';14import * as stories from '../src/components';15storyExports.runStories(stories, /MyComponent/, {16 knobs: {17 }18});19- `knobs`: An object of options to pass to the [knobs](
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!