Сервис сравнения изображений (визуальное регрессионное тестирование)
@wdio/visual-service - это сторонний пакет, для получения дополнительной информации, пожалуйста, посетите GitHub | npm
Для документации по визуальному тестированию с WebdriverIO, пожалуйста, обратитесь к документации. Этот проект содержит все необходимые модули для проведения визуальных тестов с WebdriverIO. В директории ./packages
вы найдёте:
@wdio/visual-testing
: сервис WebdriverIO для интеграции визуального тестированияwebdriver-image-comparison
: модуль сравнения изображений, который можно использовать для различных фреймворков автоматизации тестирования NodeJS, поддерживающих протокол WebDriver
Storybook Runner (БЕТА)
Нажмите, чтобы узнать больше о Storybook Runner БЕТА
Storybook Runner всё ещё находится в стадии БЕТА, документация позже будет перемещена на страницы документации WebdriverIO.
Этот модуль теперь поддерживает Storybook с новым визуальным раннером. Этот раннер автоматически сканирует локальный/удалённый экземпляр Storybook и создаёт снимки элементов каждого компонента. Это можно сделать, добавив
export const config: WebdriverIO.Config = {
// ...
services: ["visual"],
// ....
};
в ваши services
и запустив npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
через командную строку.
По умолчанию будет использоваться Chrome в режиме headless.
[!NOTE]
- Большинство опций в изуального тестирования также будут работать для Storybook Runner, см. документацию WebdriverIO.
- Storybook Runner перезапишет все ваши возможности и может запускаться только на поддерживаемых браузерах, см.
--browsers
.- Storybook Runner не поддерживает существующую конфигурацию, использующую возможности Multiremote, и выдаст ошибку.
- Storybook Runner поддерживает только веб-интерфейс для десктопа, а не для мобильных устройств.
Опции сервиса Storybook Runner
Опции сервиса можно предоставить следующим образом
export const config: WebdriverIO.Config = {
// ...
services: [
[
'visual',
{
// Некоторые опции по умолчанию
baselineFolder: join(process.cwd(), './__snapshots__/'),
debug: true,
// Опции storybook, см. описание опций CLI
storybook: {
additionalSearchParams: new URLSearchParams({foo: 'bar', abc: 'def'}),
clip: false,
clipSelector: ''#some-id,
numShards: 4,
// `skipStories` может быть строкой ('example-button--secondary'),
// массивом (['example-button--secondary', 'example-button--small'])
// или регулярным выражением, которое нужно предоставить в виде строки ("/.*button.*/gm")
skipStories: ['example-button--secondary', 'example-button--small'],
url: 'https://www.bbc.co.uk/iplayer/storybook/',
version: 6,
// Опционально - Позволяет переопределять путь к базовым изображениям. По умолчанию они группируются по категории и компоненту (например, forms/input/baseline.png)
getStoriesBaselinePath: (category, component) => `path__${category}__${component}`,
},
},
],
],
// ....
}
Опции CLI 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 будут работать в режиме мобильной эмуляции- если вы также предоставите другие браузеры, кроме 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
По умолчанию запускает тесты в режиме headless (когда браузер поддерживает его) или может быть отключено
--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/driver
будет добавлена новая пользовательская команда browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
, которая автоматически загрузит компонент и дождется его загрузки, поэтому вам не нужно использовать метод 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",
});
Это селектор, который будет использоваться:
- для выбора элемента, снимок которого нужно сделать
- для элемента, который должен быть видимым перед созданием снимка экрана
id
- Тип:
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.