L'Exécuteur Storybook est encore en BETA, la documentation sera ultérieurement déplacée vers les pages de documentation WebdriverIO.
Ce module prend désormais en charge Storybook avec un nouvel Exécuteur Visuel. Cet exécuteur analyse automatiquement une instance locale/distante de Storybook et créera des captures d'écran d'éléments pour chaque composant. Cela peut être fait en ajoutant
export const config: WebdriverIO.Config = {
services: ["visual"],
};
à vos services
et en exécutant npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
via la ligne de commande.
Il utilisera Chrome en mode headless comme navigateur par défaut.
[!NOTE]
- La plupart des options de Test Visuel fonctionneront également pour l'Exécuteur Storybook, voir la documentation WebdriverIO.
- L'Exécuteur Storybook écrasera toutes vos capacités et ne peut s'exécuter que sur les navigateurs qu'il prend en charge, voir
--browsers
.
- L'Exécuteur Storybook ne prend pas en charge une configuration existante qui utilise des capacités Multiremote et générera une erreur.
- L'Exécuteur Storybook ne prend en charge que le Web Desktop, pas le Web Mobile.
Options de service de l'Exécuteur Storybook
Les options de service peuvent être fournies comme ceci
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}`,
},
},
],
],
}
Options CLI de l'Exécuteur Storybook
--additionalSearchParams
- Type:
string
- Obligatoire: Non
- Défaut: ''
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
Ajoutera des paramètres de recherche supplémentaires à l'URL Storybook.
Voir la documentation URLSearchParams pour plus d'informations. La chaîne doit être une chaîne URLSearchParams valide.
[!NOTE]
Les guillemets doubles sont nécessaires pour empêcher le &
d'être interprété comme un séparateur de commande.
Par exemple avec --additionalSearchParams="foo=bar&abc=def"
, cela générera l'URL Storybook suivante pour le test des histoires : http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- Type:
string
- Obligatoire: Non
- Défaut:
chrome
, vous pouvez sélectionner parmi chrome|firefox|edge|safari
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- REMARQUE: Disponible uniquement via la CLI
Il utilisera les navigateurs fournis pour prendre des captures d'écran des composants
[!NOTE]
Assurez-vous d'avoir installé les navigateurs sur lesquels vous souhaitez exécuter les tests sur votre machine locale
--clip
- Type:
boolean
- Obligatoire: Non
- Défaut:
true
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
Lorsqu'il est désactivé, il créera une capture d'écran de la vue complète. Lorsqu'il est activé, il créera des captures d'écran d'éléments basées sur le --clipSelector
qui réduira la quantité d'espace blanc autour de la capture d'écran du composant et réduira la taille de la capture d'écran.
--clipSelector
- Type:
string
- Obligatoire: Non
- Défaut:
#storybook-root > :first-child
pour Storybook V7 et #root > :first-child:not(script):not(style)
pour Storybook V6, voir aussi --version
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
C'est le sélecteur qui sera utilisé :
- pour sélectionner l'élément dont on prendra la capture d'écran
- pour l'élément à attendre qu'il soit visible avant qu'une capture d'écran ne soit prise
--devices
- Type:
string
- Obligatoire: Non
- Défaut: Vous pouvez sélectionner parmi
deviceDescriptors.ts
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- REMARQUE: Disponible uniquement via la CLI
Il utilisera les appareils fournis qui correspondent à deviceDescriptors.ts
pour prendre des captures d'écran des composants
[!NOTE]
- Si vous manquez une configuration d'appareil, n'hésitez pas à soumettre une demande de fonctionnalité
- Cela ne fonctionnera qu'avec Chrome :
- si vous fournissez
--devices
, toutes les instances Chrome s'exécuteront en mode Émulation Mobile
- si vous fournissez également d'autres navigateurs que Chrome, comme
--devices --browsers=firefox,safari,edge
, cela ajoutera automatiquement Chrome en mode d'émulation mobile
- L'Exécuteur Storybook créera par défaut des instantanés d'éléments, si vous souhaitez voir la capture d'écran complète de l'émulation mobile, fournissez
--clip=false
via la ligne de commande
- Le nom de fichier ressemblera par exemple à
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- SRC: Tester un site Web mobile sur un ordinateur de bureau à l'aide de l'émulation mobile peut être utile, mais les testeurs doivent être conscients qu'il existe de nombreuses différences subtiles telles que :
- un GPU complètement différent, ce qui peut entraîner d'importants changements de performance ;
- l'interface utilisateur mobile n'est pas émulée (en particulier, la barre d'URL masquée affecte la hauteur de la page) ;
- la boîte contextuelle de désambiguïsation (où vous sélectionnez l'une des cibles tactiles) n'est pas prise en charge ;
- de nombreuses API matérielles (par exemple, l'événement orientationchange) ne sont pas disponibles.
--headless
- Type:
boolean
- Obligatoire: Non
- Défaut:
true
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- REMARQUE: Disponible uniquement via la CLI
Cela exécutera les tests par défaut en mode headless (lorsque le navigateur le prend en charge) ou peut être désactivé
--numShards
- Type:
number
- Obligatoire: Non
- Défaut:
true
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
Il s'agit du nombre d'instances parallèles qui seront utilisées pour exécuter les histoires. Cela sera limité par le maxInstances
dans votre fichier wdio.conf
.
[!IMPORTANT]
Lors de l'exécution en mode headless
, n'augmentez pas le nombre à plus de 20 pour éviter l'instabilité due aux restrictions de ressources
--skipStories
- Type:
string|regex
- Obligatoire: Non
- Défaut: null
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
Cela peut être :
- une chaîne (
example-button--secondary,example-button--small
)
- ou une regex (
"/.*button.*/gm"
)
pour ignorer certaines histoires. Utilisez l'id
de l'histoire qui peut être trouvé dans l'URL de l'histoire. Par exemple, l'id
dans cette URL http://localhost:6006/?path=/story/example-page--logged-out
est example-page--logged-out
--url
- Type:
string
- Obligatoire: Non
- Défaut:
http://127.0.0.1:6006
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
L'URL où votre instance Storybook est hébergée.
--version
- Type:
number
- Obligatoire: Non
- Défaut: 7
- Exemple:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
Il s'agit de la version de Storybook, par défaut 7
. Cela est nécessaire pour savoir si le clipSelector
V6 doit être utilisé.
Tests d'interaction Storybook
Les tests d'interaction Storybook vous permettent d'interagir avec votre composant en créant des scripts personnalisés avec des commandes WDIO pour mettre un composant dans un certain état. Par exemple, voir l'extrait de code ci-dessous :
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`
);
});
});
Deux tests sur deux composants différents sont exécutés. Chaque test définit d'abord un état puis prend une capture d'écran. Vous remarquerez également qu'une nouvelle commande personnalisée a été introduite, qui se trouve ici.
Le fichier de spécification ci-dessus peut être enregistré dans un dossier et ajouté à la ligne de commande avec la commande suivante :
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
L'exécuteur Storybook analysera d'abord automatiquement votre instance Storybook, puis ajoutera vos tests aux histoires qui doivent être comparées. Si vous ne souhaitez pas que les composants que vous utilisez pour les tests d'interaction soient comparés deux fois, vous pouvez ajouter un filtre pour supprimer les histoires "par défaut" de l'analyse en fournissant le filtre --skipStories
. Cela ressemblerait à ceci :
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
Nouvelle commande personnalisée
Une nouvelle commande personnalisée appelée browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
sera ajoutée à l'objet browser/driver
qui chargera automatiquement le composant et attendra qu'il soit prêt, vous n'aurez donc pas besoin d'utiliser la méthode browser.url('url.com')
. Elle peut être utilisée comme ceci
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`
);
});
});
Les options sont :
additionalSearchParams
- Type:
URLSearchParams
- Obligatoire: Non
- Défaut:
new URLSearchParams()
- Exemple:
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
Cela ajoutera des paramètres de recherche supplémentaires à l'URL Storybook, dans l'exemple ci-dessus, l'URL sera http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
Voir la documentation URLSearchParams pour plus d'informations.
clipSelector
- Type:
string
- Obligatoire: Non
- Défaut:
#storybook-root > :first-child
pour Storybook V7 et #root > :first-child:not(script):not(style)
pour Storybook V6
- Exemple:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
C'est le sélecteur qui sera utilisé :
- pour sélectionner l'élément dont on prendra la capture d'écran
- pour l'élément à attendre qu'il soit visible avant qu'une capture d'écran ne soit prise
- Type:
string
- Obligatoire: oui
- Exemple:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
Utilisez l'id
de l'histoire qui peut être trouvé dans l'URL de l'histoire. Par exemple, l'id
dans cette URL http://localhost:6006/?path=/story/example-page--logged-out
est example-page--logged-out
timeout
- Type:
number
- Obligatoire: Non
- Défaut: 1100 millisecondes
- Exemple:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
Le délai maximum d'attente pour qu'un composant soit visible après le chargement sur la page
url
- Type:
string
- Obligatoire: Non
- Défaut:
http://127.0.0.1:6006
- Exemple:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
L'URL où votre instance Storybook est hébergée.