我正在使用Selenium为 Web 应用程序创建一些端到端测试。
我正在使用 Python 并使用 Firefox 驱动程序
driver = webdriver.Firefox()
问题是我的网络应用程序使用 HTML5 地理定位,而且似乎每次我运行测试时,我都必须在 Firefox 中单击“允许位置”弹出窗口,这使得我的测试不太自动化。
有没有办法强制 Selenium Firefox 驱动程序始终允许地理定位而不提示?
我正在使用Selenium为 Web 应用程序创建一些端到端测试。
我正在使用 Python 并使用 Firefox 驱动程序
driver = webdriver.Firefox()
问题是我的网络应用程序使用 HTML5 地理定位,而且似乎每次我运行测试时,我都必须在 Firefox 中单击“允许位置”弹出窗口,这使得我的测试不太自动化。
有没有办法强制 Selenium Firefox 驱动程序始终允许地理定位而不提示?
您可以强制浏览器在没有权限请求的情况下返回一些预定义的位置。
只需执行以下 JavaScript 代码:
"navigator.geolocation.getCurrentPosition = function(success) { success({coords: {latitude: 50.455755, longitude: 30.511565}}); }"
在 Firefox 和 Chrome 中测试。
截至撰写本文时(4 月 20 日),这个问题已经有将近 7 年的历史了,但随着 API 的变化仍然相关。我在使用 Selenium 编写功能测试时遇到了类似的问题。
例如,规范Mozilla 示例中可能出现的场景:
!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 代码来模拟该位置。浏览器配置是通过 "Options"(如本解决方案的情况)、通过 "Profiles" 还是通过"DesiredCapabilities"设置的,这在很大程度上无关紧要。我发现选项是最简单的。
因为在提出这个问题将近 3 年之后,我遇到了同样的问题,并且以上答案都没有让我满意。我喜欢展示我使用的解决方案。
所以我在这个博客上找到了答案。
并以这种方式在我的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)
OnGEOLOCATION_PATH
是我的JSON
文件路径:
{
"status": "OK",
"accuracy": 10.0,
"location": {
"lat": 50.850780,
"lng": 4.358138,
"latitude": 50.850780,
"longitude": 4.358138,
"accuracy": 10.0
}
}
今天偶然发现了这个问题,我知道应该有一种简单快捷的方法来解决这个问题。这是我解决它的方法:
about:profiles
然后单击“创建新配置文件”来执行此操作。可以在Mozilla 的文档中找到分步说明。您需要知道您的配置文件存储在哪里,以便 Selenium 可以使用它。您可以在 中找到位置about:profiles
。这里我创建了一个“example_profile”,然后复制了“根目录”路径:
然后,您可以在实例化 Firefox 浏览器时将路径作为参数传递,如下所示:
root_directory_path = "/.../Firefox/Profiles/loeiok2p.example_profile" driver = webdriver.Firefox(firefox_profile=root_directory_path)
Selenium 应该使用具有授予权限的配置文件,并且弹出窗口不应再次出现。
我相信默认设置是使用新的匿名配置文件启动 Firefox。您可以使用 -Dwebdriver.firefox.profile=whatever 启动 selenium,其中“whatever”是您启动 firefox -P 时配置文件的名称。
为了确保持久登录和其他 cookie 没有异常:
我正在使用带有 Selenium/Python 3.141.0 的 Firefox 74.0,以下将我放在纽约市
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}")
这是来自上述答案之一的更精致的答案。这会在执行地理定位成功回调之前增加一些超时,因为通常 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", " "))
以上都没有对我有用,但这确实:
得到答案: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/')
手动允许一次然后让python完成这项工作就足够了吗?
因为您可以通过在 Firefox 的网站属性中设置它来轻松地允许: