diff --git a/moli-protocol-server/src/protocol_server/tests/cdp_dynamic_page.rs b/moli-protocol-server/src/protocol_server/tests/cdp_dynamic_page.rs index 011dc5c3a2..b86eb9580f 100644 --- a/moli-protocol-server/src/protocol_server/tests/cdp_dynamic_page.rs +++ b/moli-protocol-server/src/protocol_server/tests/cdp_dynamic_page.rs @@ -2876,15 +2876,30 @@ async fn named_popup_references_from_sibling_pages_share_the_close_lifetime() { } async fn navigate_dynamic_page_and_wait_for_load(page: &mut TestCdpSocket, id: u64, url: &str) { - send_cdp_command_without_wait(page, id, "Page.navigate", None, json!({"url": url})).await; - let mut responded = false; - let mut loaded = false; - recv_until_match(page, |message| { - responded |= message["id"] == id; - loaded |= message["method"] == "Page.loadEventFired"; - responded && loaded - }) + send_cdp_command( + page, + id, + "Page.setLifecycleEventsEnabled", + None, + json!({"enabled": true}), + ) .await; + let navigation = send_cdp_command(page, id, "Page.navigate", None, json!({"url": url})).await; + let response = response_by_id(&navigation, id); + assert!(response["error"].is_null(), "{response}"); + let loader = response["result"]["loaderId"] + .as_str() + .expect("dynamic navigation loader"); + // A popup's previous load may still be queued. Only the requested + // navigation's loader can establish that its document has finished. + let loaded = |message: &serde_json::Value| { + message["method"] == "Page.lifecycleEvent" + && message["params"]["loaderId"] == loader + && message["params"]["name"] == "load" + }; + if !navigation.iter().any(loaded) { + recv_until_match(page, loaded).await; + } } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] diff --git a/moli-renderer-v8/src/native_bridge/context_host/layout.rs b/moli-renderer-v8/src/native_bridge/context_host/layout.rs index a2772e3d70..717565abe7 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/layout.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/layout.rs @@ -628,6 +628,22 @@ impl JsContextHost { ) } + #[cfg(test)] + pub(crate) fn register_layout_test_font(&self, family: &str, bytes: Vec) { + let document = self.document_handle(); + self.document_layout_state + .borrow_mut() + .with_services_for_document(document, document, |services, _| { + services + .register_web_font(moli_layout::WebFontRegistration::new( + "layout-test-font", + moli_layout::WebFontFace::new(family), + bytes, + )) + .expect("valid layout test font"); + }); + } + #[cfg(test)] pub(crate) fn layout_snapshot_cache_observability_for_test( &self, diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/dom_surface/extracted/inline_layout.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/dom_surface/extracted/inline_layout.rs index 27246e0286..d1dde5ae9e 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/dom_surface/extracted/inline_layout.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/dom_surface/extracted/inline_layout.rs @@ -1339,7 +1339,7 @@ fn inline_end_border_preserves_tall_atomic_content() { } } -// Geometry measured in Chromium 145.0.7632.116, before and after publication. +// Geometry uses the bundled Ahem face, independently checked in Chromium. #[test] fn empty_inline_alignment_resolves_placement_separately_from_line_contribution() { let cases = [ @@ -1389,14 +1389,14 @@ fn empty_inline_alignment_resolves_placement_separately_from_line_contribution() ( "text_top", "", - [46.0, -46.0], - [91.0, 11.0], + [40.0, -40.0], + [95.0, 15.0], ), ( "text_bottom", "", - [32.0, 12.0], - [91.0, -11.0], + [30.0, 10.0], + [95.0, -15.0], ), ( "top", @@ -1421,9 +1421,14 @@ fn empty_inline_alignment_resolves_placement_separately_from_line_contribution() ] { for (id, content, quirks_geometry, standards_geometry) in cases { let markup = format!( - r#"{doctype}
{content}
"# + r#"{doctype}
{content}
"# ); let mut vm = new_parsed_test_vm("https://inline-alignment.test/", &markup); + vm._context_host.borrow().register_layout_test_font( + "MoliAhem", + include_bytes!("../../../../../../../moli-layout/tests/fixtures/moli-ahem.ttf") + .to_vec(), + ); let query = "JSON.stringify([line.getBoundingClientRect().height,b.getBoundingClientRect().top-a.getBoundingClientRect().top])"; let expected = if quirks { quirks_geometry @@ -1471,15 +1476,22 @@ fn forced_breaks_restore_ancestor_bidi_before_closing_inner_inline_boxes() { let whitespace = if preserved { ";white-space:pre" } else { "" }; let newline = if preserved { "\n" } else { "
" }; let markup = format!( - r#"{doctype}
x{newline}x
"# + r#"{doctype}
x{newline}x
"# ); let mut vm = new_parsed_test_vm("https://inline-bidi-forced-break.test/", &markup); + vm._context_host.borrow().register_layout_test_font( + "MoliAhem", + include_bytes!( + "../../../../../../../moli-layout/tests/fixtures/moli-ahem.ttf" + ) + .to_vec(), + ); let query = "JSON.stringify([line.getBoundingClientRect().height,second.getBoundingClientRect().top-line.getBoundingClientRect().top])"; let expected = if quirks || bidi == "normal" { - [90.0, 63.0] + [90.0, 65.0] } else { - [120.0, 81.0] + [120.0, 83.0] }; let first = vm.eval(query).unwrap(); assert_eq!( diff --git a/moli/tests/fetch_cli/http_fail.rs b/moli/tests/fetch_cli/http_fail.rs index a3f4a8cc28..23c9860c8f 100644 --- a/moli/tests/fetch_cli/http_fail.rs +++ b/moli/tests/fetch_cli/http_fail.rs @@ -2,8 +2,8 @@ use anyhow::Result; use axum::{ Router, extract::Path, - http::StatusCode, - response::{Html, IntoResponse, Redirect}, + http::{HeaderValue, StatusCode, header}, + response::{Html, IntoResponse, Redirect, Response}, routing::get, }; use base64::{Engine as _, engine::general_purpose::STANDARD}; @@ -99,7 +99,18 @@ impl HttpFailureFixture { ) .into_response() }), - ); + ) + .layer(axum::middleware::map_response( + |mut response: Response| async move { + // Separate requests must have identical fixture headers when + // the test compares their complete selected-format output. + response.headers_mut().insert( + header::DATE, + HeaderValue::from_static("Thu, 01 Jan 1970 00:00:00 GMT"), + ); + response + }, + )); let listener = TcpListener::bind("127.0.0.1:0").await?; let base_url = format!("http://{}", listener.local_addr()?); let task = tokio::spawn(async move {