Storybook Runner befindet sich noch in der BETA-Phase, die Dokumentation wird später zu den WebdriverIO-Dokumentationsseiten verschoben.
Dieses Modul unterstützt jetzt Storybook mit einem neuen Visual Runner. Dieser Runner scannt automatisch nach einer lokalen/entfernten Storybook-Instanz und erstellt Element-Screenshots jeder Komponente. Dies kann erfolgen, indem Sie
export const config: WebdriverIO.Config = {
services: ["visual"],
};
zu Ihren services
hinzufügen und npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
über die Kommandozeile ausführen.
Es wird Chrome im Headless-Modus als Standardbrowser verwenden.
[!NOTE]
- Die meisten Visual Testing-Optionen funktionieren auch für den Storybook Runner, siehe die WebdriverIO-Dokumentation.
- Der Storybook Runner überschreibt alle Ihre Capabilities und kann nur auf den Browsern laufen, die er unterstützt, siehe
--browsers
.
- Der Storybook Runner unterstützt keine bestehende Konfiguration mit Multiremote-Capabilities und wirft einen Fehler aus.
- Der Storybook Runner unterstützt nur Desktop Web, nicht Mobile Web.
Storybook Runner Service-Optionen
Service-Optionen können wie folgt angegeben werden
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 CLI-Optionen
--additionalSearchParams
- Typ:
string
- Obligatorisch: Nein
- Standard: ''
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
Fügt zusätzliche Suchparameter zur Storybook-URL hinzu.
Siehe die URLSearchParams-Dokumentation für weitere Informationen. Der String muss ein gültiger URLSearchParams-String sein.
[!NOTE]
Die doppelten Anführungszeichen sind notwendig, um zu verhindern, dass das &
als Befehlstrenner interpretiert wird.
Zum Beispiel wird mit --additionalSearchParams="foo=bar&abc=def"
die folgende Storybook-URL für Stories-Tests generiert: http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- Typ:
string
- Obligatorisch: Nein
- Standard:
chrome
, Sie können aus chrome|firefox|edge|safari
wählen
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- HINWEIS: Nur über die CLI verfügbar
Es werden die angegebenen Browser verwendet, um Komponenten-Screenshots zu erstellen
[!NOTE]
Stellen Sie sicher, dass Sie die Browser, auf denen Sie ausführen möchten, auf Ihrem lokalen Computer installiert haben
--clip
- Typ:
boolean
- Obligatorisch: Nein
- Standard:
true
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
Wenn deaktiviert, wird ein Viewport-Screenshot erstellt. Wenn aktiviert, werden Element-Screenshots basierend auf dem --clipSelector
erstellt, wodurch der weiße Raum um den Komponenten-Screenshot herum reduziert und die Screenshot-Größe verringert wird.
--clipSelector
- Typ:
string
- Obligatorisch: Nein
- Standard:
#storybook-root > :first-child
für Storybook V7 und #root > :first-child:not(script):not(style)
für Storybook V6, siehe auch --version
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
Dies ist der Selektor, der verwendet wird:
- um das Element auszuwählen, von dem ein Screenshot gemacht werden soll
- für das Element, auf dessen Sichtbarkeit vor einem Screenshot gewartet werden soll
--devices
- Typ:
string
- Obligatorisch: Nein
- Standard: Sie können aus den
deviceDescriptors.ts
wählen
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- HINWEIS: Nur über die CLI verfügbar
Es werden die angegebenen Geräte verwendet, die mit deviceDescriptors.ts
übereinstimmen, um Komponenten-Screenshots zu erstellen
[!NOTE]
- Wenn Ihnen eine Gerätekonfiguration fehlt, können Sie gerne eine Feature-Anfrage einreichen
- Dies funktioniert nur mit Chrome:
- wenn Sie
--devices
angeben, laufen alle Chrome-Instanzen im Mobile Emulation-Modus
- wenn Sie auch andere Browser als Chrome angeben, wie
--devices --browsers=firefox,safari,edge
, wird Chrome im Mobile-Emulationsmodus automatisch hinzugefügt
- Der Storybook Runner erstellt standardmäßig Element-Snapshots. Wenn Sie den vollständigen Mobile-Emulierten Screenshot sehen möchten, geben Sie
--clip=false
über die Kommandozeile an
- Der Dateiname sieht beispielsweise so aus:
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- SRC: Das Testen einer mobilen Website auf einem Desktop mit mobiler Emulation kann nützlich sein, aber Tester sollten sich bewusst sein, dass es viele subtile Unterschiede gibt, wie zum Beispiel:
- völlig unterschiedliche GPU, was zu großen Leistungsunterschieden führen kann;
- mobile UI wird nicht emuliert (insbesondere beeinflusst die versteckte URL-Leiste die Seitenhöhe);
- Disambiguitäts-Popup (wo Sie eines von mehreren Touch-Zielen auswählen) wird nicht unterstützt;
- viele Hardware-APIs (zum Beispiel das orientationchange-Ereignis) sind nicht verfügbar.
--headless
- Typ:
boolean
- Obligatorisch: Nein
- Standard:
true
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- HINWEIS: Nur über die CLI verfügbar
Die Tests werden standardmäßig im Headless-Modus ausgeführt (wenn der Browser dies unterstützt) oder können deaktiviert werden
--numShards
- Typ:
number
- Obligatorisch: Nein
- Standard:
true
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
Dies ist die Anzahl der parallelen Instanzen, die zum Ausführen der Stories verwendet werden. Dies wird durch maxInstances
in Ihrer wdio.conf
-Datei begrenzt.
[!IMPORTANT]
Wenn Sie im headless
-Modus ausführen, erhöhen Sie die Anzahl nicht auf mehr als 20, um Unbeständigkeit aufgrund von Ressourcenbeschränkungen zu vermeiden
--skipStories
- Typ:
string|regex
- Obligatorisch: Nein
- Standard: null
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
Dies kann sein:
- ein String (
example-button--secondary,example-button--small
)
- oder ein Regex (
"/.*button.*/gm"
)
um bestimmte Stories zu überspringen. Verwenden Sie die id
der Story, die in der URL der Story zu finden ist. Zum Beispiel ist die id
in dieser URL http://localhost:6006/?path=/story/example-page--logged-out
example-page--logged-out
--url
- Typ:
string
- Obligatorisch: Nein
- Standard:
http://127.0.0.1:6006
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
Die URL, unter der Ihre Storybook-Instanz gehostet wird.
--version
- Typ:
number
- Obligatorisch: Nein
- Standard: 7
- Beispiel:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
Dies ist die Version von Storybook, standardmäßig 7
. Dies ist notwendig, um zu wissen, ob der V6 clipSelector
verwendet werden muss.
Storybook Interaktionstesting
Storybook Interaktionstesting ermöglicht es Ihnen, mit Ihrer Komponente zu interagieren, indem Sie benutzerdefinierte Skripte mit WDIO-Befehlen erstellen, um eine Komponente in einen bestimmten Zustand zu versetzen. Hier ist ein Beispiel-Codeausschnitt:
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`
);
});
});
Es werden zwei Tests an zwei verschiedenen Komponenten durchgeführt. Jeder Test setzt zuerst einen Zustand und macht dann einen Screenshot. Sie werden auch bemerken, dass ein neuer benutzerdefinierter Befehl eingeführt wurde, der hier zu finden ist.
Die obige Spezifikationsdatei kann in einem Ordner gespeichert und mit dem folgenden Befehl zur Kommandozeile hinzugefügt werden:
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
Der Storybook Runner wird zuerst automatisch Ihre Storybook-Instanz scannen und dann Ihre Tests zu den Stories hinzufügen, die verglichen werden müssen. Wenn Sie nicht möchten, dass die Komponenten, die Sie für Interaktionstests verwenden, zweimal verglichen werden, können Sie einen Filter hinzufügen, um die "Standard"-Stories aus dem Scan zu entfernen, indem Sie den --skipStories
-Filter angeben. Dies würde wie folgt aussehen:
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
Neuer benutzerdefinierter Befehl
Ein neuer benutzerdefinierter Befehl namens browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
wird zum browser/driver
-Objekt hinzugefügt, der automatisch die Komponente lädt und wartet, bis sie fertig ist, so dass Sie die browser.url('url.com')
-Methode nicht verwenden müssen. Es kann wie folgt verwendet werden:
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`
);
});
});
Die Optionen sind:
additionalSearchParams
- Typ:
URLSearchParams
- Obligatorisch: Nein
- Standard:
new URLSearchParams()
- Beispiel:
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
Dies fügt der Storybook-URL zusätzliche Suchparameter hinzu. Im obigen Beispiel wird die URL http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
sein.
Siehe die URLSearchParams-Dokumentation für weitere Informationen.
clipSelector
- Typ:
string
- Obligatorisch: Nein
- Standard:
#storybook-root > :first-child
für Storybook V7 und #root > :first-child:not(script):not(style)
für Storybook V6
- Beispiel:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
Dies ist der Selektor, der verwendet wird:
- um das Element auszuwählen, von dem ein Screenshot gemacht werden soll
- für das Element, auf dessen Sichtbarkeit vor einem Screenshot gewartet werden soll
- Typ:
string
- Obligatorisch: ja
- Beispiel:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
Verwenden Sie die id
der Story, die in der URL der Story zu finden ist. Zum Beispiel ist die id
in dieser URL http://localhost:6006/?path=/story/example-page--logged-out
example-page--logged-out
timeout
- Typ:
number
- Obligatorisch: Nein
- Standard: 1100 Millisekunden
- Beispiel:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
Die maximale Wartezeit, die wir warten möchten, bis eine Komponente nach dem Laden auf der Seite sichtbar ist
url
- Typ:
string
- Obligatorisch: Nein
- Standard:
http://127.0.0.1:6006
- Beispiel:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
Die URL, unter der Ihre Storybook-Instanz gehostet wird.