Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion markanywhere-browse/src/commonMain/kotlin/WaitUntilLoaded.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ public suspend fun Tab.waitForNetworkIdle(
* (resolving `true`) or the [timeout] cap is hit (resolving `false`). Running
* the debounce inside the page avoids round-tripping every mutation over CDP.
*
* The observed target is `document`, not `document.documentElement`: right
* after a navigation commits there is a window in which the new document has
* no document element yet, and `observe(null)` throws `TypeError: parameter 1
* is not of type 'Node'` — which, called on the heels of a click that
* navigates, fails the whole wait. A `Document` is always a `Node`, and
* `subtree: true` from it covers everything `documentElement` would have,
* including a document element that appears (or is replaced) later.
*
* @return `true` if the DOM went quiet, `false` if [timeout] elapsed first.
*/
public suspend fun Tab.waitForDomIdle(
Expand All @@ -163,7 +171,7 @@ public suspend fun Tab.waitForDomIdle(
timer = setTimeout(() => finish(true), quiet);
};
const observer = new MutationObserver(bump);
observer.observe(document.documentElement, {
observer.observe(document, {
subtree: true, childList: true, attributes: true, characterData: true
});
bump();
Expand Down
18 changes: 18 additions & 0 deletions markanywhere-browse/src/commonTest/kotlin/WaitUntilLoadedTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ class WaitUntilLoadedTest {
assert(!idle)
}

@Test
fun `waitForDomIdle should report idle on a document with no document element`() = runTest {
val idle = runInBrowser { browser ->
// given — a document whose documentElement is gone, standing in for the
// window right after a navigation commits, before the new document has
// one; observing it directly would throw "parameter 1 is not of type
// 'Node'" and fail every click that navigates
val tab = browser.get(testPageUrl("simple.html"))
tab.rawEvaluate("document.removeChild(document.documentElement)")

// when
tab.waitForDomIdle(quietTime = 300.milliseconds, timeout = 10.seconds)
}

// then — the wait completes normally, and the empty document is quiet
assert(idle)
}

@Test
fun `waitForNetworkIdle should report idle on a page issuing no requests`() = runTest {
val idle = runInBrowser { browser ->
Expand Down