Storybook Runner jest nadal w fazie BETA, dokumentacja zostanie później przeniesiona na strony dokumentacji WebdriverIO.
Ten moduł teraz obsługuje Storybook z nowym Visual Runner. Runner ten automatycznie skanuje lokalną/zdalną instancję storybook i tworzy zrzuty ekranu elementów dla każdego komponentu. Można to zrobić, dodając
export const config: WebdriverIO.Config = {
services: ["visual"],
};
do twoich services
i uruchamiając npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
w wierszu poleceń.
Domyślnie użyje Chrome w trybie headless jako domyślnej przeglądarki.
[!NOTE]
- Większość opcji Visual Testing będzie również działać dla Storybook Runner, zobacz dokumentację WebdriverIO.
- Storybook Runner nadpisze wszystkie twoje capabilities i może działać tylko na przeglądarkach, które obsługuje, zobacz
--browsers
.
- Storybook Runner nie obsługuje istniejącej konfiguracji, która używa możliwości Multiremote i wyrzuci błąd.
- Storybook Runner obsługuje tylko Desktop Web, nie Mobile Web.
Opcje usługi Storybook Runner
Opcje usługi można dostarczyć w ten sposób
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}`,
},
},
],
],
}
Opcje CLI Storybook Runner
--additionalSearchParams
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie: ''
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
Dodaje dodatkowe parametry wyszukiwania do URL Storybooka.
Zobacz dokumentację URLSearchParams po więcej informacji. String musi być prawidłowym stringiem URLSearchParams.
[!NOTE]
Podwójne cudzysłowy są potrzebne, aby zapobiec interpretacji &
jako separatora poleceń.
Na przykład z --additionalSearchParams="foo=bar&abc=def"
wygeneruje następujący URL Storybooka dla testów historii: http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie:
chrome
, możesz wybrać spośród chrome|firefox|edge|safari
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- UWAGA: Dostępne tylko przez CLI
Użyje podanych przeglądarek do wykonywania zrzutów ekranu komponentów
[!NOTE]
Upewnij się, że masz zainstalowane przeglądarki, które chcesz używać na swoim lokalnym komputerze
--clip
- Typ:
boolean
- Obowiązkowe: Nie
- Domyślnie:
true
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
Gdy wyłączone, stworzy zrzut ekranu widoku. Gdy włączone, stworzy zrzuty ekranu elementów na podstawie --clipSelector
, co zmniejszy ilość białej przestrzeni wokół zrzutu ekranu komponentu i zmniejszy rozmiar zrzutu ekranu.
--clipSelector
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie:
#storybook-root > :first-child
dla Storybook V7 i #root > :first-child:not(script):not(style)
dla Storybook V6, zobacz także --version
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
Jest to selektor, który będzie używany:
- do wyboru elementu, którego zrzut ekranu ma być wykonany
- dla elementu, który ma być widoczny przed wykonaniem zrzutu ekranu
--devices
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie: Możesz wybrać z
deviceDescriptors.ts
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- UWAGA: Dostępne tylko przez CLI
Użyje podanych urządzeń, które pasują do deviceDescriptors.ts
do wykonywania zrzutów ekranu komponentów
[!NOTE]
- Jeśli brakuje Ci konfiguracji urządzenia, możesz śmiało przesłać Feature request
- To będzie działać tylko z Chrome:
- jeśli podasz
--devices
, wszystkie instancje Chrome będą działać w trybie emulacji mobilnej
- jeśli podasz również inne przeglądarki niż Chrome, np.
--devices --browsers=firefox,safari,edge
, automatycznie doda Chrome w trybie emulacji mobilnej
- Runner Storybook domyślnie tworzy zrzuty ekranu elementów, jeśli chcesz zobaczyć pełny zrzut ekranu emulacji mobilnej, podaj
--clip=false
w wierszu poleceń
- Nazwa pliku będzie np.
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- ŹRÓDŁO: Testowanie strony mobilnej na komputerze za pomocą emulacji mobilnej może być przydatne, ale testerzy powinni pamiętać, że istnieje wiele subtelnych różnic, takich jak:
- całkowicie inny GPU, co może prowadzić do dużych zmian w wydajności;
- interfejs mobilny nie jest emulowany (w szczególności, ukrywanie paska adresu wpływa na wysokość strony);
- okienko wyboru (gdzie wybierasz jeden z kilku celów dotykowych) nie jest obsługiwane;
- wiele API sprzętowych (na przykład zdarzenie orientationchange) jest niedostępnych.
--headless
- Typ:
boolean
- Obowiązkowe: Nie
- Domyślnie:
true
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- UWAGA: Dostępne tylko przez CLI
Domyślnie uruchomi testy w trybie headless (jeśli przeglądarka go obsługuje) lub może być wyłączony
--numShards
- Typ:
number
- Obowiązkowe: Nie
- Domyślnie:
true
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
To będzie liczba równoległych instancji, które będą używane do uruchamiania historii. Będzie to ograniczone przez maxInstances
w pliku wdio.conf
.
[!IMPORTANT]
Przy uruchamianiu w trybie headless
nie zwiększaj liczby powyżej 20, aby zapobiec niestabilności z powodu ograniczeń zasobów
--skipStories
- Typ:
string|regex
- Obowiązkowe: Nie
- Domyślnie: null
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
Może to być:
- string (
example-button--secondary,example-button--small
)
- lub regex (
"/.*button.*/gm"
)
aby pominąć określone historie. Użyj id
historii, które można znaleźć w URL historii. Na przykład, id
w tym URL http://localhost:6006/?path=/story/example-page--logged-out
to example-page--logged-out
--url
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie:
http://127.0.0.1:6006
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
URL, na którym hostowana jest twoja instancja Storybook.
--version
- Typ:
number
- Obowiązkowe: Nie
- Domyślnie: 7
- Przykład:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
To jest wersja Storybooka, domyślnie 7
. Jest to potrzebne, aby wiedzieć, czy należy użyć selektora V6 clipSelector
.
Testy interakcji Storybook
Testy interakcji Storybook umożliwiają interakcję z komponentem poprzez tworzenie niestandardowych skryptów z komendami WDIO, aby ustawić komponent w określonym stanie. Na przykład, zobacz poniższy fragment kodu:
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`
);
});
});
Wykonywane są dwa testy na dwóch różnych komponentach. Każdy test najpierw ustawia stan, a następnie wykonuje zrzut ekranu. Zauważysz również, że wprowadzono nową niestandardową komendę, którą można znaleźć tutaj.
Powyższy plik specyfikacji można zapisać w folderze i dodać do wiersza poleceń za pomocą następującego polecenia:
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
Runner Storybook najpierw automatycznie przeskanuje twoją instancję Storybook, a następnie doda twoje testy do historii, które muszą zostać porównane. Jeśli nie chcesz, aby komponenty, których używasz do testów interakcji, były porównywane dwukrotnie, możesz dodać filtr, aby usunąć "domyślne" historie ze skanowania, podając filtr --skipStories
. Wyglądałoby to tak:
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
Nowa niestandardowa komenda
Nowa niestandardowa komenda o nazwie browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
zostanie dodana do obiektu browser/driver
, który automatycznie załaduje komponent i poczeka na jego zakończenie, więc nie musisz używać metody browser.url('url.com')
. Można jej używać w ten sposób
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`
);
});
});
Opcje to:
additionalSearchParams
- Typ:
URLSearchParams
- Obowiązkowe: Nie
- Domyślnie:
new URLSearchParams()
- Przykład:
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
Dodaje dodatkowe parametry wyszukiwania do URL Storybooka, w powyższym przykładzie URL będzie http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
Zobacz dokumentację URLSearchParams po więcej informacji.
clipSelector
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie:
#storybook-root > :first-child
dla Storybook V7 i #root > :first-child:not(script):not(style)
dla Storybook V6
- Przykład:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
Jest to selektor, który będzie używany:
- do wyboru elementu, którego zrzut ekranu ma być wykonany
- dla elementu, który ma być widoczny przed wykonaniem zrzutu ekranu
- Typ:
string
- Obowiązkowe: tak
- Przykład:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
Użyj id
historii, które można znaleźć w URL historii. Na przykład, id
w tym URL http://localhost:6006/?path=/story/example-page--logged-out
to example-page--logged-out
timeout
- Typ:
number
- Obowiązkowe: Nie
- Domyślnie: 1100 milisekund
- Przykład:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
Maksymalny czas oczekiwania na widoczność komponentu po załadowaniu na stronie
url
- Typ:
string
- Obowiązkowe: Nie
- Domyślnie:
http://127.0.0.1:6006
- Przykład:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
URL, na którym hostowana jest twoja instancja Storybook.