diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp
index 022936135c5..23013d3dbf5 100644
--- a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp
@@ -62,28 +62,22 @@ void HTMLIFrameElement::attribute_changed(FlyString const& name, Optional(shadow_including_root()))
- return;
-
DOM::Document& document = verify_cast(shadow_including_root());
// NOTE: The check for "not fully active" is to prevent a crash on the dom/nodes/node-appendchild-crash.html WPT test.
if (!document.browsing_context() || !document.is_fully_active())
return;
- // 2. Create a new child navigable for insertedNode.
+ // The iframe HTML element post-connection steps, given insertedNode, are:
+ // 1. Create a new child navigable for insertedNode.
MUST(create_new_child_navigable(GC::create_function(realm().heap(), [this] {
- // FIXME: 3. If insertedNode has a sandbox attribute, then parse the sandboxing directive given the attribute's
+ // FIXME: 2. If insertedNode has a sandbox attribute, then parse the sandboxing directive given the attribute's
// value and insertedNode's iframe sandboxing flag set.
- // 4. Process the iframe attributes for insertedNode, with initialInsertion set to true.
+ // 3. Process the iframe attributes for insertedNode, with initialInsertion set to true.
process_the_iframe_attributes(true);
set_content_navigable_initialized();
})));
diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.h b/Libraries/LibWeb/HTML/HTMLIFrameElement.h
index 085df19052c..221da71bc6f 100644
--- a/Libraries/LibWeb/HTML/HTMLIFrameElement.h
+++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.h
@@ -41,7 +41,7 @@ private:
virtual void initialize(JS::Realm&) override;
// ^DOM::Element
- virtual void inserted() override;
+ virtual void post_connection() override;
virtual void removed_from(Node*) override;
virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override;
virtual i32 default_tab_index_value() const override;
diff --git a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.txt b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.txt
new file mode 100644
index 00000000000..a79a2fd0486
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.txt
@@ -0,0 +1,9 @@
+Harness status: OK
+
+Found 4 tests
+
+4 Pass
+Pass Script inserted after an iframe in the same appendChild() call can observe the iframe's non-null contentWindow
+Pass A script inserted atomically before an iframe (using a div) does not observe the iframe's contentWindow, since the 'script running' and 'iframe setup' both happen in order, after DOM insertion completes
+Pass A script inserted atomically before an iframe (using a DocumentFragment) does not observe the iframe's contentWindow, since the 'script running' and 'iframe setup' both happen in order, after DOM insertion completes
+Pass A script inserted atomically before an iframe (using a append() with multiple arguments) does not observe the iframe's contentWindow, since the 'script running' and 'iframe setup' both happen in order, after DOM insertion completes
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.html b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.html
new file mode 100644
index 00000000000..d3277fff8ac
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/insertion-removing-steps/Node-appendChild-script-and-iframe.tentative.html
@@ -0,0 +1,89 @@
+
+
+Node.appendChild: inserting script and iframe
+
+
+
+