Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@doctoright/storybook-chrome-screenshot
Advanced tools
A Storybook addon, Save the screenshot image of your stories! via puppeteer.
A Storybook Addon, Save the screenshot image of your stories :camera: via Puppeteer.
storybook-chrome-screenshot
takes a screenshot and saves it.
It is primarily responsible for image generation necessary for Visual Testing such as reg-viz
.
storybook-chrome-screenshot
executes Storybook in a child process and accesses the launched page using Puppeteer. It is a very simple mechanism.
For that reason, you can easily shoot screenshots by simply creating a story that works with the browser.
It is very easy to introduce storybook-chrome-screenshot
in your project.
First install storybook-chrome-screenshot
.
$ npm install --save-dev storybook-chrome-screenshot
Note: Please do not use globally but let it operate locally.
Next, register Addon.
.storybook/addons.js
// Other addons...
import 'storybook-chrome-screenshot/register';
Add initScreenshot decorator. It has to be before the first withScreenshot decorator. Addon uses it to catch the finish of the components' rendering.
Example: .storybook/config.js
import { addDecorator } from '@storybook/react';
import { initScreenshot } from 'storybook-chrome-screenshot';
addDecorator(initScreenshot());
Create a story with withScreenshot.
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withScreenshot } from 'storybook-chrome-screenshot';
import Button from './Button';
storiesOf('Button', module).add('with text', withScreenshot()(() => <Button>Text</Button>));
This function works well even if you use Angular:
import { storiesOf } from '@storybook/angular';
import { withScreenshot } from 'storybook-chrome-screenshot';
import { MyButtonComponent } from '../src/app/my-button/my-button.component';
storiesOf('Button', module).add(
'with custom label',
withScreenshot()(() => ({
component: MyButtonComponent,
props: {
text: 'Text'
}
}))
);
Of course, Vue.js works the same way:
import { storiesOf } from '@storybook/vue';
import { withScreenshot } from 'storybook-chrome-screenshot';
import MyButton from './Button.vue';
storiesOf('MyButton', module)
.add(
'pre-registered component',
withScreenshot()(() => ({
template: '<my-button :rounded="true">A Button with rounded edges</my-button>'
}))
)
.add(
'template + component',
withScreenshot()(() => ({
components: { MyButton },
template: '<my-button>Button rendered in a template</my-button>'
}))
)
.add(
'render + component',
withScreenshot()(() => ({
render: (h) => h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton'])
}))
);
storybook-chrome-screenshot
CommandOpen package.json
and add a screenshot
script for run storybook-chrome-screenshot
command.
{
"scripts": {
"screenshot": "storybook-chrome-screenshot -p 9001 -c .storybook"
}
}
Note: Parameters such as ports and configuration files should match the parameters of the
Storybook
you are currently using.
After that, just run the npm run screenshot
command, shotting a component wrapped with withScreenshot and save the images.
$ npm run screenshot
Or by using addDecorator()
, it is possible to shotting all the decorated stories.
import { storiesOf } from '@storybook/react';
import { withScreenshot } from 'storybook-chrome-screenshot';
storiesOf('Button', module)
.addDecorator(
withScreenshot({
/* ...options */
})
)
.add('with primary', () => <Button primary>Primary Button</Button>)
.add('with secondary', () => <Button secondary>Secondary Button</Button>);
This decorator has to be added to every story. Addon uses it to understand when story's rendering is finished.
Important!. initScreenshot
has to be added before the first withScreenshot.
Example: .storybook/config.js
import { addDecorator } from '@storybook/react';
import { initScreenshot } from 'storybook-chrome-screenshot';
addDecorator(initScreenshot());
Notify Puppeteer of the story wrapped in this function and let it recognize it as the target of the screenshot.
The following objects of options
can be specified.
{
namespace: 'global', // namespace for your screenshots. It is using in the filenames, e.g. Button-with-primary_global.png
delay: 0, // Delay milliseconds when shooting screenshots
waitFor: '', // User defined trigger function name to shoot screenshots. See "Full control the screenshot timing" section below.
viewport: { // Browser's viewport when shooting screenshots. (See: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagesetviewportviewport)
width: 1024,
height: 768,
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
isLandscape: false,
},
filePattern: '{kind}-{story}-{knobs}_{ns}-{vp}' // file pattern, combined from kind, story name, used knobs, namespace and viewport
}
Also, By passing the array
to viewport
, you can easily shoot multiple Viewports.
{
viewport: [
// Mobile
{
width: 300,
height: 420,
isMobile: true,
hasTouch: true,
},
// Tablet
{
width: 768,
height: 800,
isMobile: true,
hasTouch: true,
},
// Desktop
{
width: 1024,
height: 768,
},
],
}
Sets the default value of the option used with withScreenshot().
It is useful for changing Viewport of all stories.
Example: .storybook/config.js
import { setScreenshotOptions } from 'storybook-chrome-screenshot';
setScreenshotOptions({
viewport: {
width: 768,
height: 400,
deviceScaleFactor: 2
}
});
Get the current option used with withScreenshot().
import { getScreenshotOptions } from 'storybook-chrome-screenshot';
console.log(getScreenshotOptions());
// => Current screenshot options...
$ $(npm bin)/storybook-chrome-screenshot --help
Usage: storybook-chrome-screenshot [options]
Options:
-V, --version output the version number
-p, --port [number] Storybook server port. (default: 9001)
-h, --host [string] Storybook server host. (default: localhost)
-s, --static-dir <dir-names> Directory where to load static files from.
-c, --config-dir [dir-name] Directory where to load Storybook configurations from. (default: .storybook)
-o, --output-dir [dir-name] Directory where screenshot images are saved. (default: __screenshots__)
--parallel [number] Number of Page Instances of Puppeteer to be activated when shooting screenshots. (default: 4)
--filter-kind [regexp] Filter of kind with RegExp. (example: "Button$")
--filter-story [regexp] Filter of story with RegExp. (example: "^with\s.+$")
--inject-files <file-names> Path to the JavaScript file to be injected into frame. (default: )
--browser-timeout [number] Timeout milliseconds when Puppeteer opens Storybook. (default: 30000)
--puppeteer-launch-config [json] JSON string of launch config for Puppeteer. (default: {"args":["--no-sandbox","--disable-setuid-sandbox", "--disable-dev-shm-usage"]})
--silent Suppress standard output.
--debug Enable debug mode.
-h, --help output usage information
When shooting screenshots, you may want to disable component animation. In this case it is easiest to inject Script using the --inject-files
option.
You can create ./disable-animation.js
and disable CSS Animation with the next snippet.
(() => {
const $iframe = document.getElementById('storybook-preview-iframe');
const $doc = $iframe.contentDocument;
const $style = $doc.createElement('style');
$style.innerHTML = `* {
transition: none !important;
animation: none !important;
}`;
$doc.body.appendChild($style);
})();
Pass the created file to the --inject-files
option.
$ $(npm bin)/storybook-chrome-screenshot --inject-files ./disable-animation.js [...more options]
Sometimes you may want to full-manage the timing of performing screenshot.
Use the waitFor
option if you think so. This string parameter should points a global function to return Promise
.
For example, the following setting makes the screenshot function wait for firing of fontLoading
:
<!-- ./storybook/preview-head.html -->
<link rel="preload" href="/some-heavy-asset.woff" as="font" onload="this.setAttribute('loaded', 'loaded')">
<script>
function fontLoading() {
const loaded = () => !!document.querySelector('link[rel="preload"][loaded="loaded"]');
if (loaded()) return Promise.resolve();
return new Promise((resolve, reject) => {
const id = setInterval(() => {
if (!loaded()) return;
clearInterval(id);
resolve();
}, 50);
});
}
</script>
import { setScreenshotOptions } from 'storybook-chrome-screenshot';
setScreenshotOptions({
waitFor: 'fontLoading',
});
The following tasks remain. Contributes are welcome :smiley:
git checkout -b my-new-feature
git commit -am 'Add some feature'
git push origin my-new-feature
Bugs, feature requests and comments are more than welcome in the issues.
We will develop using the following npm scripts.
npm run test
We will run Lint, unit test, E2E test in order.
Each test can also be executed individually with the following command.
# Run TSLint
$ npm run test:lint
# Run unit test using Jest
$ npm run test:unit
# Run E2E test
$ npm run test:e2e
# Run unit tests in watch mode
$ npm run test:watch
npm run build
Compile the source code written in TypeScript.
FAQs
A Storybook addon, Save the screenshot image of your stories! via puppeteer.
The npm package @doctoright/storybook-chrome-screenshot receives a total of 0 weekly downloads. As such, @doctoright/storybook-chrome-screenshot popularity was classified as not popular.
We found that @doctoright/storybook-chrome-screenshot demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.