Simulate a Device Moving Along a GPS Route
This tutorial walks through building an automation that moves a webmate-deployed device along a real-world GPS route at a configurable speed, with smooth interpolation between waypoints so the device never appears to teleport.
Goal
By the end of this article you will have a self-contained TypeScript script that:
- requests an Android device through the webmate SDK,
- attaches to it with an Appium driver,
- and feeds it a continuous stream of GPS fixes that trace a list of waypoints at a target speed (km/h).
This is the foundation for testing navigation apps, fitness and sports trackers, ride-share and delivery flows, and any feature that depends on geofences or trip detection. Naive setLocation(start) → setLocation(end) calls produce visible teleports that break step-counters, route-matching, and trip-recording logic; this suite shows how to avoid that.
Before You Start
You need:
- A webmate account with an API key — see Generate an API Key .
- A project ID in which to deploy the device.
- Node.js 18 or newer and a working TypeScript toolchain.
- The
webmate-sdk-jspackage. The fastest starting point is the TypeScript SDK samples repository (opens in a new tab) — clone it and add this suite as a new test file. - An Appium-aware WebDriver client. The samples repo already pulls in
selenium-webdriver, which is W3C compatible and can talk to the Appium server that backs webmate mobile sessions — that is what the code below assumes.
Design the Route
A route is just an ordered list of waypoints plus a target ground speed:
Make It Smooth
The interesting part of this suite is not pushing a coordinate to the device — that is one Appium call. The interesting part is producing a believable sequence of coordinates.
Three rules cover most cases:
- Fix a tick interval. Real GPS chipsets emit fixes at roughly 1 Hz. Match that. A 1-second tick keeps map UIs smooth and avoids hammering the API; a 200 ms tick looks identical to the user but quadruples request volume.
- Measure each leg in meters. Use the haversine formula to get the great-circle distance between two waypoints. This is what lets you translate “30 km/h” into “how far should I advance this tick”.
- Interpolate along the leg. At each tick, advance a progress fraction
t ∈ [0, 1]along the current leg by(speed_mps × dt) / leg_length_m, then linearly interpolate latitude and longitude between the leg’s endpoints. Whentoverflows past1, carry the remainder into the next leg so the cadence stays smooth across waypoint boundaries.
Linear interpolation of lat/lon is fine for legs up to a few kilometers at human or vehicle speeds. For continent-scale legs you would want proper great-circle interpolation, but that is overkill here.
If you want to polish the result further, apply an ease-in/ease-out curve to the first and last few seconds of the full route, so the device does not jump from stationary straight to cruising speed. This matters mostly for fitness apps that record acceleration.
Push Updates to the Device
webmate exposes GPS simulation as a device capability (sensorsimulation.gps), but the JavaScript SDK does not currently wrap it with a convenience method. The simplest cross-platform path is to send the Appium mobile: setLocation extension command through any W3C WebDriver client — Appium’s bridge accepts it on both UIA2 (Android) and XCUITest (iOS):
| |
Use the SDK to deploy the device and pull the Selenium / Appium endpoint, then hand control to the driver for the location stream. This mirrors the pattern used in the existing sample at webmate-sdk-js-samples/src/device-interaction.test.ts, which deploys a device via Webmate.startSession(...) and DeviceRequest before driving it.
Complete Sample
| |
Verify the Result
Open the running device in the webmate Live View (or launch a map app on it before starting the script) and watch the blue dot trace the route. The motion should look continuous — no teleports between waypoints, and no stalls at corners.
Two tuning levers to keep in mind:
- A tick interval larger than ~2 seconds will look choppy to the user and may cause map-matching libraries to drop fixes.
- A tick interval below ~250 ms quadruples API volume for no perceivable gain, and can rate-limit your session.
If the route looks fine but your application under test still sees teleports, check that the app actually listens to the OS-level fused location provider and is not caching its own last-known position.
Next Steps
Two extensions are planned for this suite:
- OSM-routed paths. Replace the hand-supplied waypoint list with a call to a routing service — OSRM, GraphHopper, or Valhalla — that takes a start and end point and returns a dense polyline. Feed that polyline into
driveRouteunchanged. - Mixing GPS with other sensor simulation. Combine the GPS stream with camera simulation so a “scan a delivery QR code while standing at the destination” flow can be exercised end-to-end. The existing camera-simulation sample at
webmate-sdk-js-samples/src/device-interaction.test.tsshows the API shape to extend.