diff --git a/apps/ai-game-creator-shell/src-tauri/src/browser/playtest/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/browser/playtest/mod.rs index df4619c02..1df7ccf9a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/browser/playtest/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/browser/playtest/mod.rs @@ -422,7 +422,8 @@ pub(super) const PROBE_PLAYTEST_CONTROL_SCRIPT: &str = r#"function() { } let stylesVisible = true; - let pointerBlocked = false; + // 后代可用 auto 覆盖祖先的 none;未覆盖时计算样式仍会继承 none。 + const pointerBlocked = getComputedStyle(this).pointerEvents === 'none'; for (let current = this; current instanceof HTMLElement; current = current.parentElement) { const style = getComputedStyle(current); const opacity = Number.parseFloat(style.opacity); @@ -431,7 +432,6 @@ pub(super) const PROBE_PLAYTEST_CONTROL_SCRIPT: &str = r#"function() { && style.visibility !== 'hidden' && style.visibility !== 'collapse' && (Number.isNaN(opacity) || opacity > 0); - pointerBlocked ||= style.pointerEvents === 'none'; } const rect = this.getBoundingClientRect(); diff --git a/apps/ai-game-creator-shell/src-tauri/src/browser/tests.rs b/apps/ai-game-creator-shell/src-tauri/src/browser/tests.rs index 0d98e7c97..9d8733862 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/browser/tests.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/browser/tests.rs @@ -270,16 +270,12 @@ fn playtest_scenario_fingerprints_are_fixed_lowercase_sha256_values() { let tetris = browser_playtest_scenario_fingerprint(BrowserPlaytestScenario::TetrisV1); let lane = browser_playtest_scenario_fingerprint(BrowserPlaytestScenario::LaneDefenseV1); assert_eq!( - generic, - "e5e1b4d01e39cb7b0dd2fd5a56982c3ddf825a926738d99152875ee1ff412a8d" - ); - assert_eq!( - tetris, - "b3c49f43f70291ea5c9431a21bb751fead2e244c8e97fecec20ee3e38215a59c" - ); - assert_eq!( - lane, - "6a24072ce7a570dd29edac0ca3fa905546140e44ca4ab6412d8fc7fe1239aa5a" + [generic.as_str(), tetris.as_str(), lane.as_str()], + [ + "85e7ec677411745ad3a7385db67a2c89441cb2ccc12a7a1853bb87ba74f15e0d", + "60c202a9fe6313dd414365db52df8b5b63110971f89708ac1563d531f510f4ff", + "a3120c8cf585f2e06091229c3b7c3a5bd8aa08821704064edc611297ee54f466", + ] ); assert!(generic.bytes().all(|byte| byte.is_ascii_hexdigit())); assert!(tetris.bytes().all(|byte| byte.is_ascii_hexdigit())); @@ -1354,7 +1350,7 @@ async fn real_chrome_generic_playtest_rejects_one_frame_playing_state() { #[tokio::test] #[ignore = "requires an installed Chrome/Chromium/Edge and explicit local browser execution"] async fn real_chrome_generic_playtest_accepts_earlier_window_capture_stop_immediate_flow() { - let result = run_stable_generic_viewport_fixture(false).await; + let result = run_stable_generic_viewport_fixture(false, None).await; assert!( result.passed, "diagnostics={:#?}\nviewports={:#?}", @@ -1388,7 +1384,7 @@ async fn real_chrome_generic_playtest_accepts_earlier_window_capture_stop_immedi #[tokio::test] #[ignore = "requires an installed Chrome/Chromium/Edge and explicit local browser execution"] async fn real_chrome_generic_playtest_rejects_mobile_only_unwired_control() { - let result = run_stable_generic_viewport_fixture(true).await; + let result = run_stable_generic_viewport_fixture(true, None).await; assert!( !result.passed, "a successful desktop cannot hide mobile gameplay failure" @@ -1410,8 +1406,117 @@ async fn real_chrome_generic_playtest_rejects_mobile_only_unwired_control() { .any(|message| message.starts_with("playtest mobile:"))); } +#[tokio::test] +#[ignore = "requires an installed Chrome/Chromium/Edge and explicit local browser execution"] +async fn real_chrome_generic_playtest_pointer_events_allows_auto_under_none() { + let result = run_stable_generic_viewport_fixture( + false, + Some( + r#"