|
1 | 1 | # @wdio/visual-service
|
2 | 2 |
|
| 3 | +## 5.1.0 |
| 4 | + |
| 5 | +### Minor Changes |
| 6 | + |
| 7 | +- a0e29f2: Adding storybook interaction testing |
| 8 | + |
| 9 | + ### Storybook Interaction Testing |
| 10 | + |
| 11 | + Storybook Interaction Testing allows you to interact with your component by creating custom scripts with WDIO commands to set a component into a certain state. For example, see the code snippet below: |
| 12 | + |
| 13 | + ```ts |
| 14 | + import { browser, expect } from "@wdio/globals"; |
| 15 | + |
| 16 | + describe("Storybook Interaction", () => { |
| 17 | + it("should create screenshots for the logged in state when it logs out", async () => { |
| 18 | + const componentId = "example-page--logged-in"; |
| 19 | + await browser.waitForStorybookComponentToBeLoaded({ id: componentId }); |
| 20 | + |
| 21 | + await expect($("header")).toMatchElementSnapshot( |
| 22 | + `${componentId}-logged-in-state` |
| 23 | + ); |
| 24 | + await $("button=Log out").click(); |
| 25 | + await expect($("header")).toMatchElementSnapshot( |
| 26 | + `${componentId}-logged-out-state` |
| 27 | + ); |
| 28 | + }); |
| 29 | + |
| 30 | + it("should create screenshots for the logged out state when it logs in", async () => { |
| 31 | + const componentId = "example-page--logged-out"; |
| 32 | + await browser.waitForStorybookComponentToBeLoaded({ id: componentId }); |
| 33 | + |
| 34 | + await expect($("header")).toMatchElementSnapshot( |
| 35 | + `${componentId}-logged-out-state` |
| 36 | + ); |
| 37 | + await $("button=Log in").click(); |
| 38 | + await expect($("header")).toMatchElementSnapshot( |
| 39 | + `${componentId}-logged-in-state` |
| 40 | + ); |
| 41 | + }); |
| 42 | + }); |
| 43 | + ``` |
| 44 | + |
| 45 | + Two tests on two different components are executed. Each test first sets a state and then takes a screenshot. You will also notice that a new custom command has been introduced, which can be found [here](#new-custom-command). |
| 46 | + |
| 47 | + The above spec file can be saved in a folder and added to the command line with the following command: |
| 48 | + |
| 49 | + ```sh |
| 50 | + npm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts' |
| 51 | + ``` |
| 52 | + |
| 53 | + The Storybook runner will first automatically scan your Storybook instance and then add your tests to the stories that need to be compared. If you don't want the components that you use for interaction testing to be compared twice, you can add a filter to remove the "default" stories from the scan by providing the [`--skipStories`](#--skipstories) filter. This would look like this: |
| 54 | + |
| 55 | + ```sh |
| 56 | + npm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts' |
| 57 | + ``` |
| 58 | + |
| 59 | + ### New Custom Command |
| 60 | + |
| 61 | + A new custom command called `browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })` will be added to the `browser/driver`-object that will automatically load the component and wait for it to be done, so you don't need to use the `browser.url('url.com')` method. It can be used like this |
| 62 | + |
| 63 | + ```ts |
| 64 | + import { browser, expect } from "@wdio/globals"; |
| 65 | + |
| 66 | + describe("Storybook Interaction", () => { |
| 67 | + it("should create screenshots for the logged in state when it logs out", async () => { |
| 68 | + const componentId = "example-page--logged-in"; |
| 69 | + await browser.waitForStorybookComponentToBeLoaded({ id: componentId }); |
| 70 | + |
| 71 | + await expect($("header")).toMatchElementSnapshot( |
| 72 | + `${componentId}-logged-in-state` |
| 73 | + ); |
| 74 | + await $("button=Log out").click(); |
| 75 | + await expect($("header")).toMatchElementSnapshot( |
| 76 | + `${componentId}-logged-out-state` |
| 77 | + ); |
| 78 | + }); |
| 79 | + |
| 80 | + it("should create screenshots for the logged out state when it logs in", async () => { |
| 81 | + const componentId = "example-page--logged-out"; |
| 82 | + await browser.waitForStorybookComponentToBeLoaded({ id: componentId }); |
| 83 | + |
| 84 | + await expect($("header")).toMatchElementSnapshot( |
| 85 | + `${componentId}-logged-out-state` |
| 86 | + ); |
| 87 | + await $("button=Log in").click(); |
| 88 | + await expect($("header")).toMatchElementSnapshot( |
| 89 | + `${componentId}-logged-in-state` |
| 90 | + ); |
| 91 | + }); |
| 92 | + }); |
| 93 | + ``` |
| 94 | + |
| 95 | + The options are: |
| 96 | + |
| 97 | + #### `clipSelector` |
| 98 | + |
| 99 | + - **Type:** `string` |
| 100 | + - **Mandatory:** No |
| 101 | + - **Default:** `#storybook-root > :first-child` for Storybook V7 and `#root > :first-child:not(script):not(style)` for Storybook V6 |
| 102 | + - **Example:** |
| 103 | + |
| 104 | + ```ts |
| 105 | + await browser.waitForStorybookComponentToBeLoaded({ |
| 106 | + clipSelector: "#your-selector", |
| 107 | + id: "componentId", |
| 108 | + }); |
| 109 | + ``` |
| 110 | + |
| 111 | + This is the selector that will be used: |
| 112 | + |
| 113 | + - to select the element to take the screenshot of |
| 114 | + - for the element to wait to be visible before a screenshot is taken |
| 115 | + |
| 116 | + #### `id` |
| 117 | + |
| 118 | + - **Type:** `string` |
| 119 | + - **Mandatory:** yes |
| 120 | + - **Example:** |
| 121 | + |
| 122 | + ```ts |
| 123 | + await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' }) |
| 124 | + ``` |
| 125 | + |
| 126 | + Use the `id` of the story that can be found in the URL of the story. For example, the `id` in this URL `http://localhost:6006/?path=/story/example-page--logged-out` is `example-page--logged-out` |
| 127 | + |
| 128 | + #### `timeout` |
| 129 | + |
| 130 | + - **Type:** `number` |
| 131 | + - **Mandatory:** No |
| 132 | + - **Default:** 1100 milliseconds |
| 133 | + - **Example:** |
| 134 | + |
| 135 | + ```ts |
| 136 | + await browser.waitForStorybookComponentToBeLoaded({ |
| 137 | + id: "componentId", |
| 138 | + timeout: 20000, |
| 139 | + }); |
| 140 | + ``` |
| 141 | + |
| 142 | + The max timeout we want to wait for a component to be visible after loading on the page |
| 143 | + |
| 144 | + #### `url` |
| 145 | + |
| 146 | + - **Type:** `string` |
| 147 | + - **Mandatory:** No |
| 148 | + - **Default:** `http://127.0.0.1:6006` |
| 149 | + - **Example:** |
| 150 | + |
| 151 | + ```ts |
| 152 | + await browser.waitForStorybookComponentToBeLoaded({ |
| 153 | + id: "componentId", |
| 154 | + url: "https://your.url", |
| 155 | + }); |
| 156 | + ``` |
| 157 | + |
| 158 | + The URL where your Storybook instance is hosted. |
| 159 | + |
3 | 160 | ## 5.0.1
|
4 | 161 |
|
5 | 162 | ### Patch Changes
|
|
0 commit comments