happy-dom
happy-dom copied to clipboard
querySelectorAll shoud respect document order
When using multiple selectors seprated by coma with querySelectorAll, the returned elements should be in document order as per the specifications.
For example, with the following HTML:
<h1>1.0</h1>
<h2>1.1</h2>
<h2>1.2</h2>
<h1>2.0</h1>
<h2>2.1</h2>
<h2>2.2</h2>
If I call document.querySelectorAll("h1,h2") happy-dom returns [1.0, 2.0, 1.1, 1.2, 2.1, 2.2] instead of the expected [1.0, 1.1, 1.2, 2.0, 2.1, 2.2]
Hi @olace! :slightly_smiling_face:
Sorry for taking such long time answering this. I will look into fixing this as soon as possible.
I'm trying to use happy-dom
with @testing-library/user-event
, but ran into an issue with simulated tab
key presses not focusing the next tabbable element. I thought I could work around it by querying for all of the tabbable elements and using that result to figure out which element to focus next, but then I ran into this issue with the results of querySelectorAll
being out of order. In my case it grouped all of the button
results before the input
results.
Hi @olace and @kevinbarabash! :slightly_smiling_face:
This has finally been fixed.
You can read more about the release here: https://github.com/capricorn86/happy-dom/releases/tag/v9.10.0
This still seems to be occurring using happy-dom 9.19.2, for example in Substack posts. When I run:
const { Window } = require("happy-dom");
async function main() {
const url =
"https://magneticgrowth.substack.com/p/api-renaissance-the-dawn-of-api-unicorns";
const response = await fetch(url);
const html = await response.text();
const window = new Window({
url,
settings: {
disableCSSFileLoading: true,
disableIframePageLoading: true,
disableJavaScriptEvaluation: true,
disableJavaScriptFileLoading: true,
},
});
window.document.write(html);
const lines = window.document
.querySelector("article")
.querySelectorAll("h1, h2, h3, h4, h5, h6, p, blockquote, li")
.map((element) => element.textContent);
console.log(
lines
.map((line, index) => `${index + 1}: ` + line.trim().substring(0, 50))
.join("\n")
);
}
main();
I get (compare the sixth and below lines output by happy-dom here, with what the browser outputs further below):
1: API Renaissance: The Dawn of API Unicorns Supporti
2: API Renaissance: The Dawn of API Unicorns Supporti
3: Reimagining the Software World for an AI-driven Fu
4: API Renaissance: The Dawn of API Unicorns Supporti
5: What if I told you the next wave of billion-dollar
6: APIs are how the brains (server-side logic layer)
7: [And this next part is probably interesting for ev
8: In the future, somebody’s AI will draft a tweet ba
9: A Bank Without a Website
10: Imagine a bank with no tellers, no ATMs — but also
11: Is it crazy? Maybe. But we’ve gone from accepting
12: Want more thought pieces in your inbox? I publish
13: Let’s keep going:
14: An insurance company just needs to offer a conveni
15: An insurance company just needs to offer a conveni
16: A real estate brokerage must simply offer a conven
17: A real estate brokerage must simply offer a conven
18: A grocery store just needs to let your AI run thro
19: A grocery store just needs to let your AI run thro
20: A restaurant delivery company just has to let your
21: A restaurant delivery company just has to let your
22: A doctor’s office can expose its scheduling softwa
23: A doctor’s office can expose its scheduling softwa
24: A fashion ecomm website can let AI efficiently sco
25: A fashion ecomm website can let AI efficiently sco
26: You get the point.
27: Current Apps Are Optimized Around Humans
28: If you have a company today, then now is the time
29: The Picks and Shovels of this New World
30: If we can agree that APIs are about to have their
31: API generation: every company will need an API lay
32: API generation: every company will need an API lay
33: API documentation: alongside the APIs, we will nee
34: API documentation: alongside the APIs, we will nee
35: AI Accountability: with AI’s speaking to AI’s, the
36: AI Accountability: with AI’s speaking to AI’s, the
37: API authentication: currently, the user must sign
38: API authentication: currently, the user must sign
39: API pay walling: how does a company charge for a s
40: API pay walling: how does a company charge for a s
41: API revenue generation: imagine you have an app th
42: API revenue generation: imagine you have an app th
43: API marketplace or exchange: how will we standardi
44: API marketplace or exchange: how will we standardi
45: Each of these opportunities will breed at least on
46: ChatGPT’s plugins are likely the first incarnation
47: Whoever emerges as the winner, I think we can expe
48: Do you want to build in this space?
49: Great. Let’s talk.
50: I’m actively investing in ventures that explore th
51: A company’s website or mobile app has been meticul
52: Whether I fund your venture, we build something to
53: Know someone who could get inspired by this conten
54: Share
55:
56: Thanks to Paige, Tal, and my brilliant engineer da
57:
58: Our most remarkable new AI tech meticulously scour
59: And yet, this will soon be outdated and unnecessar
60: Let’s Imagine a World Optimized Around AI
61: Let’s imagine a world where apps are rebooted from
62: We are about to have an API renaissance.
63: [API sidebar for non-engineers:]
64: API Renaissance: The Dawn of API Unicorns Supporti
However, when I run it in the browser:
console.log([...document.querySelector("article").querySelectorAll("h1, h2, h3, h4, h5, h6, p, blockquote, li")].map((el, index) => `${index + 1}: ` + el.textContent.trim().substring(0, 50)).join('\n'))
I get the following output:
1: API Renaissance: The Dawn of API Unicorns Supporti
2: API Renaissance: The Dawn of API Unicorns Supporti
3: Reimagining the Software World for an AI-driven Fu
4: API Renaissance: The Dawn of API Unicorns Supporti
5: What if I told you the next wave of billion-dollar
6: Current Apps Are Optimized Around Humans
7: A company’s website or mobile app has been meticul
8: Our most remarkable new AI tech meticulously scour
9: And yet, this will soon be outdated and unnecessar
10: Let’s Imagine a World Optimized Around AI
11: Let’s imagine a world where apps are rebooted from
12: We are about to have an API renaissance.
13: [API sidebar for non-engineers:]
14: APIs are how the brains (server-side logic layer)
15: [And this next part is probably interesting for ev
16: In the future, somebody’s AI will draft a tweet ba
17: A Bank Without a Website
18: Imagine a bank with no tellers, no ATMs — but also
19: Is it crazy? Maybe. But we’ve gone from accepting
20: Want more thought pieces in your inbox? I publish
21: Pledge your support
22: Let’s keep going:
23: An insurance company just needs to offer a conveni
24: An insurance company just needs to offer a conveni
25: A real estate brokerage must simply offer a conven
26: A real estate brokerage must simply offer a conven
27: A grocery store just needs to let your AI run thro
28: A grocery store just needs to let your AI run thro
29: A restaurant delivery company just has to let your
30: A restaurant delivery company just has to let your
31: A doctor’s office can expose its scheduling softwa
32: A doctor’s office can expose its scheduling softwa
33: A fashion ecomm website can let AI efficiently sco
34: A fashion ecomm website can let AI efficiently sco
35: You get the point.
36: If you have a company today, then now is the time
37: The Picks and Shovels of this New World
38: If we can agree that APIs are about to have their
39: API generation: every company will need an API lay
40: API generation: every company will need an API lay
41: API documentation: alongside the APIs, we will nee
42: API documentation: alongside the APIs, we will nee
43: AI Accountability: with AI’s speaking to AI’s, the
44: AI Accountability: with AI’s speaking to AI’s, the
45: API authentication: currently, the user must sign
46: API authentication: currently, the user must sign
47: API pay walling: how does a company charge for a s
48: API pay walling: how does a company charge for a s
49: API revenue generation: imagine you have an app th
50: API revenue generation: imagine you have an app th
51: API marketplace or exchange: how will we standardi
52: API marketplace or exchange: how will we standardi
53: Each of these opportunities will breed at least on
54: ChatGPT’s plugins are likely the first incarnation
55: Whoever emerges as the winner, I think we can expe
56: Do you want to build in this space?
57: Great. Let’s talk.
58: I’m actively investing in ventures that explore th
59: Whether I fund your venture, we build something to
60: Know someone who could get inspired by this conten
61: Share
62:
63: Thanks to Paige, Tal, and my brilliant engineer da
64:
65: Recommend Alex Furmansky - Magnetic Growth to the
66: Actionable learnings for leaders walking through a
67: Recommend Alex Furmansky - Magnetic Growth
68: Actionable learnings for leaders walking through a
69: By Alex Furmansky @ Magnetic · Launched 8 months
70: Why are you recommending Alex Furmansky - Magnetic
71: Recommendations are shown to readers after they su
72: API Renaissance: The Dawn of API Unicorns Supporti
For reference, jsdom outputs the correct result, so that's my workaround for now.
@ariofrio I think I have identified the problem you experienced now. The sorting mechanism was sorting incorrectly as it sorted by characters and numbers came in the wrong order (1, 10, 11, 2, 3, 4 etc.). The unit test did not cover this.
There is another fix in now.
You can read more about the new release here: https://github.com/capricorn86/happy-dom/releases/tag/v9.20.1
See #928