【问题标题】:Appium - How to set Geo Location on iOS Device?Appium - 如何在 iOS 设备上设置地理位置?
【发布时间】:2018-01-31 13:32:07
【问题描述】:

元:-

  • iOS模拟器设备v10.3
  • Appium java-client v5.0.0 BETA8
  • 硒 v3.4.0

实际上我正在尝试使用Appium XCUITest 自动化在iOS 设备中设置GeoLocation。我试过下面的代码,它在Android 设备上运行良好,而在iOS 上抛出异常:

import org.openqa.selenium.html5.Location;

AppiumServiceBuilder builder = new AppiumServiceBuilder().usingAnyFreePort().withAppiumJS("path/to/appium/main.js");

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("automationName", "XCUITest");
IOSDriver driver= new IOSDriver(builder, capabilities);

//Here this code working fine with AndroidDriver
Location location = new Location(latitude, longitude, altitude);    
driver.setLocation(location);

例外:

org.openqa.selenium.WebDriverException:方法尚未实现(警告:服务器未提供任何堆栈跟踪信息)

当我尝试使用 JavascriptExecutor 时:

Map<String, String> args = new HashMap<String, String>();
args.put("address", "Address");
((JavascriptExecutor)webDriver).executeScript("mobile:setLocation", args);

例外:

org.openqa.selenium.UnsupportedCommandException:未知的移动命令“setLocation”。仅支持滚动、滑动、捏合、双击、双指敲击、触摸并按住、点击、拖动从ToForDuration、selectPickerWheelValue、警报命令。 (警告:服务器未提供任何堆栈跟踪信息)

当我尝试时:

import org.openqa.selenium.remote.DriverCommand;

Map<String, String> args = new HashMap<String, String>();
args.put("location", "Address");
driver.execute(DriverCommand.SET_LOCATION, args);

例外:

org.openqa.selenium.WebDriverException:方法尚未实现(警告:服务器未提供任何堆栈跟踪信息)

有没有办法使用 appium 在iOS 上设置GeoLocation

Appium 日志:

[debug] [JSONWP Proxy] 得到状态 200 的响应:"{\n \"value\" : {\n \"state\" : \"success\",\n \"os\" : { \n \"name\" : \"iOS\",\n \"version\" : \"10.3.1\"\n },\n \"ios\" : {\n \"simulatorVersion\" : \"10.3.1\",\n \"ip\" : \"192.168.1.17\"\n },\n \"build\" : {\n \"time\" : \"2017 年 8 月 29 日 15 :40:09\"\n }\n },\n \"sessionId\" : \"10A97A93-D13A-4888-A536-0D62E0674A2B\",\n \"status\" : 0\n}"

[调试] [XCUITest] WebDriverAgent 在 ip '192.168.1.17' 上运行 [调试] [XCUITest] WebDriverAgent 在 16121ms 后成功启动 [debug] [BaseDriver] 事件“wdaSessionAttempted”记录在 1504013035278 (18:53:55 GMT+0530 (IST)) [debug] [XCUITest] 发送 createSession 命令到 WDA [debug] [JSONWP Proxy] 代理 [POST /session] 到 [POST http://localhost:8100/session] 正文: {"desiredCapabilities":{"bundleId":"com.example.apple-samplecode.UICatalog","arguments":[],"environment":{},"shouldWaitForQuiescence":true,"shouldUseTestManagerForVisibilityDetection":false,"maxTypingFrequency ":120,"shouldUseSingletonTestManager":true}} [调试] [JSONWP 代理] 得到状态 200 的响应: {"value":{"sessionId":"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C","capabilities":{"device":"iphone","browserName":"UICatalog","sdkVersion":"10.3. 1","CFBundleIdentifier":"com.example.apple-samplecode.UICatalog"}},"sessionId":"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C","status":0} [调试] [BaseDriver] 事件“wdaSessionStarted”记录在 1504013038184 (18:53:58 GMT+0530 (IST)) [debug] [XCUITest] 找到 WDA 派生数据 文件夹: '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs' [XCUITest] 将“555”权限设置为 '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs/Logs/Test/Attachments' 文件夹 [debug] [XCUITest] 找到 WDA 派生数据文件夹: '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-folfazwwukpzfkegdblpnfuwlvfn' [XCUITest] 将“555”权限设置为 '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-folfazwwukpzfkegdblpnfuwlvfn/Logs/Test/Attachments' 文件夹 [debug] [BaseDriver] 事件“wdaPermsAdjusted”记录在 1504013038192 (18:53:58 GMT+0530 (IST)) [调试] [BaseDriver] 事件 'wdaStarted' 记录于 1504013038193(18:53:58 GMT+0530 (IST))[调试] [XCUITest] 将初始方向设置为 'PORTRAIT' [debug] [JSONWP 代理] 代理 [POST /orientation] 到 [POST http://localhost:8100/session/43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C/orientation] with body: {"orientation":"PORTRAIT"} [debug] [JSONWP Proxy] 得到 状态为 200 的响应: {"value":{},"sessionId":"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C","status":0} [调试] [BaseDriver] 事件“orientationSet”记录在 1504013038453 (18:53:58 GMT+0530 (IST)) [Appium] 创建了新的 XCUITestDriver 会话 成功,会话 6909c363-12a5-4a21-9298-c7f750ba7e09 添加到 主会话列表 [debug] [BaseDriver] 事件 'newSessionStarted' 记录在 1504013038456 (18:53:58 GMT+0530 (IST)) [调试] [MJSONWP] 使用 driver.createSession() 结果响应客户端: {"webStorageEnabled":false,"locationContextEnabled":false,"browserName":"","platform":"MAC","javascriptEnabled":true,"databaseEnabled":false,"takesScreenshot":true,"networkConnectionEnabled": false,"app":"src/test/resources/executor/UICatalog.app","maxTypingFrequency":"120","newCommandTimeout":0,"platformVersion":"10.3","automationName":"XCUITest", "platformName":"iOS","udid":"0A41ECE4-6D03-4FEA-A82A-858FDBA6620E","deviceName":"iPhone 6"} [HTTP] GET /wd/hub/session/6909c363-12a5-4a21-9298-c7f750ba7e09 {} [调试] [MJSONWP] 使用 args 调用 AppiumDriver.getSession(): [“6909c363-12a5-4a21-9298-c7f750ba7e09”] [调试] [XCUITest] 执行 命令 'getSession' [debug] [JSONWP Proxy] 代理 [GET /] 到 [GET http://localhost:8100/session/43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C] 没有正文 [调试] [JSONWP 代理] 得到状态为 200 的响应:“{\n \"value\" : {\n \"sessionId\" : \"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C\",\n \"功能\" : {\n \"device\" : \"iphone\",\n \"browserName\" : \"UICatalog\",\n
\"sdkVersion\" : \"10.3.1\",\n \"CFBundleIdentifier\" : \"com.example.apple-samplecode.UICatalog\"\n }\n },\n \"sessionId\" : \"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C\",\n \"status\" : 0\n}" [XCUITest] 将 WDA 上限合并到 Appium 上限 会话详细信息响应 [debug] [MJSONWP] 响应客户端 driver.getSession() 结果: {"udid":"","app":"src/test/resources/executor/UICatalog.app","maxTypingFrequency":120,"newCommandTimeout":0,"platformVersion":"10.3","automationName": "XCUITest","platformName":"iOS","deviceName":"iPhone 6","device":"iphone","browserName":"UICatalog","sdkVersion":"10.3.1","CFBundleIdentifier":"com.example.apple-samplecode.UICatalog"} [HTTP] 获取 /wd/hub/session/6909c363-12a5-4a21-9298-c7f750ba7e09 {} [调试] [MJSONWP] 使用 args 调用 AppiumDriver.getSession(): [“6909c363-12a5-4a21-9298-c7f750ba7e09”] [调试] [XCUITest] 执行 命令 'getSession' [debug] [JSONWP Proxy] 代理 [GET /] 到 [GET http://localhost:8100/session/43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C] 没有正文 [调试] [JSONWP 代理] 得到状态为 200 的响应:“{\n \"value\" : {\n \"sessionId\" : \"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C\",\n \"功能\" : {\n \"device\" : \"iphone\",\n \"browserName\" : \"UICatalog\",\n
\"sdkVersion\" : \"10.3.1\",\n \"CFBundleIdentifier\" : \"com.example.apple-samplecode.UICatalog\"\n }\n },\n \"sessionId\" : \"43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C\",\n \"status\" : 0\n}" [XCUITest] 将 WDA 上限合并到 Appium 上限 会话详细信息响应 [debug] [MJSONWP] 响应客户端 driver.getSession() 结果: {"udid":"","app":"src/test/resources/executor/UICatalog.app","maxTypingFrequency":120,"newCommandTimeout":0,"platformVersion":"10.3","automationName": "XCUITest","platformName":"iOS","deviceName":"iPhone 6","device":"iphone","browserName":"UICatalog","sdkVersion":"10.3.1","CFBundleIdentifier":"com.example.apple-samplecode.UICatalog"} [HTTP] POST /wd/hub/session/6909c363-12a5-4a21-9298-c7f750ba7e09/位置 {"location":{"altitude":0,"latitude":20.672267,"hCode":1751403001,"class":"org.openqa.selenium.html5.Location","longitude":83.1649}} [调试] [MJSONWP] 使用 args 调用 AppiumDriver.setGeoLocation(): [{"altitude":0,"latitude":20.672267,"hCode":1751403001,"class":"org.openqa.selenium.html5.Location","longitude":83.1649},"6909c363-12a5-4a21- 9298-c7f750ba7e09"] [调试] [XCUITest] 执行命令 'setGeoLocation' [HTTP] 删除 /wd/hub/session/6909c363-12a5-4a21-9298-c7f750ba7e09 {} [调试] [MJSONWP] 使用 args 调用 AppiumDriver.deleteSession(): ["6909c363-12a5-4a21-9298-c7f750ba7e09"] [调试] [BaseDriver] 事件 'quitSessionRequested' 记录在 1504013038955 (18:53:58 GMT+0530 (IST)) [调试] [JSONWP 代理] 代理 [删除 /session/6909c363-12a5-4a21-9298-c7f750ba7e09] 到 [删除 http://localhost:8100/session/43710C7E-2FDE-4A35-A2E0-4D309EE2CE9C] 没有正文 [调试] [JSONWP 代理] 得到状态为 200 的响应:“{\n \"value\" : {\n\n },\n \"sessionId\" : \"28E97E0B-DF47-4325-8991-A28B77134EDB\",\n \"状态\" : 0\n}" [XCUITest] 关闭子进程 [XCUITest] 关闭 xcodebuild 进程 (pid 37304) [XCUITest] xcodebuild 退出并带有代码 'null' 和信号 'SIGTERM' [debug] [XCUITest] 找到 WDA 派生数据 文件夹: '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs' [XCUITest] 将“755”权限设置为 '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs/Logs/Test/Attachments' 文件夹 [debug] [XCUITest] 找到 WDA 派生数据文件夹: '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-folfazwwukpzfkegdblpnfuwlvfn' [XCUITest] 将“755”权限设置为 '/Users/omprakash.mishra/Library/Developer/Xcode/DerivedData/WebDriverAgent-folfazwwukpzfkegdblpnfuwlvfn/Logs/Test/Attachments' 文件夹 [debug] [XCUITest] 不清除日志文件。采用 clearSystemFiles 开启能力。 [调试] [iOSLog] 停止 iOS 日志捕获 [Appium] 删除会话 来自我们的主会话列表的 6909c363-12a5-4a21-9298-c7f750ba7e09 [调试] [BaseDriver] 事件“quitSessionFinished”记录在 1504013039408 (18:53:59 GMT+0530 (IST)) [调试] [MJSONWP] 收到 response: null [debug] [MJSONWP] 但是删除会话,所以不 返回 [debug] [MJSONWP] 响应客户端 driver.deleteSession() 结果:null [HTTP]

【问题讨论】:

  • 为什么用 Android 标记问题?和Java?作为 Java 和 Android 开发人员,我需要用它做什么?
  • @VladMatvienko 实际上是 OP 尝试使用 selenium Java 在 AndroidiOS 设备上进行自动化。这就是为什么..:)
  • @Omi 当您在Location location = new Location(latitude, longitude, altitude); driver.setLocation(location); 中遇到异常时,您的 appium 服务器日志会读取什么内容?
  • @nullpointer - 我已经编辑了我的问题并添加了 Appium 日志,请检查一次。
  • @Omi 我希望除了这些调试之外会有更多的日志。当您尝试执行 iOS 代码时,请分享事件的完整日志。

标签: java ios geolocation appium


【解决方案1】:

这个 AppleScript 可以工作。

public static void setLocation(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 static String simulatorAppName() {
    return "Simulator";
}

【讨论】:

    【解决方案2】:

    看来您需要一个 AppiumDriver。 根据this评论。

    【讨论】:

      【解决方案3】:

      您可以使用setLocation方法在Android模拟器或iOS模拟器中设置经纬度:

      导入 org.openqa.selenium.html5.Location;

      位置 loc = new Location(20.0, 12.5, 1000); // 纬度、经度、高度 driver.setLocation(loc);

      【讨论】:

      • 但它仍然没有在 Android 模拟器中设置位置
      【解决方案4】:

      我同意使用苹果脚本为 iOS 模拟器设置自定义地理位置的解决方案,因为 Appium 不支持 iOS 的这种方法(Apple 没有为 XCTest 框架提供 API 来模拟 GPS 位置)

      苹果脚本:

      #!/usr/bin/env bash
      
      osascript -e 'tell application "System Events"
          tell process "Simulator"
              set frontmost to true
              click menu item "Custom Location…" of menu of menu item "Location" of menu "Debug" of menu bar 1
              set popup to window "Custom Location"
              set value of text field 1 of popup to (system attribute "Latitude")
              set value of text field 2 of popup to (system attribute "Longitude")
              click button "OK" of popup
          end tell
      end tell'
      

      我正在使用 python,所以这是我的 Android 和 iOS 解决方案:

          def set_geo_location(self, latitude, longitude, altitude):
      
          logging.info("set geo location")
          try:
              # Currently Apple does not provide any API for XCTest framework to simulate GPS location
              self.driver.set_location(latitude=latitude, longitude=longitude, altitude=altitude)
          except WebDriverException:
              # this will launch Apple Script to automatically set custom GPS location on iOS simulator
              subprocess.call([os.path.join(PROJECT_ROOT, "set_geolocation_for_iOS.sh")],
                              env={"Latitude": latitude, "Longitude": longitude})  # bash cli command for iOS simulator
          sleep(2)
      

      我正在将 GPS 坐标传递给该方法:

      set_geo_location("-77.85", "166.66", "10")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-17
        • 1970-01-01
        • 2016-08-13
        • 2020-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多