所以,我使用emotion-js
已有一段时间了,我喜欢它!但是我真的很讨厌e2e测试。所有选择器的外观如下:div > div > div > p
,因为emotion
注入的类名是随机生成的字符串。
因此,我想到了将data-
属性与DisplayName
注入到每个元素中,以便能够以更干净的方式测试它们:[data-test-id*="DateButton"]
或类似的东西。所以我写了这个简单的包装:
https://gist.github.com/sergeyvlakh/3072a4e2e27456bda853a1e1a213a568
我这样使用它:
import Injector from './injector';
export default props =>
(
<Injector>
<MyReactTree />
</Injector>
)
这里的问题是我不是“动态”注入数据属性。我想像recompose
中的任何HoC一样使用它:
export default Injector(App)
或者甚至具有动态道具名称,例如:export default Injector('data-test-id')(App)
。
但是... Injector
的孩子在这种情况下将是不确定的,所以我不知道如何进行:)
更新: 多亏了remix23,我才这样:https://gist.github.com/sergeyvlakh/f99310cdef018c06451333a36e764372
但是我强烈建议使用他的代码。
答案 0 :(得分:2)
您可以通过访问每个子元素等等来递归地跟踪儿童。
也许更昂贵但更直接的方法也应该起作用:
function Injector(Target) {
class InjectedTarget extends Component {
render() {
const { chilren, ...rest } = this.props;
return (
<Target
data-test-id={Target.DisplayName}
{...rest}
>
{React.Children.map(children, (child) => {
const isComponent =
child &&
child.type &&
typeof child.type !== 'string' &&
Object.prototype.isPrototypeOf.apply(
React.Component.prototype,
[child.type.prototype]
);
if (!isComponent) {
return child;
}
return React.createElement(Injector(child.type), { ...child.props, 'data-test-id': Target.DisplayName });
})}
</Target>
);
}
}
return InjectedTarget;
}
我认为这将是性能上的明智选择,但这是为了进行测试?