Quick Start
storyshots integrates easily into existing applications thanks to its architecture.
Installation and Build
At the moment, the library is not published to any package registries due to an unstable package structure. Components are installed from local artifacts, not from a public registry.
Install dependencies in the root of the project:
npm install
Build packages and package them into an archive:
npm run build && npm run pack
Integration into Project
As a result, .tar artifacts will be generated. Descriptions of these components can be found in the architecture and modules sections.
For a standard CSR project using react, the following set will be sufficient:
@storyshots/core– the core ofstoryshots.@storyshots/react– the client preview forreactapplications.@storyshots/exec-preview– the preview server.
These modules must be placed in the project folder and added to VCS control:
project/
├── src/
├── offline/
│ ├── @storyshots-core-0.0.18.tgz
│ ├── @storyshots-react-0.0.18.tgz
│ └── @storyshots-exec-preview-0.0.18.tgz
└── package.json
Next, register the dependencies:
{
"devDependencies": {
"@storyshots/core": "file:offline/storyshots-core-0.0.18.tgz",
"@storyshots/react": "file:offline/storyshots-react-0.0.18.tgz",
"@storyshots/exec-preview": "file:offline/storyshots-exec-preview-0.0.18.tgz"
}
}
And install them:
npm i
Preview Description
Files related to storyshots in this guide are located in src/storyshots (see test location).
After installation, you're ready to define the preview client and your first stories. Let's start with the preview:
import { createPreviewApp } from '@storyshots/react';
// Initialize the preview
export const { it, run } = createPreviewApp({
/*
Define default behavior for external dependencies.
In this case, it's BE API methods.
*/
createExternals: (config) => ({
getUser: async () => ({ id: 1, name: 'John Doe' }),
}),
// Mark methods for logging calls
createJournalExternals: (externals, config) => ({
getUser: config.journal.asRecordable('getUser', externals.getUser),
}),
});
Then, define your first stories:
import { finder } from '@storyshots/core';
import { it } from '../preview/config';
export const stories = [
it('renders the application correctly'),
it('handles missing user gracefully', {
// Modify server behavior for this story
arrange: (externals) => ({ ...externals, getUser: async () => null }),
}),
it('allows to login', {
// Simulate actions on the page
act: (actor) => actor.click(finder.getByRole('button', { name: 'Login' })),
}),
];
Stories can be decomposed.
Then, run the defined stories by implementing the default render with dependency injection:
import { map } from '@storyshots/core';
import { run } from './config';
import { stories } from '../stories';
run(
map(stories, (story) => ({
render: (externals) => (
<Externals externals={externals}>
<App />
</Externals>
),
...story,
})),
);
Manager Description
Next, define the app server:
import { createExecPreview } from '@storyshots/exec-preview';
export function createAppServer() {
return createExecPreview({
ui: {
command: 'npx webpack-cli serve', // <- Script to run the app in dev mode
at: 'http://localhost:8080', // <- Dev server address
},
ci: {
command: 'npx webpack-cli build', // <- Build script
serve: './dist', // <- Location of the build artifact
},
});
}
Also, configure the used bundler (in this example, webpack), specifying the correct entry:
export default {
entry:
// process.env.STORYSHOTS is automatically set by @storyshots/exec-preview
process.env.STORYSHOTS === 'true' // <- Set entry for preview depending on the build mode.
? './src/storyshots/preview/index.tsx'
: './src/index.tsx',
// ... ///
};
More details about @storyshots/exec-preview can be found in this section.
After defining the server, define the general testing configuration:
import { ManagerConfig } from '@storyshots/core/manager';
import { createAppServer } from './createAppServer';
export default {
// List of tested devices
devices: [
{
name: 'desktop',
width: 1480,
height: 920,
},
],
// Paths to main artifacts: screenshots and records
paths: {
screenshots: path.join(process.cwd(), 'screenshots'),
records: path.join(process.cwd(), 'records'),
},
// App server configuration
preview: createAppServer(),
} satisfies ManagerConfig;
A full list of available settings is available in this section.
Then, start the UI mode using:
storyshots --ui /src/storyshots/manager/config.ts
To run all tests in headless mode, use:
storyshots /src/storyshots/manager/config.ts
Examples
- Example #1 –
react+webpack+ standardfetchqueries. - Example #2 –
react+webpack+rtk-query. - Example #3 –
next.js.