Skip to content
Draft
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
1 change: 0 additions & 1 deletion moli-benchmark/wpt-cross-current/failed-cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2805,7 +2805,6 @@ fullscreen/api/element-request-fullscreen-active-document.html
fullscreen/api/element-request-fullscreen-not-allowed.html
fullscreen/api/historical.html
fullscreen/api/promises-reject.html
geolocation/non-secure-contexts.http.html
gyroscope/Gyroscope-supported-by-permissions-policy.html
html/browsers/browsing-the-web/history-traversal/001.html
html/browsers/browsing-the-web/history-traversal/PopStateEvent.html
Expand Down
1 change: 1 addition & 0 deletions moli-benchmark/wpt-cross-current/passed-cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5054,6 +5054,7 @@ focus/iframe-focuses-parent-same-site.html
focus/scroll-matches-focus.html
fullscreen/api/document-fullscreen-enabled-active-document.html
fullscreen/rendering/fullscreen-pseudo-class-support.html
geolocation/non-secure-contexts.http.html
gyroscope/Gyroscope_insecure_context.html
hr-time/clamped-time-origin.html
hr-time/navigation-start-post-before-unload.html
Expand Down
36 changes: 33 additions & 3 deletions moli-protocol/src/conn/page_state/surfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ impl BrowserContext {
Object.defineProperty(obj, key, {{ configurable: true, get: getter }});
}} catch (_error) {{}}
}};
const geolocationOverrideEnabled = {geolocation_override_enabled};
const geolocationOverride = {geolocation_override};
const navigatorOnline = {navigator_online};
const maxTouchPoints = {max_touch_points};
Expand All @@ -467,7 +468,10 @@ impl BrowserContext {
const geoState = globalThis.__moliGeolocationState || {{
nextWatchId: 1,
watchers: new Map(),
object: null
object: null,
installed: false,
nativeHadOwnProperty: false,
nativeOwnDescriptor: null
}};
globalThis.__moliGeolocationState = geoState;
const previousOverrideKey = geoState.overrideKey || null;
Expand Down Expand Up @@ -559,12 +563,37 @@ impl BrowserContext {
}}
}};
}}
if (previousOverrideKey !== null && previousOverrideKey !== geoState.overrideKey) {{
if (geolocationOverrideEnabled && previousOverrideKey !== null && previousOverrideKey !== geoState.overrideKey) {{
for (const watcher of geoState.watchers.values()) {{
deliverGeolocation(watcher.success, watcher.error);
}}
}}
defineGetter(navigator, 'geolocation', () => geoState.object);
if (geolocationOverrideEnabled) {{
if (!geoState.installed) {{
geoState.nativeHadOwnProperty = Object.prototype.hasOwnProperty.call(
navigator,
'geolocation'
);
geoState.nativeOwnDescriptor = Object.getOwnPropertyDescriptor(
navigator,
'geolocation'
) || null;
}}
defineGetter(navigator, 'geolocation', () => geoState.object);
geoState.installed = true;
}} else if (geoState.installed) {{
if (geoState.nativeHadOwnProperty && geoState.nativeOwnDescriptor) {{
Object.defineProperty(
navigator,
'geolocation',
geoState.nativeOwnDescriptor
);
}} else {{
delete navigator.geolocation;
}}
geoState.installed = false;
geoState.watchers.clear();
}}
}} catch (_error) {{}}
defineGetter(navigator, 'onLine', () => currentNavigatorOnline());
defineGetter(navigator, 'maxTouchPoints', () => maxTouchPoints);
Expand All @@ -584,6 +613,7 @@ impl BrowserContext {
}} catch (_error) {{}}
}}
}})();",
geolocation_override_enabled = geolocation_override.is_some(),
geolocation_override = geolocation_override
.and_then(EmulatedGeolocationOverrideState::position)
.map(|position| {
Expand Down
88 changes: 88 additions & 0 deletions moli-protocol/src/domains/emulation/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2396,6 +2396,94 @@ async fn evaluate_geolocation_once_for_session(
ctx.take_response_by_id(id)["result"]["result"]["value"].clone()
}

async fn evaluate_geolocation_surface_shape(ctx: &mut TestContext, id: u64) -> serde_json::Value {
ctx.process_and_wait_for_response_async(json!({
"id": id,
"method": "Runtime.evaluate",
"sessionId": "SID-1",
"params": {
"awaitPromise": true,
"returnByValue": true,
"expression": r#"
new Promise((resolve) => {
const geolocation = navigator.geolocation;
const finish = (outcome) => resolve(JSON.stringify({
outcome,
navigatorOwn: Object.prototype.hasOwnProperty.call(
navigator,
"geolocation"
),
nativePrototype:
typeof Geolocation === "function" &&
Object.getPrototypeOf(geolocation) === Geolocation.prototype
}));
geolocation.getCurrentPosition(
() => finish("success"),
(error) => finish(`error:${error.code}`)
);
})
"#
}
}))
.await;
let response = ctx.take_response_by_id(id);
let value = response["result"]["result"]["value"]
.as_str()
.expect("geolocation surface shape should be a JSON string");
serde_json::from_str(value).expect("geolocation surface shape should be valid JSON")
}

#[tokio::test(flavor = "multi_thread")]
async fn geolocation_override_only_shadows_native_surface_while_enabled() {
let mut ctx = TestContext::new();
let mut bc = BrowserContext::new("BID-1".into());
bc.set_active_target_id("TID-1");
bc.attach_active_session("SID-1");
install_session_page_for_emulation_test(&mut ctx, bc, "data:text/html,<body>geo</body>").await;

assert_eq!(
evaluate_geolocation_surface_shape(&mut ctx, 101).await,
json!({
"outcome": "error:1",
"navigatorOwn": false,
"nativePrototype": true,
})
);

ctx.process_async(json!({
"id": 102,
"method": "Emulation.setGeolocationOverride",
"sessionId": "SID-1",
"params": { "latitude": 1, "longitude": 2, "accuracy": 3 }
}))
.await;
ctx.expect_result(102, json!({}), Some("SID-1"));
assert_eq!(
evaluate_geolocation_surface_shape(&mut ctx, 103).await,
json!({
"outcome": "success",
"navigatorOwn": true,
"nativePrototype": false,
})
);

ctx.process_async(json!({
"id": 104,
"method": "Emulation.clearGeolocationOverride",
"sessionId": "SID-1"
}))
.await;
ctx.expect_result(104, json!({}), Some("SID-1"));
assert_eq!(
evaluate_geolocation_surface_shape(&mut ctx, 105).await,
json!({
"outcome": "error:1",
"navigatorOwn": false,
"nativePrototype": true,
})
);
}

#[tokio::test(flavor = "multi_thread")]
async fn set_geolocation_override_updates_loaded_page_geolocation_surface() {
let mut ctx = TestContext::new();
Expand Down
Loading