【问题标题】:Always Allow Geolocation in Firefox using Selenium使用 Selenium 在 Firefox 中始终允许地理定位
【发布时间】:2013-04-23 22:40:41
【问题描述】:

我正在使用 Selenium 为 Web 应用程序创建一些端到端测试。

我正在使用 Python 并使用 Firefox 驱动程序

driver = webdriver.Firefox()

问题是我的网络应用程序使用 HTML5 地理定位,而且似乎每次我运行测试时,我都必须点击 Firefox 中的“允许位置”弹出窗口,这使得我的测试不太自动化。

有没有办法强制 Selenium Firefox 驱动程序始终允许地理定位而不提示?

【问题讨论】:

  • 不确定 -proper- 解决方案,但是如果您知道弹出窗口何时出现(即它不会意外出现),那么您可能可以使用 win32ole send_keys 解决此问题..并在弹出时按Enter ;)

标签: python selenium geolocation


【解决方案1】:

手动允许一次然后让 python 完成这项工作就足够了吗?

因为您可以通过在 Firefox 的网站属性中进行设置来轻松地允许:

【讨论】:

    【解决方案2】:

    您可以强制浏览器在没有权限请求的情况下返回一些预定义的位置。

    只需执行以下 JavaScript 代码:

    "navigator.geolocation.getCurrentPosition = function(success) { success({coords: {latitude: 50.455755, longitude: 30.511565}}); }"
    

    在 Firefox 和 Chrome 中测试。

    【讨论】:

    • 这当然对我有用,它允许其余的测试通过。但是,它只是绕过了运行真正进行地理定位的测试的能力。
    • 有效! (在 Firefox 25.0.1 上测试)
    【解决方案3】:

    我相信默认设置是使用新的匿名配置文件启动 Firefox。您可以使用 -Dwebdriver.firefox.profile=whatever 启动 selenium,其中“whatever”是您启动 firefox -P 时配置文件的名称。

    为了确保持久登录和其他 cookie 没有异常:

    • 使用“firefox -P”启动 Firefox
    • 选择用于启动测试的配置文件
    • 编辑 -> 首选项 -> 隐私,选择使用自定义历史设置
    • 告诉 Firefox 在“我关闭 Firefox”之前保留 cookie

    【讨论】:

      【解决方案4】:

      这是来自上述答案之一的更精致的答案。这会在执行地理定位成功回调之前增加一些超时,因为通常 JavaScript 的编写方式是在返回事件循环的一个周期之前,地理坐标坐标不可用。

      这还允许通过 Web 控制台跟踪欺骗。

      SPOOF_LOCATION_JS = """
      (function() {
      console.log('Preparing geo spoofing');
      navigator.geolocation.getCurrentPosition = function(success) {
          console.log("getCurrentPosition() called");
          setTimeout(function() { console.log("Sending out fake coordinates"); success({coords: {latitude: 50.455755, longitude: 30.511565}}); }, 500);
      };
      console.log("Finished geospoofing")})();
      """
      
      
      browser.evaluate_script(SPOOF_LOCATION_JS.replace("\n", " "))
      

      【讨论】:

        【解决方案5】:

        因为在提出这个问题将近 3 年后,我遇到了同样的问题,并且以上答案都没有让我满意。我喜欢展示我使用的解决方案。

        所以我在this blog找到了答案。

        并以这种方式在我的 python 代码中使用它:

        @classmethod
        def setUpClass(cls):
            cls.binary = FirefoxBinary(FF_BINARY_PATH)
            cls.profile = FirefoxProfile()
            cls.profile.set_preference("geo.prompt.testing", True)
            cls.profile.set_preference("geo.prompt.testing.allow", True)
            cls.profile.set_preference('geo.wifi.uri', GEOLOCATION_PATH)
            cls.driver = Firefox(firefox_binary=cls.binary, firefox_profile=cls.profile)
        

        GEOLOCATION_PATH 上是我到JSON 文件的路径:

        {
            "status": "OK",
            "accuracy": 10.0,
            "location": {
                "lat": 50.850780,
                "lng": 4.358138,
                "latitude": 50.850780,
                "longitude": 4.358138,
                "accuracy": 10.0
            }
        }
        

        【讨论】:

        • 这在经过一些调整后起作用:在 Linux 上,我必须指定像“file:///home/user/mylocation.json”这样的路径。此外,JSON 可以更简单,即:{"location":{"lat":42.650515,"lng":-72.829819},"accuracy":5}(参见此处:developers.google.com/maps/documentation/geolocation/…
        【解决方案6】:

        今天偶然发现了这个问题,我知道应该有一种简单快捷的方法来解决这个问题。以下是我的解决方法:

        1. 创建将由 Selenium 使用的新 Firefox 配置文件。您可以通过键入about:profiles 然后单击“创建新配置文件”来完成。可以在Mozilla's docs 中找到分步说明。
        2. 前往需要权限的站点并等待它要求您授予权限。授予他们并选中“记住此决定”框。
        3. 您需要知道配置文件的存储位置,以便 Selenium 可以使用它。您可以在about:profiles 中找到该位置。在这里,我创建了一个“example_profile”,然后复制了“根目录”路径:

        4. 然后,您可以在实例化 Firefox 浏览器时将路径作为参数传递,如下所示:

          root_directory_path = "/.../Firefox/Profiles/loeiok2p.example_profile"
          driver = webdriver.Firefox(firefox_profile=root_directory_path)
          

        Selenium 应使用具有授予权限的配置文件,并且弹出窗口不应再次出现。

        【讨论】:

          【解决方案7】:

          以上方法都不适合我,但确实如此:

          得到答复:https://security.stackexchange.com/questions/147166/how-can-you-fake-geolocation-in-firefox

          from selenium import webdriver
          
          profile = webdriver.FirefoxProfile()
          
          profile.set_preference("geo.prompt.testing", True)
          profile.set_preference("geo.prompt.testing.allow", True)
          profile.set_preference('geo.wifi.uri',
                                 'data:application/json,{"location": {"lat": 40.7590, "lng": -73.9845}, "accuracy": 27000.0}')
          
          
          driver = webdriver.Firefox(firefox_profile=profile)
          
          driver.get('https://www.where-am-i.net/')
          

          【讨论】:

            【解决方案8】:

            我正在使用带有 Selenium/Python 3.141.0 的 Firefox 74.0,以下将我置于 NYC

            profile = FirefoxProfile()
            profile.set_preference("geo.prompt.testing", True)
            profile.set_preference("geo.prompt.testing.allow", True)
            profile.set_preference("geo.provider.testing", True)
            "geo.provider.network.url", "data:application/json,{"location": {"lat": 40.7590, "lng": -73.9845}, "accuracy": 27000.0}")
            

            【讨论】:

              【解决方案9】:

              截至撰写本文时(4 月 20 日),这个问题已经有将近 7 年的历史了,但随着 API 的变化,它仍然具有相关性。我在使用 Selenium 编写功能测试时遇到了类似的问题。

              例如,规范Mozilla example 中可能出现的场景:

              • 浏览器不支持地理定位 (!navigator.geolocation)
              • 支持地理定位 (getCurrentPosition(success, error))
                • 拒绝访问地理位置 (error)
                • 允许访问地理位置 (success)

              以下是这些场景如何转换为 Selenium 设置:

              from selenium import webdriver
              
              # geolocation API not supported
              geoDisabled = webdriver.FirefoxOptions()
              geoDisabled.set_preference("geo.enabled", False)
              browser = webdriver.Firefox(options=geoDisabled)
              

              为了在启用地理的浏览器的提示中模拟“不允许”单击的路径(默认情况下启用,通过about:config检查):

              # geolocation supported but denied
              geoBlocked = webdriver.FirefoxOptions()
              geoBlocked.set_preference("geo.prompt.testing", True)
              geoBlocked.set_preference("geo.prompt.testing.allow", False)
              browser = webdriver.Firefox(options=geoBlocked)
              

              最后,模拟“允许位置访问”点击

              # geolocation supported, allowed and location mocked
              geoAllowed = webdriver.FirefoxOptions()
              geoAllowed.set_preference('geo.prompt.testing', True)
              geoAllowed.set_preference('geo.prompt.testing.allow', True)
              geoAllowed.set_preference('geo.provider.network.url',
                  'data:application/json,{"location": {"lat": 51.47, "lng": 0.0}, "accuracy": 100.0}')
              browser = webdriver.Firefox(options=geoAllowed)
              

              geo.wifi.uri 属性似乎不再存在,而是改为geo.provider.network.url。该解决方案还可以防止从磁盘加载“随机” Firefox 配置文件,或者在运行时执行 JS 代码来模拟该位置。浏览器配置是通过“选项”(与此解决方案一样)、“配置文件”还是通过"DesiredCapabilities" 设置的,这在很大程度上无关紧要。我发现 Options 是最简单的。

              【讨论】:

              • 要使用特定的所需功能启动,请运行:capabilities = DesiredCapabilities.FIREFOX; capabilities["locationContextEnabled"] = False; browser = webdriver.Firefox(desired_capabilities=capabilities)
              猜你喜欢
              • 2023-03-23
              • 2020-12-19
              • 2010-12-20
              • 1970-01-01
              • 2016-04-05
              • 1970-01-01
              • 2021-01-09
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多