You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytest、Selenium无法模拟浏览器位置与时区,求解决方案

模拟浏览器位置与时区的实现方案(基于Selenium/Pytest/Splinter)

一、时区模拟

1. Chrome启动参数全局设置

直接通过启动参数固定时区,无需后续额外操作,适合全局生效的测试场景:

from splinter import Browser

chrome_options = {
    "args": [
        "--timezone=Asia/Shanghai",  # 传入IANA标准时区标识符
        "--disable-features=VizDisplayCompositor"  # 部分环境下需禁用该特性保证时区生效
    ]
}

browser = Browser('chrome', options=chrome_options)

2. DevTools协议动态切换时区

通过Selenium底层的CDP命令动态修改时区,支持测试过程中随时切换:

# 切换为纽约时区
browser.driver.execute_cdp_cmd(
    "Emulation.setTimezoneOverride",
    {"timezoneId": "America/New_York"}
)

# 验证时区是否生效
current_timezone = browser.evaluate_script("return Intl.DateTimeFormat().resolvedOptions().timeZone")
print(current_timezone)  # 应输出 America/New_York

二、地理位置模拟

1. 启动参数预配置固定位置

通过启动参数直接锁定地理位置,跳过浏览器权限弹窗:

chrome_options = {
    "args": [
        "--geolocation=31.2304,121.4737",  # 纬度,经度(以上海坐标为例)
        "--geolocation-fixed",  # 禁用自动地理位置检测
        "--disable-geolocation-prompt"  # 跳过位置权限请求弹窗
    ]
}

browser = Browser('chrome', options=chrome_options)

2. DevTools协议动态修改位置

支持测试流程中随时切换地理位置,灵活性更高:

# 设置纽约地理位置:纬度、经度、精度(单位米)
browser.driver.execute_cdp_cmd(
    "Emulation.setGeolocationOverride",
    {
        "latitude": 40.7128,
        "longitude": -74.0060,
        "accuracy": 100
    }
)

# 验证位置是否生效
position = browser.evaluate_script("""
    return new Promise(resolve => {
        navigator.geolocation.getCurrentPosition(pos => resolve(pos.coords));
    })
""")
print(position)  # 应输出预设的经纬度信息

三、结合Pytest与Gherkin的集成示例

1. Pytest Fixture封装复用配置

在conftest.py中定义全局浏览器fixture,统一预设时区和位置:

import pytest
from splinter import Browser

@pytest.fixture(scope="function")
def browser():
    chrome_options = {
        "args": [
            "--timezone=Europe/London",
            "--geolocation=51.5074,-0.1278",
            "--geolocation-fixed",
            "--disable-geolocation-prompt"
        ]
    }
    b = Browser('chrome', options=chrome_options)
    yield b
    b.quit()

2. Gherkin场景与步骤实现(基于pytest-bdd)

Feature: 区域化功能验证
  Scenario: 检查页面时区显示
    Given 浏览器已设置为伦敦时区
    When 打开测试页面
    Then 页面显示的时区应为 "Europe/London"

  Scenario: 验证地理位置服务
    Given 浏览器已定位到伦敦
    When 触发位置获取操作
    Then 获取到的经纬度应匹配预设值

对应步骤代码:

from pytest_bdd import given, when, then, parsers

@given("浏览器已设置为伦敦时区")
def setup_london_timezone(browser):
    browser.driver.execute_cdp_cmd(
        "Emulation.setTimezoneOverride",
        {"timezoneId": "Europe/London"}
    )

@when("打开测试页面")
def open_test_page(browser):
    browser.visit("https://your-test-domain.com/location-test")

@then(parsers.parse('页面显示的时区应为 "{expected_tz}"'))
def verify_timezone_display(browser, expected_tz):
    displayed_tz = browser.find_by_id("timezone-label").text
    assert displayed_tz == expected_tz

四、常见问题排查

  • JS模拟失效:部分网站会检测DevTools状态或限制JS修改系统级参数,优先使用启动参数或CDP原生接口,而非直接mocknavigator对象。
  • 版本兼容:确保Splinter依赖的Selenium版本为4.x及以上,旧版本对CDP命令支持有限。
  • 权限弹窗:添加--disable-geolocation-prompt启动参数可跳过位置权限请求,避免测试中断。

内容的提问来源于stack exchange,提问作者Hrithik Maurya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:26:22