Storybook Runner все ще знаходиться в БЕТА-версії, документація пізніше буде перенесена на сторінки документації WebdriverIO.
Цей модуль тепер підтримує Storybook з новим візуальним раннером. Цей раннер автоматично сканує локальний/віддалений екземпляр Storybook і створює елементні знімки екрану кожного компонента. Це можна зробити, додавши
export const config: WebdriverIO.Config = {
services: ["visual"],
};
до ваших services
і запустивши npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
через командний рядок.
За замовчуванням використовується Chrome у безголовому режимі.
[!NOTE]
- Більшість опцій візуального тестування також працюватимуть для Storybook Runner, дивіться документацію WebdriverIO.
- Storybook Runner перевизначить всі ваші можливості і може запускатися тільки на браузерах, які він підтримує, див.
--browsers
.
- Storybook Runner не підтримує існуючу конфігурацію, яка використовує Multiremote capabilities і видасть помилку.
- Storybook Runner підтримує тільки Desktop Web, а не Mobile Web.
Опції сервісу Storybook Runner
Опції сервісу можна надати так
export const config: WebdriverIO.Config = {
services: [
[
'visual',
{
baselineFolder: join(process.cwd(), './__snapshots__/'),
debug: true,
storybook: {
additionalSearchParams: new URLSearchParams({foo: 'bar', abc: 'def'}),
clip: false,
clipSelector: ''#some-id,
numShards: 4,
skipStories: ['example-button--secondary', 'example-button--small'],
url: 'https://www.bbc.co.uk/iplayer/storybook/',
version: 6,
getStoriesBaselinePath: (category, component) => `path__${category}__${component}`,
},
},
],
],
}
Опції CLI для Storybook Runner
--additionalSearchParams
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням: ''
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
Додає додаткові параметри пошуку до URL Storybook.
Дивіться документацію URLSearchParams для отримання додаткової інформації. Рядок має бути валідним рядком URLSearchParams.
[!NOTE]
Подвійні лапки потрібні, щоб запобігти інтерпретації &
як роздільника команд.
Наприклад, з --additionalSearchParams="foo=bar&abc=def"
буде створено наступний URL Storybook для тестування історій: http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням:
chrome
, ви можете вибрати з chrome|firefox|edge|safari
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- ПРИМІТКА: Доступно тільки через CLI
Використовуватиме вказані браузери для створення знімків екрану компонентів
[!NOTE]
Переконайтеся, що у вас встановлені браузери, які ви хочете використовувати, на локальній машині
--clip
- Тип:
boolean
- Обов'язковий: Ні
- За замовчуванням:
true
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
Якщо вимкнено, буде створено знімок екрану всього вікна. Якщо включено, буде створено знімки екрану елементів на основі --clipSelector
, що зменшить кількість білого простору навколо знімка компонента та зменшить розмір знімка.
--clipSelector
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням:
#storybook-root > :first-child
для Storybook V7 та #root > :first-child:not(script):not(style)
для Storybook V6, див. також --version
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
Це селектор, який буде використовуватися:
- для вибору елемента, знімок якого потрібно зробити
- для елемента, який потрібно дочекатися, щоб він став видимим, перед створенням знімка
--devices
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням: Ви можете вибрати з
deviceDescriptors.ts
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- ПРИМІТКА: Доступно тільки через CLI
Використовуватиме вказані пристрої, які відповідають deviceDescriptors.ts
, для створення знімків екрану компонентів
[!NOTE]
- Якщо вам не вистачає конфігурації пристрою, будь ласка, не соромтеся подати запит на функцію
- Це працюватиме тільки з Chrome:
- якщо ви надасте
--devices
, то всі екземпляри Chrome працюватимуть у режимі Mobile Emulation
- якщо ви також вказуєте інші браузери, окрім Chrome, наприклад,
--devices --browsers=firefox,safari,edge
, то Chrome у режимі мобільної емуляції буде автоматично додано
- Storybook Runner за замовчуванням створює знімки елементів, якщо ви хочете побачити повний знімок екрану з мобільною емуляцією, то вкажіть
--clip=false
через командний рядок
- Ім'я файлу буде, наприклад, виглядати так
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- SRC: Тестування мобільного веб-сайту на десктопі з використанням мобільної емуляції може бути корисним, але тестувальники повинні знати, що існує багато тонких відмінностей, таких як:
- повністю інший GPU, що може призвести до великих змін у продуктивності;
- мобільний інтерфейс не емулюється (зокрема, приховування URL-бару впливає на висоту сторінки);
- спливаюче вікно роз'яснення (де ви вибираєте одну з кількох дотичних цілей) не підтримується;
- багато апаратних API (наприклад, подія orientationchange) недоступні.
--headless
- Тип:
boolean
- Обов'язковий: Ні
- За замовчуванням:
true
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- ПРИМІТКА: Доступно тільки через CLI
За замовчуванням запускає тести в безголовому режимі (якщо браузер його підтримує) або можна вимкнути
--numShards
- Тип:
number
- Обов'язковий: Ні
- За замовчуванням:
true
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
Це кількість паралельних екземплярів, які будуть використовуватися для запуску історій. Це буде обмежено maxInstances
у вашому файлі wdio.conf
.
[!IMPORTANT]
При запуску в headless
-режимі не збільшуйте кількість до більше ніж 20, щоб запобігти нестабільності через обмеження ресурсів
--skipStories
- Тип:
string|regex
- Обов'язковий: Ні
- За замовчуванням: null
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
Це може бути:
- рядок (
example-button--secondary,example-button--small
)
- або регулярний вираз (
"/.*button.*/gm"
)
для пропуску певних історій. Використовуйте id
історії, який можна знайти в URL історії. Наприклад, id
в цьому URL http://localhost:6006/?path=/story/example-page--logged-out
- це example-page--logged-out
--url
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням:
http://127.0.0.1:6006
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
URL, де розміщений ваш екземпляр Storybook.
--version
- Тип:
number
- Обов'язковий: Ні
- За замовчуванням: 7
- Приклад:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
Це версія Storybook, за замовчуванням 7
. Це потрібно, щоб знати, чи потрібно використовувати clipSelector
для V6.
Storybook Interaction Testing
Storybook Interaction Testing дозволяє взаємодіяти з вашим компонентом, створюючи користувацькі скрипти з командами WDIO для встановлення компонента у певний стан. Наприклад, див. фрагмент коду нижче:
import { browser, expect } from "@wdio/globals";
describe("Storybook Interaction", () => {
it("should create screenshots for the logged in state when it logs out", async () => {
const componentId = "example-page--logged-in";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
await $("button=Log out").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
});
it("should create screenshots for the logged out state when it logs in", async () => {
const componentId = "example-page--logged-out";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
await $("button=Log in").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
});
});
Виконуються два тести на двох різних компонентах. Кожен тест спочатку встановлює стан, а потім робить знімок екрану. Ви також помітите, що було введено нову власну команду, яку можна знайти тут.
Вищевказаний spec-файл можна зберегти в папці та додати до командного рядка наступною командою:
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
Storybook Runner спочатку автоматично просканує ваш екземпляр Storybook, а потім додасть ваші тести до історій, які потрібно порівняти. Якщо ви не хочете, щоб компоненти, які ви використовуєте для тестування взаємодії, порівнювалися двічі, ви можете додати фільтр для видалення "типових" історій зі сканування, надавши фільтр --skipStories
. Це виглядатиме так:
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
Нова власна команда
Нова власна команда browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
буде додана до об'єкту browser/driver
, яка автоматично завантажить компонент і чекатиме, доки він не буде готовий, тому вам не потрібно використовувати метод browser.url('url.com')
. Її можна використовувати так:
import { browser, expect } from "@wdio/globals";
describe("Storybook Interaction", () => {
it("should create screenshots for the logged in state when it logs out", async () => {
const componentId = "example-page--logged-in";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
await $("button=Log out").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
});
it("should create screenshots for the logged out state when it logs in", async () => {
const componentId = "example-page--logged-out";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
await $("button=Log in").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
});
});
Опції такі:
additionalSearchParams
- Тип:
URLSearchParams
- Обов'язковий: Ні
- За замовчуванням:
new URLSearchParams()
- Приклад:
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
Це додасть додаткові параметри пошуку до URL Storybook, у наведеному вище прикладі URL буде http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
Дивіться документацію URLSearchParams для отримання додаткової інформації.
clipSelector
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням:
#storybook-root > :first-child
для Storybook V7 та #root > :first-child:not(script):not(style)
для Storybook V6
- Приклад:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
Це селектор, який буде використовуватися:
- для вибору елемента, знімок якого потрібно зробити
- для елемента, який потрібно дочекатися, щоб він став видимим, перед створенням знімка
- Тип:
string
- Обов'язковий: так
- Приклад:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
Використовуйте id
історії, який можна знайти в URL історії. Наприклад, id
в цьому URL http://localhost:6006/?path=/story/example-page--logged-out
- це example-page--logged-out
timeout
- Тип:
number
- Обов'язковий: Ні
- За замовчуванням: 1100 мілісекунд
- Приклад:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
Максимальний час очікування видимості компонента після завантаження на сторінці
url
- Тип:
string
- Обов'язковий: Ні
- За замовчуванням:
http://127.0.0.1:6006
- Приклад:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
URL, де розміщений ваш екземпляр Storybook.