google-chromeandroid-emulatormockinglocationgoogle-chrome-devtools

Continuously emulate GPS Locations on Chrome


For a mobile web application I would like to emulate location movements of the device. While it is possible to override a single location using the Sensor Tab in Chrome's Developer Console (See: https://developers.google.com/web/tools/chrome-devtools/device-mode/device-input-and-sensors) I would like to override the location continuously, say for instance update the device's location every second.

Is there a possibility to achieve this in Chrome (or any other Desktop Browser)?

I am looking for a solution similar to the Android Emulator which allows to replay recorded GPS Tracks (From GPX or KML files): enter image description here

(See: https://developer.android.com/guide/topics/location/strategies.html#MockData)


Solution

  • DevTools has no feature for this, but if you happen to be using getCurrentPosition() you can pretty much recreate this by overriding the function in a snippet.

    I suppose this workflow won't work if you're using watchPosition() (which you probably are), because I believe that's basically a listener that gets fired when the browser updates the coordinates. There's no way to update the browser's coordinates.

    However, I'll record the workflow below b/c it may be useful to somebody else.

    1. Store your script in a snippet.
    2. Override navigator.geolocation.getCurrentPosition() to the target coordinates.

    So, you could store the coordinates and timestamps in JSON (either within the snippet, or just fetch the JSON from the snippet using XHR / Fetch), and then use setTimeout() to update the coordinates at the specified times.

    var history = [
      {
        time: 1000,
        coords: ...
      },
      {
        time: 3000,
        coords: ...
      }
    ];
    
    for (var i = 0; i < history.length; i++) {
      setTimeout(function() {
        navigator.geolocation.getCurrentPosition = function(success, failure) { 
          success({ 
            coords: history[i].coords,
            timestamp: Date.now()
          }); 
      }, history[i].time);
    }