BackstopJS - 为所有场景设置公共选择器
BackstopJS - Set common selector for all scenarios
我正在使用 BackstopJS 运行 对一些 React 组件进行视觉回归测试。我的所有组件都显示在 "common" 包装器内的各个 Storybook 页面上。
例如,Storybook 中的每个故事都设置为显示以下内容:
<div key="my_unique_key" id="component_preview">
<MyReactComponentHere />
</div>
由于我的所有组件都显示在 ID 为 component_preview
的公共容器内的单独页面上,因此我想在 BackstopJS 中为 all[=34] 设置一个选择器=] 测试套件,因为这是每个测试的屏幕截图的重点(即,这是因为我避免捕获每个页面上随组件显示的任何降价或道具表)。
我知道我可以在每个场景中单独设置它,如下所示:
scenarios: [
{
...
selectors: [
'div[id="component_preview"]'
],
...
}
],
但考虑到我可能有大量场景(这是一个不断发展的项目,所以我不知道将来我想单独捕获多少组件),我想可以将其设置为所有场景的一般规则,而不必为每个场景单独设置。
我尝试在 scenarios
配置之外设置一个 selectors
数组,但没有任何效果。
是否可以为所有场景设置一个像这样的通用选择器,而不必在每个场景上单独设置它?
如果我必须在每个场景中单独设置它没什么大不了的(只是意味着更多的工作/相同配置的重复)但我想尽可能避免这样做。
好的,所以我一直在做一些这方面的工作,并提出了这个解决方案,它可以满足我的需求,无需设置要在每个场景中捕获的通用选择器。
最初的目标是单独捕获我的 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"
进一步说明,我将 puppeteer
与 backstopjs
一起使用。
我必须解决的第一个问题是 Storybook 在每个页面的内部 <iframe>
元素内显示您的组件、降价和 prop-tables。这导致 backstopjs
出现问题,因为 CSS 作用域没有内部 <iframe>
内部 document
的概念。如果我的组件比直接 UI 中可见的大,那么它不会意识到内部 document
比外部长。除此之外,我无法为内部 <iframe>
内的任何组件设置任何 hideSelectors
或 removeSelectors
,因为它超出了范围。
因此,第一个有助于在其自己的页面上隔离内部 <iframe>
的重大发现是将 iframe.html
添加到 URL,如下所示(例如 - 假设您是运行 默认端口 localhost
上的 Storybook:
http://localhost:6006/iframe.html?selectedKind=...
这将以前内部的 <iframe>
隔离在其自己的页面上,而不会出现左侧菜单面板。因此,从这里开始,我现在可以根据需要隐藏和删除选择器,因为现在一切都在范围内。页面上显示的 Storybook markdown 和 prop-tables 很方便地位于单个 <div>
元素内。我用来指向这个 <div>
元素的唯一 CSS 选择器如下:
div[id="root"] > div > div > div[style*="font-family: -apple-system"]
所以我决定做的是在我的 backstop.json
配置文件中调用一个通用的 onReadyScript
,而不是设置一个通用的选择器来捕获每个场景,如下所示:
{
"id": "suite_name",
"viewports": [
...
],
"onReadyScript": "my-on-ready-script.js",
"scenarios": [
...
],
...
}
然后,我的脚本被设置为删除 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();
});
};
这让我的组件在每个页面上完全独立显示,backstopjs
,然后可以单独捕获该组件。
这是我找到的实现我的目标的最佳解决方案。我也把它作为其他人的潜在解决方案。希望其中有一些东西可以帮助其他人做我想做的同样的事情!
我正在使用 BackstopJS 运行 对一些 React 组件进行视觉回归测试。我的所有组件都显示在 "common" 包装器内的各个 Storybook 页面上。
例如,Storybook 中的每个故事都设置为显示以下内容:
<div key="my_unique_key" id="component_preview">
<MyReactComponentHere />
</div>
由于我的所有组件都显示在 ID 为 component_preview
的公共容器内的单独页面上,因此我想在 BackstopJS 中为 all[=34] 设置一个选择器=] 测试套件,因为这是每个测试的屏幕截图的重点(即,这是因为我避免捕获每个页面上随组件显示的任何降价或道具表)。
我知道我可以在每个场景中单独设置它,如下所示:
scenarios: [
{
...
selectors: [
'div[id="component_preview"]'
],
...
}
],
但考虑到我可能有大量场景(这是一个不断发展的项目,所以我不知道将来我想单独捕获多少组件),我想可以将其设置为所有场景的一般规则,而不必为每个场景单独设置。
我尝试在 scenarios
配置之外设置一个 selectors
数组,但没有任何效果。
是否可以为所有场景设置一个像这样的通用选择器,而不必在每个场景上单独设置它?
如果我必须在每个场景中单独设置它没什么大不了的(只是意味着更多的工作/相同配置的重复)但我想尽可能避免这样做。
好的,所以我一直在做一些这方面的工作,并提出了这个解决方案,它可以满足我的需求,无需设置要在每个场景中捕获的通用选择器。
最初的目标是单独捕获我的 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"
进一步说明,我将 puppeteer
与 backstopjs
一起使用。
我必须解决的第一个问题是 Storybook 在每个页面的内部 <iframe>
元素内显示您的组件、降价和 prop-tables。这导致 backstopjs
出现问题,因为 CSS 作用域没有内部 <iframe>
内部 document
的概念。如果我的组件比直接 UI 中可见的大,那么它不会意识到内部 document
比外部长。除此之外,我无法为内部 <iframe>
内的任何组件设置任何 hideSelectors
或 removeSelectors
,因为它超出了范围。
因此,第一个有助于在其自己的页面上隔离内部 <iframe>
的重大发现是将 iframe.html
添加到 URL,如下所示(例如 - 假设您是运行 默认端口 localhost
上的 Storybook:
http://localhost:6006/iframe.html?selectedKind=...
这将以前内部的 <iframe>
隔离在其自己的页面上,而不会出现左侧菜单面板。因此,从这里开始,我现在可以根据需要隐藏和删除选择器,因为现在一切都在范围内。页面上显示的 Storybook markdown 和 prop-tables 很方便地位于单个 <div>
元素内。我用来指向这个 <div>
元素的唯一 CSS 选择器如下:
div[id="root"] > div > div > div[style*="font-family: -apple-system"]
所以我决定做的是在我的 backstop.json
配置文件中调用一个通用的 onReadyScript
,而不是设置一个通用的选择器来捕获每个场景,如下所示:
{
"id": "suite_name",
"viewports": [
...
],
"onReadyScript": "my-on-ready-script.js",
"scenarios": [
...
],
...
}
然后,我的脚本被设置为删除 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();
});
};
这让我的组件在每个页面上完全独立显示,backstopjs
,然后可以单独捕获该组件。
这是我找到的实现我的目标的最佳解决方案。我也把它作为其他人的潜在解决方案。希望其中有一些东西可以帮助其他人做我想做的同样的事情!