DEV Community

Cover image for Emulate GeoLocation for Automated Testing with webdriverIO
Pablo Calvo for coffeestain.io

Posted on

Emulate GeoLocation for Automated Testing with webdriverIO

As exposed on the first post of this series, Google Chrome DevTools includes a series of features that facilitate the emulation of customers Experience Profiles, such as device, resolution and of course geographical location.

Chrome DevTools Protocol

Once you have mastered the art of manual testing and want to try some automated geoLocation testing, you don't have to look away looking for new tools. Chrome DevTools exposes its own Protocol which allow us to programmatically use the same tools you know how to use on the browser.

Let's automate it

For the sake of this post I decided to use webdriverIO to write the automated tests. The reason to use this framework is that there is 3rd party service already developed and ready to use that allow us to seamlessly use the devTools without adding any extra code.

Getting started

Setup the project

We need to create a folder, and start a nodeJs project. (Recommended: Make sure the latest version of node is installed).

$ mkdir webdriverio-test && cd webdriverio-test
$ npm init -y

Install webdriverIO CLI

Now let's install the wdio CLI, which provide us with tools to setup and run a basic webdriverIO project.

$ npm i --save-dev @wdio/cli

Generate a wdio config file and create a test folder

WebdriverIO uses a configuration file (by default wdio.conf.js) that contains the basic information of the framework. Once the basic setup is complete webdriverIO will look into ./test/specs for the test files.

$ npx wdio config -y
$ mkdir -p ./test/specs

Setup devTools service

So far we have only setup the basic default configuration for webdriverIO. On this next step we are going to include the devTools service which will provide us with capabilities to interact with the devTools protocol.

$ npm install @wdio/devtools-service --save-dev

Then go to the wdio.conf.js and add the devtools service to the webdriverIO configuration.

...
// Services take over a specific job you don't want to take care of. They enhance
// your test setup with almost no effort. Unlike plugins, they don't add new
// commands. Instead, they hook themselves up into the test process.
    services: ["devtools"],
..

This is basically all the necessary configuration

Now let's create some tests

Create a file under the folder above and name it geo.js. This file will contain our testing code.

Test Scenario

  1. Navigate to https://www.where-am-i.net/ and verify the current position.
  2. Use devTools to emulate a different location. (London)
  3. Verify that the user is on a new location.
  4. Again use devTools to emulate another location. (Tokyo)
  5. Repeat the verification.

Read the comments in the code

const assert = require('assert')

describe('Check Location overriding the timezone', () => {
    it('Check the default timezone', () => {
        browser.url('https://www.where-am-i.net/')
        // this validation depends on where are you!
        // assert.equal(location.getText(), '19.075984, 72.877656')
        // you might get 0.0 and 0.0 the first time because of authorization issues
    })

    it('Check that London should be the timezone', () => {
        // change to london location and timezone
        // cdp is the command to use a devTools command
        // we are going to use the Emulation module
        // and the setGeoLocationOverride method
        // info: https://chromedevtools.github.io/devtools-protocol/tot/Emulation/
        // note: the location and timezone must match or you will get an unavailable position    

        browser.cdp('Emulation', 'setGeolocationOverride' , {
            latitude:51.507351,
            longitude:-0.127758,
            accuracy: 1
        })
        browser.cdp('Emulation', 'setTimezoneOverride', {
            timezoneId: 'Europe/London'
        })       
        browser.pause(3000) // wait so you can notice the map changing
        let location = $('#location') // get a location reference for validation
        assert.equal(location.getText(), '51.507351, -0.127758')

    })

    it('Check that Tokyo should be the timezone', () => {
        // change to lo Tokyo location and timezone
        browser.cdp('Emulation', 'setGeolocationOverride' , {
            latitude:35.689487,
            longitude:139.691706,
            accuracy: 1
        })

        browser.cdp('Emulation', 'setTimezoneOverride', {
            timezoneId: 'Asia/Tokyo'
        })
        browser.pause(3000) // wait so you can notice the map changing
        assert.equal($('#location').getText(), '35.689487, 139.691706')
    })
});

Let's execute the tests

Just run on your terminal

$ npx wdio wdio.conf.js

Alt Text

Just like that!! We just emulated different user locations with no need to add complicated code or any extra tooling.

Now what?

Well... this example is just a very small fragment of what you actually accomplish with devTools and webdriverIO. I encourage you to explore more the documentation for both tools and discover new capabilities that can be added to your tests.

webdriverIO devTools Service
Chrome devTools Protocol

Share your thoughts and comments on how you test geolocation within your automated tests!!

Top comments (4)

Collapse
 
coderrr profile image
rk_coderr • Edited

Hey ,
After updating webdriveIO package getting below error
webdriver= 7.33.0
webdriverio=7.33.0
await browser.setGeoLocation({ latitude, longitude, accuracy });
Cannot read properties of undefined (reading 'logLevels')
at remote (file:///C:/Users/rupali.kale/workspace/bulk-upload-automation-app/node_modules/webdriverio/build/index.js:28:38)
at exports.remote (node_modules\webdriverio\build\cjs\index.js:83:12)
not able to execute in local env..
can anyone pls help me here!!

Collapse
 
grk_official profile image
Guna Ravikumar 🇮🇳 • Edited

It is working as expected in local but unable to run in selenium grid. getting an error [chrome 98.0.4758.102 linux #0-0] browser.cdp is not a function
[chrome 98.0.4758.102 linux #0-0] TypeError: browser.cdp is not a function
[chrome 98.0.4758.102 linux #0-0] at Context. (/home/gunaravikumar/automated-qa-mp/test/specs/tires_wallet_landing_test.js:33:39).

what is the solution to run in selenium grid ?? please help me as soon as possible.

Collapse
 
grk_official profile image
Guna Ravikumar 🇮🇳 • Edited

In the case of using the browser.cdp, it works fine when running the test on the local environment, but in the case of remote running, I get this error:

[chrome 98.0.4758.102 linux #0-0] browser.cdp is not a function
[chrome 98.0.4758.102 linux #0-0] TypeError: browser.cdp is not a function
[chrome 98.0.4758.102 linux #0-0] at Context. (/home/gunaravikumar/automated-qa-mp/test/specs/tires_wallet_landing_test.js:33:39).

Collapse
 
coderrr profile image
rk_coderr • Edited

tried to use browser.cdp but stuck due this error
Cannot read properties of undefined (reading 'logLevels')
at remote (node_modules\webdriverio\build\index.js:57:48)
can anyone pls help me here!!