nodejs: 24.7
jsdom: 26.1.0
Basically, I want to create a selector, that would exclude nested elements - it should find only elements at the first level of nesting. I have this:
it('Test selector non-nested', () => {
const mainAttribute = 'data-main';
const itemAttribute = 'data-item';
const sideAttribute = 'data-side';
document.body.innerHTML = `
<div>
<div ${mainAttribute}>
<div ${itemAttribute}>
<div ${sideAttribute}>
<div ${mainAttribute}>
<div ${itemAttribute}>
<div ${sideAttribute}></div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
const result = [];
const foundElements = document.querySelectorAll(`[${mainAttribute}]`);
for (const element of foundElements) {
result.push(element);
}
for (const element of result) {
const selector = `:scope [${sideAttribute}]:not(:scope [${itemAttribute}] [${itemAttribute}] [${sideAttribute}])`;
element.innerHTML = element.innerHTML; // It makes it work!
const results = element.querySelectorAll(selector);
expect(results.length).toEqual(1);
}
});
As you can see, I want to find elements having sideAttribute, but only in the top element having the itemAttribute. It means that in this case I want to have 1 result for both iterations of the loop.
It doesn't work UNLESS I will throw element.innerHTML = element.innerHTML; in there, then it magically starts working. What's going on here?
The problem happens in jsdom, but not in a browser. I created an issue ticket here: https://github.com/jsdom/jsdom/issues/3924 but maybe someone will find a workaround for that.
querySelector()instead ofquerySelectorAll()?querySelector()I would just get null the second time.element.innerHTML = element.innerHTML;, I getresults.length = 1.