From 699283e8600e29a3a41fba7526164273ed4cdefb Mon Sep 17 00:00:00 2001 From: Pierre Le Fevre Date: Sat, 18 Jul 2026 15:48:03 +0800 Subject: [PATCH] Improve Opera interaction and text metrics parity (isu issue 281) --- .isu/issues.json | 16 +- crates/e2e/scenarios/real-web/opera.com.we | 2 + crates/e2e/src/render.rs | 193 +++++++++++++++++++-- crates/layout/src/lib.rs | 152 ++++++++++++---- crates/render/src/atlas.rs | 17 +- crates/render/src/lib.rs | 28 ++- crates/text/src/font/mod.rs | 88 ++++++++++ 7 files changed, 426 insertions(+), 70 deletions(-) diff --git a/.isu/issues.json b/.isu/issues.json index f469af0..0eb1567 100644 --- a/.isu/issues.json +++ b/.isu/issues.json @@ -1,5 +1,5 @@ { - "next_id": 403, + "next_id": 404, "issues": [ { "id": 1, @@ -4922,6 +4922,20 @@ "author": "piefev", "state": "open", "created_at": "2026-07-18T07:06:15Z" + }, + { + "id": 403, + "repo": "we", + "title": "Opera parity remains blocked after dynamic interaction and font metrics fixes", + "body": "Parent: isu issue 281\n\nThis pass fixed two deterministic gaps while working on Opera parity:\n- scenario interactions now drain dynamically inserted scripts and refresh adopted styles/images before repainting, so the Opera SurveyMonkey path hydrates after the existing footer input interaction;\n- inline text layout now uses scaled font ascent/descent metrics for baseline offsets instead of assuming the baseline is exactly one font-size from the line top.\n\nThe Opera scenario now asserts the post-interaction survey container, but the Chromium screenshot assertions still fail.\n\nRepro:\n cargo run -p we-e2e -- --scenario crates/e2e/scenarios/real-web/opera.com.we --out-dir crates/e2e/artifacts\n\nCurrent result after this pass:\n- desktop L100: 64.71% match (433569/1228500 px differ, tol=4, max_diff=0.1000%)\n- mobile L112: 67.77% match (106103/329160 px differ, tol=4, max_diff=0.1000%)\n\nArtifacts:\n- crates/e2e/artifacts/real-web/opera.com/desktop.png\n- crates/e2e/artifacts/real-web/opera.com/desktop.png.diff.png\n- crates/e2e/artifacts/real-web/opera.com/desktop_dom.txt\n- crates/e2e/artifacts/real-web/opera.com/desktop_interaction_dom.txt\n- crates/e2e/artifacts/real-web/opera.com/mobile.png\n- crates/e2e/artifacts/real-web/opera.com/mobile.png.diff.png\n- crates/e2e/artifacts/real-web/opera.com/mobile_dom.txt\n- crates/e2e/artifacts/real-web/opera.com/mobile_interaction_dom.txt\n\nRemaining visible blockers are broad text raster/antialiasing differences, hero/cookie vertical placement, and first-screenshot timing/state differences versus the 5s-settled live Chromium golden. Keep crates/e2e/scenarios/real-web/opera.com.we xfail until both screenshot assertions pass within the default threshold.", + "labels": [ + "real-web", + "text" + ], + "assigned": [], + "author": "piefev", + "state": "open", + "created_at": "2026-07-18T07:37:25Z" } ] } diff --git a/crates/e2e/scenarios/real-web/opera.com.we b/crates/e2e/scenarios/real-web/opera.com.we index ed1dd09..a4007ef 100644 --- a/crates/e2e/scenarios/real-web/opera.com.we +++ b/crates/e2e/scenarios/real-web/opera.com.we @@ -96,6 +96,7 @@ assert_dom_contains "Opera" type [id=footer__lang-input-next] interactivity dump_dom real-web/opera.com/desktop_interaction_dom.txt assert_dom_contains https://www.opera.com/interactivity +assert_dom_contains survey_container assert_screenshot_matches real-web/opera.com/desktop.png opera.com.desktop.chromium.expected.png viewport 390 844 @@ -107,4 +108,5 @@ assert_dom_contains "Opera" type [id=footer__lang-input-next] interactivity dump_dom real-web/opera.com/mobile_interaction_dom.txt assert_dom_contains https://www.opera.com/interactivity +assert_dom_contains survey_container assert_screenshot_matches real-web/opera.com/mobile.png opera.com.mobile.chromium.expected.png diff --git a/crates/e2e/src/render.rs b/crates/e2e/src/render.rs index 307f6b2..3b71034 100644 --- a/crates/e2e/src/render.rs +++ b/crates/e2e/src/render.rs @@ -35,7 +35,7 @@ use we_render::{build_display_list_with_page_scroll, GpuRenderer, RenderFonts}; use we_style::computed::resolve_styles; use we_svg::{render_svg, svg_intrinsic_size, SvgIntrinsicSize}; use we_text::font::{self, Font, FontRegistry}; -use we_url::Url; +use we_url::{Origin, Url}; use crate::console::{CapturedConsole, RcConsole}; @@ -87,10 +87,12 @@ pub struct Session { pub height: u32, /// Captured `console.*` output. pub console: Rc, - /// Captured stylesheet from initial load (`