Commit f594f482 authored by Ken Rockot's avatar Ken Rockot Committed by Chromium LUCI CQ

Fix geolocation-api/watchPosition-page-visibility

The mock geolocation service expects a new position to be set by the
time any new queryNextPosition request arrives.

This test was designed to call watchPosition and iterate over multiple
steps, with each step updating the mock position so that the watcher's
next queryNextPosition can be appropriately satisfied.

Unfortunately one of the steps does asynchronous work before updating
the mock position, so if the mock happens to receive a
queryNextPosition on behalf of the watcher before that work completes,
it will throw and fail the test. Flake ensues.

This addresses the issue by more carefully synchronizing the mock
state against the test logic, ensuring that stray queryNextPosition
handling is deferred during the asynchronous work.

Fixed: 1083824
Change-Id: I53b60d1104616bc1644573b48271823060698569
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2634006
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844298}
parent 8544f849
...@@ -1456,7 +1456,6 @@ crbug.com/944583 [ Mac ] fast/events/platform-wheelevent-paging-x-in-scrolling-p ...@@ -1456,7 +1456,6 @@ crbug.com/944583 [ Mac ] fast/events/platform-wheelevent-paging-x-in-scrolling-p
crbug.com/944583 [ Mac ] fast/events/platform-wheelevent-paging-y-in-scrolling-page.html [ Pass Failure Timeout ] crbug.com/944583 [ Mac ] fast/events/platform-wheelevent-paging-y-in-scrolling-page.html [ Pass Failure Timeout ]
# Sheriff: 2020-05-18 # Sheriff: 2020-05-18
crbug.com/1083820 [ Mac ] fast/scrolling/document-level-wheel-event-listener-passive-by-default.html [ Pass Failure ] crbug.com/1083820 [ Mac ] fast/scrolling/document-level-wheel-event-listener-passive-by-default.html [ Pass Failure ]
crbug.com/1083824 wpt_internal/geolocation-api/watchPosition-page-visibility.https.html [ Pass Failure Timeout ]
# In external/wpt/html/, we prefer checking in failure # In external/wpt/html/, we prefer checking in failure
# expectation files. The following tests with [ Failure ] don't have failure # expectation files. The following tests with [ Failure ] don't have failure
......
...@@ -81,9 +81,8 @@ export class GeolocationMock { ...@@ -81,9 +81,8 @@ export class GeolocationMock {
} }
return new Promise(resolve => { return new Promise(resolve => {
this.queryNextPositionIntercept_ = resolver => { this.queryNextPositionIntercept_ = resolver => {
resolve(geoposition => { this.queryNextPositionIntercept_ = null;
resolver({geoposition}); resolve(geoposition => { resolver({geoposition}); });
});
}; };
}); });
} }
......
...@@ -22,10 +22,15 @@ let mockLatitude = 51.478; ...@@ -22,10 +22,15 @@ let mockLatitude = 51.478;
let mockLongitude = -0.166; let mockLongitude = -0.166;
const mockAccuracy = 100.0; const mockAccuracy = 100.0;
function generateNextPosition() {
++mockLatitude;
++mockLongitude;
return mock.makeGeoposition(mockLatitude, mockLongitude, mockAccuracy);
}
function updatePosition() { function updatePosition() {
++mockLatitude; const p = generateNextPosition();
++mockLongitude; mock.setGeolocationPosition(p.latitude, p.longitude, p.accuracy);
mock.setGeolocationPosition(mockLatitude, mockLongitude, mockAccuracy);
} }
function setMainWindowHidden(hidden) { function setMainWindowHidden(hidden) {
...@@ -58,14 +63,6 @@ function checkPosition(p) { ...@@ -58,14 +63,6 @@ function checkPosition(p) {
assert_equals(position.coords.longitude, mockLongitude); assert_equals(position.coords.longitude, mockLongitude);
} }
async function showPageAndUpdatePosition() {
assert_false(isPageVisible);
state++;
await setMainWindowHidden(false);
isPageVisible = true;
updatePosition();
}
navigator.geolocation.watchPosition(async p => { navigator.geolocation.watchPosition(async p => {
assert_true(isPageVisible); assert_true(isPageVisible);
state++; state++;
...@@ -75,13 +72,28 @@ navigator.geolocation.watchPosition(async p => { ...@@ -75,13 +72,28 @@ navigator.geolocation.watchPosition(async p => {
updatePosition(); updatePosition();
break; break;
case 2: { case 2: {
// Make sure we stall the next queryNextPosition() request so we
// can defer its reply until the window is hidden.
let interception = mock.interceptQueryNextPosition();
await setMainWindowHidden(true); await setMainWindowHidden(true);
let respond = await interception;
isPageVisible = false; isPageVisible = false;
// This should not be received.
updatePosition(); // This should not be received. If it is, this enclosing function
// Wait for it to not be received, then continue. // will run with `isPageVisible` still `false` and the assertion at
// the top of the function will fail.
respond(generateNextPosition());
// Wait for it to not be received, then continue. We also defer the
// next queryNextPosition() here to stall until we've shown the
// window again.
interception = mock.interceptQueryNextPosition();
await roundTripToBrowser(); await roundTripToBrowser();
showPageAndUpdatePosition(); await setMainWindowHidden(false);
isPageVisible = true;
respond = await interception;
respond(generateNextPosition());
break; break;
} }
case 3: case 3:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment