diff --git a/Tests/LibWeb/Text/expected/DOM/Document-body-element-frameset-before-body.txt b/Tests/LibWeb/Text/expected/DOM/Document-body-element-frameset-before-body.txt
new file mode 100644
index 00000000000..6085c019466
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/DOM/Document-body-element-frameset-before-body.txt
@@ -0,0 +1,2 @@
+BODY == BODY
+FRAMESET == FRAMESET
diff --git a/Tests/LibWeb/Text/input/DOM/Document-body-element-frameset-before-body.html b/Tests/LibWeb/Text/input/DOM/Document-body-element-frameset-before-body.html
new file mode 100644
index 00000000000..7e478e999a8
--- /dev/null
+++ b/Tests/LibWeb/Text/input/DOM/Document-body-element-frameset-before-body.html
@@ -0,0 +1,17 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index 85df968491c..94d0c13752c 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -842,17 +842,18 @@ void Document::set_dir(String const& dir)
html->set_dir(dir);
}
+// https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2
HTML::HTMLElement* Document::body()
{
+ // The body element of a document is the first of the html element's children that is either
+ // a body element or a frameset element, or null if there is no such element.
auto* html = html_element();
if (!html)
return nullptr;
- auto* first_body = html->first_child_of_type();
- if (first_body)
- return first_body;
- auto* first_frameset = html->first_child_of_type();
- if (first_frameset)
- return first_frameset;
+ for (auto* child = html->first_child(); child; child = child->next_sibling()) {
+ if (is(*child) || is(*child))
+ return static_cast(child);
+ }
return nullptr;
}