经过多年的测试,我发现如果不是不可能的话,测试使用插槽的web组件非常困难。在解释这个问题之前,我想说的是,我不能改变生成的标记来改进它们本身。
<wc-1 attributes-etc="">
<wc-2 attributes-etc="">
<slot>
<wc-3 attributes-etc="">
<slot>
...eventually get to an input...
<input type="text" name="firstName" />有来自某种表单构建器的嵌套web组件的支持,也有大量使用的插槽。web组件有属性,但是插槽从来没有,所以我使用web组件名称进行查询。
document.querSelector('wc-1')
.shadowRoot.querySelector('wc-2')
.shadowRoot.querySelector('slot')
// Yields <slot>...</slot>到目前为止,这一切都很好,Cypress有我使用的.shadow()命令,但我只是在这里测试devtools,以查看该槽具有的所有属性。
document.querSelector('wc-1')
.shadowRoot.querySelector('wc-2')
.shadowRoot.querySelector('slot')
.shadowRoot
// Yields "null".
// I don't know how to get to the .lightDOM? of wc-2?我尝试的任何属性最终都是空的,或者返回值中有0个元素。使用其他前端工具和全局DOM,我总是可以在一个命令中使用cy.get('div[data-testid="the-nested-element-i-want"]').type('important words')。
所以我的主要问题是:一旦web组件开始堆积,人们如何测试这些东西?或者不要这样做,而只是在隔离/单元测试中测试web组件,因为它很难查询嵌套的影子王国?
主要目标是最终获得cy.get('input[name"firstName"]').type('John')的表单输入。在我的示例中,有人能给我一个链接好的docuement.querySelector()命令来访问<wc-3>吗?
发布于 2021-02-13 18:32:39
答案涉及assignedNodes():https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedNodes
-- HTMLSlotElement接口的assignedNodes()属性返回分配给这个时隙的节点序列.
对我来说,使用它和assignedElements()没有什么区别。所以,您所要做的就是在查询到所需的时隙后使用该方法。就我的例子而言,答案是:
const wc-3 = document.querySelector('wc-1').shadowRoot
.querySelector('wc-2').shadowRoot
.querySelector('slot').assignedNodes()
.map((el) => el.shadowRoot)[0]然后你可以继续往下走.我知道我只有一个没有名字的插槽,所以我从返回的.map()中得到了它。
为我指出正确方向的问答道具:Web components: How to work with children?
发布于 2021-02-12 16:18:53
您的<slot>中将没有DOM内容,因为没有DOM内容将移动到插槽。
lightDOM内容是在插槽中反映的,但是仍然是不可见的!在lightDOM中。
(这就是为什么你也是 slotted content )
从医生那里:
,.‘;;。
所以要测试某物是否是“在”a槽“中
slot=?属性,并再次检查<slot name=? >是否实际存在于shadowDOMF 221中
反之亦然
或者钩入slotchange事件,但这不是测试。
伪码:
反之亦然;可能包含错误。它的伪码..。
function processDOMnode( node ){
if (node.shadowRoot){
// query shadowDOM
let slotnames = [...node.shadowRoot.querySelectorAll("slot")].map(s=>s.name);
// query lightDOM
slotnames.forEach( name =>{
let content = node.querySelectorAll(`[slot="${name}"]`);
console.log( "slot:" , name , "content:" , content );
});
// maybe do something with slotnames in lightDOM that do NOT exist in shadowDOM
// dive deeper
this.shadowRooot.children.forEach(shadownode => processDOMnode(shadownode));
}
}https://stackoverflow.com/questions/66174625
复制相似问题