Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support getGeoLocation (requires 'Always' in Location Services) #1266

Merged
merged 6 commits into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
37 changes: 37 additions & 0 deletions lib/commands/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@ import log from '../logger';

let commands = {};

/**
* @typedef {Object} LocationObject
*
* @property {number} latitude - The latitude of the device under test
* @property {number} longitude - The lognitude of the device under test
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
* @property {number} altitude - Always 0 since iOS does not return altitude as the Location Service
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
*/

/**
* Returns location of the device under test.
* The device under test must allow the location services for WDA
* as 'Always' to get the location data correctly.
*
* The 'latitude' and 'longitude' could be zero even the location services
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
* is 'Always' since it needs a time to uptodate the location data.
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
*
* @returns {LocationObject}
* @throws {Error} If the device under test returns an error message.
* i.e.: tvOS returns unsupported error
*/
commands.getGeoLocation = async function getGeoLocation () {
const {
authorizationStatus,
latitude,
longitude
} = await this.proxyCommand('/wda/device/location', 'GET');

// '3' is 'Always' in the privacy
// https://developer.apple.com/documentation/corelocation/clauthorizationstatus
if (authorizationStatus !== 3) {
log.errorAndThrow(`Location service must be 'Always'. Please set it up manually via ` +
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Jan 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must be set to 'Always' in order to retrieve the current geolocation data

`'Settings > Privacy > Location Services -> WebDriverAgentRunner-Runner'`);
}

return {latitude, longitude, altitude: 0};
};

commands.setGeoLocation = async function setGeoLocation (location) {
let {latitude, longitude} = location;

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"appium-ios-simulator": "^3.25.1",
"appium-remote-debugger": "^8.13.2",
"appium-support": "^2.47.1",
"appium-webdriveragent": "^2.32.2",
"appium-webdriveragent": "^2.33.0",
"appium-xcode": "^3.8.0",
"async-lock": "^1.0.0",
"asyncbox": "^2.3.1",
Expand Down
7 changes: 7 additions & 0 deletions test/functional/basic/basic-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ describe('XCUITestDriver - basics -', function () {
});
});

describe('get geo location -', function () {
it('should fail because of preference error', async function () {
await driver.getGeoLocation('30.0001', '21.0002')
.should.eventually.be.rejectedWith('Location service must be');
});
});

describe('geo location -', function () {
it('should work on Simulator', async function () {
if (process.env.CI || process.env.REAL_DEVICE) {
Expand Down
24 changes: 24 additions & 0 deletions test/unit/commands/location-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@ describe('location commands', function () {
proxySpy.reset();
});

describe('getGeoLocation', function () {
it('should be authorizationStatus !== 3', async function () {
proxySpy.withArgs(
'/wda/device/location',
'GET').returns({authorizationStatus: 0, latitude: 0, longitude: 0});

await driver.getGeoLocation({})
.should.eventually.be.rejectedWith('Location service must be');
});

it('should be authorizationStatus === 3', async function () {
proxySpy.withArgs(
'/wda/device/location',
'GET').returns({authorizationStatus: 3, latitude: -100, longitude: 100});

await driver.getGeoLocation({})
.should.eventually.eql({
altitude: 0,
latitude: -100,
longitude: 100
});
});
});

describe('setLocation', function () {
let startSimulateLocationServiceStub;
let setLocationStub;
Expand Down