BackstopJS - 为所有场景设置通用选择器

AJC*_*C24 1 backstop.js

我正在使用 BackstopJS 在一些 React 组件上运行一些视觉回归测试。我将所有组件都显示在“通用”包装器内的各个 Storybook 页面上。

例如,Storybook 中的每个故事都设置为显示以下内容:

<div key="my_unique_key" id="component_preview">
  <MyReactComponentHere />
</div>
Run Code Online (Sandbox Code Playgroud)

由于我的所有组件都显示在带有 ID 的公共容器内的单独页面上component_preview,我想在 BackstopJS 中为所有测试套件设置一个选择器,以便这是每个测试(即这是为了避免捕获与每个页面上的组件一起显示的任何降价或道具表)。

我知道我可以在每个场景中单独设置如下:

scenarios: [
  {
    ...
    selectors: [
      'div[id="component_preview"]'
    ],
    ...
  }
],
Run Code Online (Sandbox Code Playgroud)

但是鉴于我可能有大量场景(这是一个不断增长的项目,所以我不知道将来要单独捕获多少个组件),我希望能够将其设置为所有场景的一般规则,不必为每个单独的场景单独设置。

我试过selectorsscenarios配置之外设置一个数组,但没有任何效果。

是否可以为所有场景设置一个这样的通用选择器,而不必在每个场景中单独设置它?

如果我必须在每个场景中单独设置这没什么大不了的(只是意味着更多的工作/相同配置的重复),但如果可能的话,我想避免这样做。

AJC*_*C24 5

好的,所以我一直在为此做一些工作,并提出了这个解决方案,它适用于我想要的东西,而无需设置一个通用选择器来捕获每个场景。

最初的目标是单独捕获我的 React 组件,显示在 Storybook 上(即没有降价或道具表妨碍)。

仅供大家参考,这些是我正在使用的相关依赖项和版本(从我的项目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"
Run Code Online (Sandbox Code Playgroud)

进一步说明,我正在使用puppeteerwith backstopjs

我必须解决的第一个问题是 Storybook<iframe>在每个页面的内部元素中显示您的组件、降价和道具表。这导致了一个问题,backstopjs因为 CSS 范围没有内部document内部的概念<iframe>。如果我的组件比直接 UI 中可见的要大,那么它就不会意识到内部document比外部长。除此之外,我无法在该内部设置任何hideSelectorsremoveSelectors任何组件,<iframe>因为它超出了范围。

因此,有助于<iframe>在其自己的页面上隔离内部的第一个主要发现是iframe.html按如下方式添加到 URL(例如 - 假设您localhost在默认端口上运行 Storybook ):

http://localhost:6006/iframe.html?selectedKind=...
Run Code Online (Sandbox Code Playgroud)

这会将之前内部的<iframe>内容隔离在其自己的页面上,而不会出现左侧菜单面板。所以,从这里开始,我现在可以按照自己的意愿隐藏和删除选择器,因为现在一切都在范围内。页面上显示的 Storybook markdown 和 prop-tables 方便地位于单个<div>元素内。我用来指向这个<div>元素的唯一 CSS 选择器如下:

div[id="root"] > div > div > div[style*="font-family: -apple-system"]
Run Code Online (Sandbox Code Playgroud)

所以我决定做的不是设置一个通用选择器来捕获每个场景,而是onReadyScript在我的backstop.json配置文件中调用一个通用的,如下所示:

{
  "id": "suite_name",
  "viewports": [
    ...
  ],
  "onReadyScript": "my-on-ready-script.js",
  "scenarios": [
    ...
  ],
  ...
}
Run Code Online (Sandbox Code Playgroud)

然后,我的脚本被设置为删除 markdown 和 prop-tables<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();
    });
};
Run Code Online (Sandbox Code Playgroud)

这使我的组件在每个页面上完全独立地显示backstopjs,然后,可以单独捕获该组件。

这是我能够找到的最佳解决方案来实现我的目标。我也把它作为其他人的潜在解决方案。希望这里面有一些东西可以帮助其他人做我想做的事情!