Storybook Runner ainda está em BETA, a documentação será posteriormente movida para as páginas de documentação do WebdriverIO.
Este módulo agora suporta Storybook com um novo Visual Runner. Este executor verifica automaticamente uma instância local/remota do storybook e criará capturas de tela de elementos de cada componente. Isso pode ser feito adicionando
export const config: WebdriverIO.Config = {
services: ["visual"],
};
aos seus services
e executando npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
através da linha de comando.
Ele usará o Chrome no modo headless como navegador padrão.
[!NOTE]
- A maioria das opções de Teste Visual também funcionará para o Storybook Runner, consulte a documentação do WebdriverIO.
- O Storybook Runner substituirá todas as suas capacidades e só pode ser executado nos navegadores que ele suporta, veja
--browsers
.
- O Storybook Runner não suporta uma configuração existente que usa capacidades Multiremote e lançará um erro.
- O Storybook Runner suporta apenas Desktop Web, não Mobile Web.
Opções de Serviço do Storybook Runner
As opções de serviço podem ser fornecidas assim
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}`,
},
},
],
],
}
Opções de CLI do Storybook Runner
--additionalSearchParams
- Tipo:
string
- Obrigatório: Não
- Padrão: ''
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
Adicionará parâmetros de pesquisa adicionais à URL do Storybook.
Consulte a documentação URLSearchParams para mais informações. A string deve ser uma string URLSearchParams válida.
[!NOTE]
As aspas duplas são necessárias para evitar que o &
seja interpretado como um separador de comando.
Por exemplo, com --additionalSearchParams="foo=bar&abc=def"
gerará a seguinte URL do Storybook para testes de histórias: http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- Tipo:
string
- Obrigatório: Não
- Padrão:
chrome
, você pode selecionar entre chrome|firefox|edge|safari
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- NOTA: Disponível apenas através da CLI
Usará os navegadores fornecidos para tirar capturas de tela dos componentes
[!NOTE]
Certifique-se de ter os navegadores que deseja executar instalados em sua máquina local
--clip
- Tipo:
boolean
- Obrigatório: Não
- Padrão:
true
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
Quando desativado, criará uma captura de tela da viewport. Quando ativado, criará capturas de tela de elementos com base no --clipSelector
, o que reduzirá a quantidade de espaço em branco ao redor da captura de tela do componente e reduzirá o tamanho da captura de tela.
--clipSelector
- Tipo:
string
- Obrigatório: Não
- Padrão:
#storybook-root > :first-child
para Storybook V7 e #root > :first-child:not(script):not(style)
para Storybook V6, veja também --version
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
Este é o seletor que será usado:
- para selecionar o elemento para tirar a captura de tela
- para o elemento esperar ficar visível antes de uma captura de tela ser tirada
--devices
- Tipo:
string
- Obrigatório: Não
- Padrão: Você pode selecionar a partir de
deviceDescriptors.ts
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- NOTA: Disponível apenas através da CLI
Ele usará os dispositivos fornecidos que correspondem ao deviceDescriptors.ts
para tirar capturas de tela dos componentes
[!NOTE]
- Se você sentir falta de uma configuração de dispositivo, sinta-se à vontade para enviar uma Solicitação de recurso
- Isso só funcionará com Chrome:
- se você fornecer
--devices
, todas as instâncias do Chrome serão executadas no modo de Emulação Móvel
- se você também fornecer outros navegadores além do Chrome, como
--devices --browsers=firefox,safari,edge
, ele adicionará automaticamente Chrome no modo de emulação móvel
- O Storybook Runner criará por padrão capturas de elementos; se você quiser ver a captura de tela completa da Emulação Móvel, forneça
--clip=false
pela linha de comando
- O nome do arquivo ficará, por exemplo, como
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- SRC: Testar um site móvel em um desktop usando emulação móvel pode ser útil, mas os testadores devem estar cientes de que existem muitas diferenças sutis, como:
- GPU totalmente diferente, o que pode levar a grandes mudanças de desempenho;
- a interface do usuário móvel não é emulada (em particular, a barra de URL oculta afeta a altura da página);
- o popup de desambiguação (onde você seleciona um dos poucos alvos de toque) não é suportado;
- muitas APIs de hardware (por exemplo, evento orientationchange) não estão disponíveis.
--headless
- Tipo:
boolean
- Obrigatório: Não
- Padrão:
true
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- NOTA: Disponível apenas através da CLI
Isso executará os testes por padrão no modo headless (quando o navegador o suportar) ou pode ser desativado
--numShards
- Tipo:
number
- Obrigatório: Não
- Padrão:
true
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
Este será o número de instâncias paralelas que serão usadas para executar as histórias. Isso será limitado pelo maxInstances
no seu arquivo wdio.conf
.
[!IMPORTANT]
Ao executar no modo headless
, não aumente o número para mais de 20 para evitar instabilidade devido a restrições de recursos
--skipStories
- Tipo:
string|regex
- Obrigatório: Não
- Padrão: null
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
Isso pode ser:
- uma string (
example-button--secondary,example-button--small
)
- ou uma regex (
"/.*button.*/gm"
)
para pular certas histórias. Use o id
da história que pode ser encontrado na URL da história. Por exemplo, o id
nesta URL http://localhost:6006/?path=/story/example-page--logged-out
é example-page--logged-out
--url
- Tipo:
string
- Obrigatório: Não
- Padrão:
http://127.0.0.1:6006
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
A URL onde sua instância do Storybook está hospedada.
--version
- Tipo:
number
- Obrigatório: Não
- Padrão: 7
- Exemplo:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
Esta é a versão do Storybook, o padrão é 7
. Isso é necessário para saber se o clipSelector
V6 precisa ser usado.
Testes de Interação do Storybook
Os Testes de Interação do Storybook permitem que você interaja com seu componente criando scripts personalizados com comandos WDIO para colocar um componente em um determinado estado. Por exemplo, veja o trecho de código abaixo:
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`
);
});
});
Dois testes em dois componentes diferentes são executados. Cada teste primeiro define um estado e depois tira uma captura de tela. Você também notará que um novo comando personalizado foi introduzido, que pode ser encontrado aqui.
O arquivo de especificação acima pode ser salvo em uma pasta e adicionado à linha de comando com o seguinte comando:
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
O Storybook runner primeiro verificará automaticamente sua instância do Storybook e depois adicionará seus testes às histórias que precisam ser comparadas. Se você não quiser que os componentes que você usa para testes de interação sejam comparados duas vezes, você pode adicionar um filtro para remover as histórias "padrão" da verificação fornecendo o filtro --skipStories
. Isso ficaria assim:
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
Novo Comando Personalizado
Um novo comando personalizado chamado browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
será adicionado ao objeto browser/driver
que carregará automaticamente o componente e esperará que ele seja concluído, para que você não precise usar o método browser.url('url.com')
. Pode ser usado assim
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`
);
});
});
As opções são:
additionalSearchParams
- Tipo:
URLSearchParams
- Obrigatório: Não
- Padrão:
new URLSearchParams()
- Exemplo:
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
Isso adicionará parâmetros de pesquisa adicionais à URL do Storybook, no exemplo acima a URL será http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
Consulte a documentação URLSearchParams para mais informações.
clipSelector
- Tipo:
string
- Obrigatório: Não
- Padrão:
#storybook-root > :first-child
para Storybook V7 e #root > :first-child:not(script):not(style)
para Storybook V6
- Exemplo:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
Este é o seletor que será usado:
- para selecionar o elemento para tirar a captura de tela
- para o elemento esperar ficar visível antes de uma captura de tela ser tirada
- Tipo:
string
- Obrigatório: sim
- Exemplo:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
Use o id
da história que pode ser encontrado na URL da história. Por exemplo, o id
nesta URL http://localhost:6006/?path=/story/example-page--logged-out
é example-page--logged-out
timeout
- Tipo:
number
- Obrigatório: Não
- Padrão: 1100 milissegundos
- Exemplo:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
O tempo máximo que queremos esperar para que um componente fique visível após o carregamento na página
url
- Tipo:
string
- Obrigatório: Não
- Padrão:
http://127.0.0.1:6006
- Exemplo:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
A URL onde sua instância do Storybook está hospedada.