Testing locations in iOS 10 & XCode 8

Is anyone aware of a workaround for XCUITest not supporting geolocations? Is there a way to set up a profile in XCode that spoofs a certain location based on GPS coordinates or a street address?

I have an existing test suite that tests an iOS mapping application (like Yelp’s map view), so in order to fully exercise the application we need to be able to set locations.

Is there truly no way to set a location using Appium while testing an iOS 10 app using XCode 8?

device or simulator?

Simulator currently. If there’s a workaround by using a real device, I’m happy to consider that as well.

try:

General way

Location tallinn_airport_loc = new Location(59.416343, 24.802423, 0);
((IOSDriver) driver).setLocation(tallinn_airport_loc);

Simulator hard way with osascript (did not check long time but worked 1year ago)

public void setLocationWithEmulator(Location loc) {
        try {
            String[] cmd = {"osascript", "-e",
                    "on menu_click(mList)\n" +
                    "    local appName, topMenu, r\n" +
                    "\n" +
                    "    -- Validate our input\n" +
                    "    if mList's length < 3 then error \"Menu list is not long enough\"\n" +
                    "\n" +
                    "    -- Set these variables for clarity and brevity later on\n" +
                    "    set {appName, topMenu} to (items 1 through 2 of mList)\n" +
                    "    set r to (items 3 through (mList's length) of mList)\n" +
                    "\n" +
                    "    -- This overly-long line calls the menu_recurse function with\n" +
                    "    -- two arguments: r, and a reference to the top-level menu\n" +
                    "    tell application \"System Events\" to my menu_click_recurse(r, ((process appName)'s ¬\n" +
                    "        (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))\n" +
                    "end menu_click\n" +
                    "\n" +
                    "on menu_click_recurse(mList, parentObject)\n" +
                    "    local f, r\n" +
                    "\n" +
                    "    -- `f` = first item, `r` = rest of items\n" +
                    "    set f to item 1 of mList\n" +
                    "    if mList's length > 1 then set r to (items 2 through (mList's length) of mList)\n" +
                    "\n" +
                    "    -- either actually click the menu item, or recurse again\n" +
                    "    tell application \"System Events\"\n" +
                    "        if mList's length is 1 then\n" +
                    "            click parentObject's menu item f\n" +
                    "        else\n" +
                    "            my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))\n" +
                    "        end if\n" +
                    "    end tell\n" +
                    "end menu_click_recurse\n" +
                    "\n" +
                    "application \""+simulatorAppName()+"\" activate    \n" +
                    "delay 0.2\n" +
                    "menu_click({\""+simulatorAppName()+"\",\"Debug\", \"Location\", \"None\"})\n" +
                    "\n" +
                    "delay 0.2\n" +
                    "menu_click({\""+simulatorAppName()+"\",\"Debug\", \"Location\", \"Custom Location…\"})\n" +
                    "\n" +
                    "delay 0.2\n" +
                    "tell application \"System Events\"\n" +
                    "    tell process \""+simulatorAppName()+"\"\n" +
                    "        set value of text field 1 of window \"Custom Location\" to \""+loc.getLatitude()+"\"\n" +
                    "        set value of text field 2 of window \"Custom Location\" to \""+loc.getLongitude()+"\"\n" +
                    "        click UI Element \"OK\" of window \"Custom Location\"\n" +
                    "    end tell\n" +
                    "end tell"
            };
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(process.getErrorStream()));
            String lsString;
            while ((lsString = bufferedReader.readLine()) != null) {
                System.out.println(lsString);
            }
            try{Thread.sleep(10000);}catch (Exception e1){}
        } catch (Exception e) {}
    }
    public String simulatorAppName() {
        return "Simulator";
    }

Thanks I’ll give that a shot.

@Aleksei Thanks for posting this code. I tried it, and when the Custom Location dialog opens the OK button is disabled.

Do you happen to know of a work around for this?

Thanks

DD

I figured out the issue. I had to:

  1. Open Xcode
  2. Product -> Scheme -> Edit Scheme
  3. Click Run
  4. Check Allow Location Simulation

In Order to get the below to work
1. Apple->System Preference
2. Click Security & Privacy
3. Click Privacy Tab
4. Click the Lock to Unlock
5. Check Eclipse
6. Lock again

1 Like