BackstopJS - Установить общий селектор для всех сценариев

Я использую BackstopJS для запуска некоторых визуальных регрессионных тестов на некоторых компонентах React. Все мои компоненты отображаются на отдельных страницах сборника рассказов в "обычной" оболочке.

Например, каждая история в сборнике рассказов настроена для отображения следующего:

<div key="my_unique_key" id="component_preview">
  <MyReactComponentHere />
</div>

Поскольку все мои компоненты отображаются на отдельных страницах изолированно внутри этого общего контейнера с идентификатором component_preview Я хотел бы установить селектор в BackstopJS для всех наборов тестов, так как это является фокусом захвата экрана для каждого теста (т. Е. Так, чтобы я не захватывал любые таблицы уценки или проп, отображаемые с компонентом на каждой странице).).

Я знаю, что могу индивидуально установить это в каждом сценарии следующим образом:

scenarios: [
  {
    ...
    selectors: [
      'div[id="component_preview"]'
    ],
    ...
  }
],

Но, учитывая, что у меня может быть большое количество сценариев (это постоянно растущий проект, поэтому я понятия не имею, сколько компонентов я хочу захватить изолированно в будущем), я бы хотел установить это как общее правило для всех сценариев, и не нужно индивидуально устанавливать его для каждого отдельного сценария.

Я пытался установить selectors массив за пределами scenarios конфигурация, но это не имело никакого эффекта.

Можно ли установить общий селектор, подобный этому, для всех сценариев, не устанавливая его отдельно для каждого сценария?

Нет ничего страшного, если мне придется устанавливать это индивидуально для каждого сценария (просто означает больше работы / дублирования одной и той же конфигурации), но я бы хотел избежать этого, если это возможно.

1 ответ

Решение

Хорошо, так что я проделал некоторую работу над этим и придумал это решение, которое работает для того, что я хочу, без необходимости устанавливать общий селектор для захвата в каждом отдельном сценарии.

Первоначальная цель состояла в том, чтобы захватить компоненты React, отображаемые в сборнике рассказов, изолированно (т. Е. Без мешков уценки или таблиц пропов).

Только для справки, это соответствующие зависимости и версии, которые я использую (скопированы и вставлены из моих проектов package.json файл):

"@storybook/addon-actions": "^3.4.8",
"@storybook/addon-info": "^3.4.8",
"@storybook/addon-links": "^3.4.8",
"@storybook/addon-options": "^3.4.8",
"@storybook/addons": "^3.4.8",
"@storybook/react": "^3.4.8",
"backstopjs": "^3.2.19",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-dom": "^16.4.1"

В качестве дальнейшего примечания я использую puppeteer с backstopjs,

Первой проблемой, которую мне пришлось обойти, был тот факт, что Storybook отображает ваш компонент, уценку и таблицы проповеди внутри <iframe> элемент на каждой странице. Это вызвало проблему с backstopjs так как область видимости CSS не имела понятия внутреннего document внутри этого внутреннего <iframe>, Если бы мой компонент был больше, чем тот, который был виден в непосредственном пользовательском интерфейсе, он бы не понял, что внутренний document был длиннее, чем внешний. Кроме того, я не смог установить hideSelectors или же removeSelectors для любых компонентов внутри этого внутреннего <iframe> так как это было вне области.

Итак, первое крупное открытие, которое помогло изолировать этот внутренний <iframe> на своей странице было добавить iframe.html на URL-адрес следующим образом (например, предположим, что на вашем компьютере работает Storybook localhost на порту по умолчанию):

http://localhost:6006/iframe.html?selectedKind=...

Это изолирует, что ранее внутренний <iframe> на своей собственной странице без появления левой панели меню. Таким образом, теперь я мог скрывать и удалять селекторы так, как хотел, поскольку теперь все было в поле зрения. Уценка Storybook и таблицы пропов, которые отображаются на странице, удобно заключены в одну <div> элемент. Уникальный селектор CSS, который я использовал, чтобы указать на это <div> Элемент выглядит следующим образом:

div[id="root"] > div > div > div[style*="font-family: -apple-system"]

Так что вместо того, чтобы устанавливать общий селектор для каждого сценария, я решил вызвать общий onReadyScript в моем backstop.json Файл конфигурации выглядит следующим образом:

{
  "id": "suite_name",
  "viewports": [
    ...
  ],
  "onReadyScript": "my-on-ready-script.js",
  "scenarios": [
    ...
  ],
  ...
}

Мой скрипт был настроен на удаление уценки и проп-таблиц. <div> элемент следующим образом:

module.exports = async function (puppeteer) {
  /* Remove the markdown and prop tables from the Storybook preview panel */
  await puppeteer
    .$eval('div[id="root"] > div > div > div[style*="font-family: -apple-system"]', (markdownAndPropTables) => {
      markdownAndPropTables.parentNode.remove();
    });
};

Это оставляет мой компонент полностью изолированным на каждой странице и backstopjsзатем можно захватить этот компонент самостоятельно.

Это лучшее решение, которое мне удалось найти для достижения моих целей с этим. Я представляю это как потенциальное решение для всех остальных. Надеюсь, в этом есть что-то, что поможет кому-то еще делать то же, что я хотел!

Другие вопросы по тегам