Storybook Runner все ще перебуває в BETA, документація пізніше буде перенесена на сторінки документації WebdriverIO.
Цей модуль тепер підтримує Storybook з новим Visual Runner. Цей runner автоматично сканує локальний/віддалений екземпляр Storybook і створює знімки елементів для кожного компонента. Це можна зробити, додавши
export const config: WebdriverIO.Config = {
services: ["visual"],
};
до ваших services
і запустивши npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
через командний рядок.
За замовчуванням він використовуватиме Chrome у безголовому режимі як браузер за замовчуванням.
[!NOTE]
- Більшість опцій Visual Testing також працюватимуть для Storybook Runner, дивіться документацію WebdriverIO.
- Storybook Runner перезапише всі ваші capabilities і може працювати лише на тих браузерах, які він підтримує, дивіться
--browsers
.
- Storybook Runner не підтримує наявну конфігурацію, яка використовує можливості Multiremote, і викине помилку.
- 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}`,
},
},
],
],
}
Опції командного рядка 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, що може призвести до великих змін продуктивності;
- мобільний UI не емулюється (зокрема, приховування 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
Тестування взаємодії в Storybook дозволяє взаємодіяти з вашим компонентом, створюючи власні скрипти з командами 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.