-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from gemini-testing/sp.storybook
docs(storybook): add documentation about storybook
- Loading branch information
Showing
11 changed files
with
1,009 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
title: Screenshot testing with Storybook | ||
slug: screenshot-testing-with-storybook | ||
hide_table_of_contents: false | ||
date: 2024-09-26T13:00 | ||
--- | ||
|
||
Now, for automatic visual testing of your components, you only need Storybook with your components and the `@testplane/storybook` plugin. There’s no need to write any tests anymore. | ||
|
||
<!-- truncate --> | ||
|
||
[Storybook][storybook] is a tool for developing user interfaces based on components. It allows developers to independently visualize components in various states in an isolated environment, separate from other components. | ||
This "showroom" is perfect for screenshot testing your components, as this isolated environment makes such tests significantly more stable and faster compared to e2e testing. | ||
|
||
With the [@testplane/storybook][testplane-storybook] plugin, you can automatically verify changes to your components using screenshot testing without writing a single line of test code. | ||
You just need to describe your component in `Storybook` and Testplane will automatically generate all necessary tests upon execution, run them in the required browsers and provide a visual report for updating screenshots. | ||
Additionally, if a [play function][play-function] has been declared for the components, Testplane will execute it before the test begins to set the component to the desired state. | ||
|
||
However, if these capabilities are not enough, you can directly describe a Testplane test in the story file, which will be executed as an additional test for the component. | ||
|
||
How to use it? | ||
|
||
Learn more about this in our documentation [Screenshot testing with Storybook][vt-story]. | ||
Also you can try it yourself in our [example project][example] on GitHub with customized screenshot testing. | ||
|
||
[storybook]: https://storybook.js.org | ||
[testplane-storybook]: https://github.com/gemini-testing/testplane-storybook | ||
[play-function]: https://storybook.js.org/docs/writing-stories/play-function | ||
[vt-story]: ../../docs/v8/visual-testing/with-storybook | ||
[example]: https://github.com/gemini-testing/testplane/tree/master/examples/storybook-autoscreenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
import Admonition from "@theme/Admonition"; | ||
|
||
# @testplane/storybook | ||
|
||
## Overview {#overview} | ||
|
||
Use the [@testplane/storybook][testplane-storybook] plugin to automatically check the changes in your Storybook components with screenshot testing without a single line of test code. | ||
|
||
This plugin adds: | ||
|
||
- automatic screenshot tests for storybook stories; | ||
- an ability to write Testplane tests for storybook stories right inside of the stories. | ||
|
||
## Installation {#install} | ||
|
||
```bash | ||
npm install @testplane/storybook --save-dev | ||
``` | ||
|
||
## Setup {#setup} | ||
|
||
<Admonition type="info">Storybook 6.4+ is required to use this plugin.</Admonition> | ||
|
||
### Storybook | ||
|
||
If you use `storybook@6`, you will need to enable [buildStoriesJson][build-stories] feature in your `storybook` config: | ||
|
||
```typescript tytle=".storybook/main.js" | ||
export default { | ||
// ... | ||
features: { | ||
// ... | ||
buildStoriesJson: true, | ||
}, | ||
}; | ||
``` | ||
|
||
You don't need to do this with storybook@7 or storybook@8. | ||
|
||
### Testplane | ||
|
||
Add `@testplane/storybook` plugin into your Testplane config: | ||
|
||
```typescript title=".testplane.conf.ts" | ||
export default { | ||
plugins: { | ||
"@testplane/storybook": {}, | ||
|
||
// other Testplane plugins... | ||
}, | ||
|
||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
With this minimal config, you will be able to run `npx testplane --storybook` to autotest each storybook story with [Testplane assertView][assert-view] command. Testplane will open each story, wait for play function to finish (if defined), and then call `assertView` command. These tests would be generated in runtime. | ||
|
||
### Description of configuration parameters {#setup_description} | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<td>**Parameter**</td> | ||
<td>**Type**</td> | ||
<td>**Default**</td> | ||
<td>**Description**</td> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>enabled</td> | ||
<td>`Boolean`</td> | ||
<td>true</td> | ||
<td>Enable / disable plugin.</td> | ||
</tr> | ||
<tr> | ||
<td>storybookConfigDir</td> | ||
<td>`String`</td> | ||
<td>".storybook"</td> | ||
<td>Path to the storybook configuration directory.</td> | ||
</tr> | ||
<tr> | ||
<td>autoScreenshots</td> | ||
<td>`Boolean`</td> | ||
<td>true</td> | ||
<td>Enable / disable auto-screenshot tests</td> | ||
</tr> | ||
<tr> | ||
<td>localport</td> | ||
<td>`Number`</td> | ||
<td>6006</td> | ||
<td>Port to launch storybook dev server on.</td> | ||
</tr> | ||
<tr> | ||
<td>remoteStorybookUrl</td> | ||
<td>`String`</td> | ||
<td>""</td> | ||
<td>URL of the remote Storybook. If specified, local storybook dev sever would not be launched.</td> | ||
</tr> | ||
<tr> | ||
<td>browserIds</td> | ||
<td>`Array<String | RegExp>`</td> | ||
<td>[]</td> | ||
<td>Array of `browserId` to run storybook tests on. By default, all of browsers, specified in Testplane config would be used</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
|
||
<Admonition type="info"> | ||
Storybook tests performance greatly depends on [Testplane testsPerSession][testsPerSession] | ||
parameter, as these tests speeds up on reusing existing sessions, so setting values around 20+ | ||
is preferred. These tests ignore [Testplane isolation][isolation]. It would be turned off | ||
unconditionally. | ||
</Admonition> | ||
|
||
## Advanced usage | ||
|
||
If you have `ts-node` in your project, you can write your Testplane tests right inside of storybook story files: | ||
|
||
<Admonition type="info"> | ||
Storybook story files must have `.js` or `.ts` extension for this to work. Formats `jsx/tsx` are | ||
not supported yet. | ||
</Admonition> | ||
|
||
```typescript title="stories/Primary.stories.ts" | ||
import type { StoryObj } from "@storybook/react"; | ||
import type { WithTestplane } from "@testplane/storybook"; | ||
|
||
export const Primary: WithTestplane<StoryObj> = { | ||
args: { | ||
primary: true, | ||
label: "Button", | ||
}, | ||
testplane: { | ||
"my test": async ({ browser, expect }) => { | ||
const element = await browser.$(".storybook-button"); | ||
|
||
await expect(element).toHaveText("Button"); | ||
}, | ||
}, | ||
}; | ||
``` | ||
|
||
You can also specify extra options in story default config: | ||
|
||
```typescript | ||
import type { WithTestplane } from "@testplane/storybook"; | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
const meta: WithTestplane<Meta<typeof Button>> = { | ||
title: "Example/Button", | ||
component: Button, | ||
testplane: { | ||
skip: false, // if true, skips all Testplane tests from this story file | ||
autoscreenshotSelector: ".my-selector", // Custom selector to auto-screenshot elements | ||
browserIds: ["chrome"], // Testplane browsers to run tests from this story file | ||
assertViewOpts: { | ||
// override default assertView options for tests from this file | ||
ignoreDiffPixelCount: 5, | ||
}, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
``` | ||
|
||
If you decide to create separate config for storybook auto-tests (which is suggested), you need to specify config path via CLI option. For example: | ||
|
||
```bash | ||
npx testplane --storybook -c .testplane.storybook.conf.ts | ||
``` | ||
|
||
This allows you to store references next to your story files: | ||
|
||
```typescript title=".testplane.conf.ts" | ||
import path from "path"; | ||
import { getStoryFile } from "@testplane/storybook"; | ||
|
||
export default { | ||
screenshotsDir: test => { | ||
const relativeStoryFilePath = getStoryFile(test); | ||
const relativeStoryFileDirPath = path.dirname(relativeStoryFilePath); | ||
|
||
return path.join(relativeStoryFileDirPath, "screens", test.id, test.browserId); | ||
}, | ||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
In this example, screenshot references would be stored in `screens/<testId>/<browserId>` folder, next to each of your story files. | ||
|
||
## Useful links {#useful_links} | ||
|
||
- [@testplane/storybook plugin sources][testplane-storybook] | ||
- [assertView command][assert-view] | ||
|
||
[assert-view]: ../commands/browser/assertView.mdx | ||
[build-stories]: https://storybook.js.org/docs/6.4/configure/overview#feature-flags | ||
[isolation]: ../config/browsers.mdx#isolation | ||
[testplane-storybook]: https://github.com/gemini-testing/testplane-storybook | ||
[testplane]: https://github.com/gemini-testing/testplane | ||
[testsPerSession]: ../config/browsers.mdx#tests_per_session |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Visual testing | ||
|
||
Visual testing is implemented in testplane, with which the user can check the visual changes of an individual component, a viewport or the entire page. | ||
We recommend using the [html-reporter][html-reporter] plugin, which provides a user-friendly UI for analyzing tests, saving/updating modified images and running tests. | ||
|
||
![Html-report](/img/docs/html-reporter/html-reporter.overview.png) | ||
|
||
### Screenshot Comparison Features {#features} | ||
|
||
For screenshot checks, Testplane provides the `assertView` command, which allows you to take a screenshot of a specific element or the entire viewport. | ||
When the assertView command is invoked, it searches for the required element on the page with automatic waiting. By default, animations will be disabled on the page before taking a screenshot to eliminate potential instability in the test due to the changing state of the element. | ||
After taking a screenshot, the resulting image will be compared with the reference image. If the reference image does not exist yet, then it must be saved using the html reporter UI or the `--update-refs` CLI option. | ||
To compare images, we use our own library [looks-same][looks-same], which differs from competitors in high performance and accuracy of comparison. | ||
|
||
The following settings are taken into account during comparison: | ||
|
||
- the blinking cursor in text inputs is ignored by default; | ||
- elements specified in the comparison options are ignored in the image; | ||
- comparison accuracy settings (acceptable deviations) are considered; | ||
- anti-aliasing (the most common diffs in screenshots) accuracy settings for fonts are considered. | ||
|
||
### Usage {#usage} | ||
|
||
```typescript | ||
await browser.assertView(state, options); | ||
await browser.assertView(state, selector, options); | ||
await element.assertView(state, options); | ||
``` | ||
|
||
The `assertView` command is available both in the browser context and in the context of the found element. The set of arguments is different in these cases: | ||
|
||
```typescript | ||
it("check search view", async ({ browser }) => { | ||
// ... | ||
|
||
// screenshot of the current browser viewport | ||
await browser.assertView("viewport-screen"); | ||
|
||
// screenshot of a specific element on the page (call from the browser context) | ||
await browser.assertView("any-state-name", ".DocSearch", opts); | ||
|
||
const searchInput = await browser.$(".DocSearch"); | ||
await searchInput.click(); | ||
|
||
// taking screenshot of a previously found item (from the element context) | ||
await searchInput.assertView("any-state-name"); | ||
}); | ||
``` | ||
|
||
Read more about the capabilities of the `assertView' command in the relevant sections. | ||
|
||
### Useful links {#useful_links} | ||
|
||
- [browser.assertView command][browser-command] | ||
- [element.assertView command][element-command] | ||
|
||
[html-reporter]: ../../html-reporter/html-reporter-setup | ||
[looks-same]: https://github.com/gemini-testing/looks-same | ||
[browser-command]: https://testplane.io/docs/v8/commands/browser/assertView/ | ||
[element-command]: https://testplane.io/docs/v8/commands/element/assertView/ |
Oops, something went wrong.