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

时间:2018-05-18 09:52:19

标签: backstop.js

我正在使用BackstopJS对某些React组件运行一些可视化回归测试。我将所有组件都显示在单个Storybook页面上的“常用”包装器中。

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

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

由于我的所有组件都在具有ID component_preview的公共容器中单独显示在单独的页面上,因此我想在BackstopJS中为所有测试套件设置一个选择器,以便因为这是每次测试的屏幕截图的焦点(即,这是因为我避免捕获与每页上的组件一起显示的任何markdown或prop表)。

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

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

但考虑到我可能有很多场景(这是一个不断发展的项目,所以我不知道将来要分别捕获多少组件),我希望能够将此设置为所有方案的一般规则,而不必为每个方案单独设置此项。

我尝试在selectors配置之外设置scenarios数组,但它没有任何效果。

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

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

1 个答案:

答案 0 :(得分:2)

好的,所以我一直在为此做一些工作,并提出了此解决方案,该解决方案可以满足我的需要,而无需设置一个公共选择器来捕获每个场景。

最初的目标是捕获我的React组件,这些组件独立显示在Storybook上(即,没有Markdown或prop表妨碍)。

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

作为进一步的说明,我将puppeteerbackstopjs一起使用。

我要解决的第一个问题是,故事书在每个页面的内部<iframe>元素内显示组件,markdown和prop-table。这导致backstopjs出现问题,因为CSS范围没有内部document内部的内部<iframe>的概念。如果我的组件大于直接用户界面中可见的组件,则不会意识到内部document比外部UI长。除此之外,我无法为内部hideSelectors内的任何组件设置任何removeSelectors<iframe>,因为它不在范围内。

因此,有助于在其自己的页面上隔离内部<iframe>的第一个主要发现是将iframe.html添加到URL,如下所示(例如-假设您在{{ 1}}(默认端口):

localhost

这会将先前内部的http://localhost:6006/iframe.html?selectedKind=... 隔离在自己的页面上,而不会出现左侧菜单面板。因此,由于现在所有内容都在范围内,因此我现在可以根据需要隐藏和删除选择器。方便地,页面上显示的Storybook降价和道具表位于单个<iframe>元素内。我用来指向此<div>元素的唯一CSS选择器如下:

<div>

因此,我决定要做的不是在每个方案中设置要捕获的公共选择器,而是按如下方式在我的div[id="root"] > div > div > div[style*="font-family: -apple-system"] 配置文件中调用公共onReadyScript

backstop.json

然后,我的脚本被设置为删除markdown和prop-tables { "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(); }); }; 上完全独立显示,然后可以单独捕获该组件。

这是我找到的最佳解决方案,可以实现我的目标。我也将其作为其他所有人的潜在解决方案。希望其中可以有一些东西可以帮助其他想要做我想做的事情的人!