mcpField
S
SeleniumBase MCP

SeleniumBase MCP

本地服务
github.com浏览器自动化13.2k2 天前更新

关于 SeleniumBase MCP

SeleniumBase MCP 是面向开发者和测试团队的 Python 浏览器自动化、抓取与测试框架。其 CDP Mode 提供隐蔽浏览器操作选项和 CAPTCHA 处理功能。

主要功能

  1. 01CDP Mode 浏览器自动化
  2. 02针对反机器人检测的隐蔽选项
  3. 03CAPTCHA 处理
  4. 04网页抓取
  5. 05基于 pytest 的端到端测试

适用场景

  1. 01自动执行浏览器交互
  2. 02抓取网页列表内容
  3. 03使用 pytest 测试 Web 应用

MCP 相关

README 提及 SeleniumBase MCP 并链接到 MCP,但未说明向 MCP 客户端开放哪些能力。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"seleniumbase-seleniumbase": {
"command": "uvx",
"args": [
"seleniumbase"
]
}
}
}
启动命令uvx seleniumbase

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiseleniumbase4.56.4

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

📊 SeleniumBase

一个框架,适用于浏览器自动化、网页抓取和测试。

包含用于绕过机器人检测和 CAPTCHA 的隐身选项。

PyPI 版本 SeleniumBase GitHub Actions SeleniumBase 文档 SeleniumBase README 配图 SeleniumBase PyPI 下载量
YouTube 频道 SeleniumBase Facebook 粉丝 SeleniumBase X 粉丝 README 配图 星标数

seleniumbase%2SeleniumBase | Trendshift

🚀 开始 | 🏰 功能 | 🎛️ 选项 | 📚 示例 | 💻 脚本 | 🗾 区域设置
📗 API | 📘 隐身 API | 🔠 设计模式 | 🔴 录制器 | 📊 仪表板
🎖️ 图形界面 | 📰 测试页面 | 👤 UC 模式 | 🐙 CDP 模式 | 📶 图表 | 🖥️ 设备农场
👁️ 原理 | 🚝 迁移 | 🎭 隐身 Playwright | 🛂 MasterQA | 🚎 导览
🤖 MCP | 🟨 JS 管理器 | 🌏 翻译器 | 🎞️ 演示工具 | 🖼️ 视觉 | 🗂️ 测试计划


🥷 CDP Mode 可让浏览器自动化避开反机器人服务的检测,并为原版 Playwright 添加 隐身 功能。还包含绕过 CAPTCHA 的代码。

📚 以 "test" 开头或结尾的示例脚本专为使用 pytest 运行而设计。其他脚本可直接使用原生 python 运行。(这些脚本以 "raw" 开头,以免混淆。)


📝 这是一个使用 示例,采用 seleniumbase sb_cdp(纯 CDP 模式):
(它可同时绕过 BrowserScan 和 Sannysoft 的机器人检测)

from seleniumbase import sb_cdp

sb = sb_cdp.Chrome()
sb.goto("https://browserscan.net/bot-detection")
sb.assert_element('strong:contains("Normal")')
sb.sleep(1)
sb.goto("https://bot.sannysoft.com/")
sb.assert_element(".passed")
sb.assert_element_not_visible(".failed")
sb.sleep(1)
sb.quit()

BrowserScan 测试结果:正常
(所有 BrowserScan 机器人检测测试均已成功通过)

已成功通过所有 Sannysoft 测试
(所有 Sannysoft 机器人检测测试均已成功通过)


📝 这是另一个使用 示例,采用 seleniumbase sb_cdp(纯 CDP 模式):
(它会执行各种浏览器操作,并绕过 Cloudflare Turnstile)

from seleniumbase import sb_cdp

sb = sb_cdp.Chrome(incognito=True)
sb.goto("https://www.planetminecraft.com/account")
sb.assert_element('input[name="login"]')
sb.type('input[name="email"]', "[email protected]")
sb.type('input[name="password"]', "Fake_Password")
sb.click("input#autologin")  # The checkbox
if sb.is_element_visible("input[disabled]"):
    sb.solve_captcha()  # Enables the input
sb.assert_element_absent("input[disabled]")
sb.sleep(1.5)
sb.quit()
python raw_cdp_planetmc.py

已成功绕过 Cloudflare Turnstile

✅ sb.solve_captcha() 可处理未被自动绕过的 CAPTCHA。
(如果页面上没有 CAPTCHA 时调用,则不会发生任何操作/不起作用。)

ℹ️ sb.assert_* 方法最多等待 7 秒,以确认预期条件出现。


📝 此脚本会抓取 Hacker News 列表:

from seleniumbase import sb_cdp

sb = sb_cdp.Chrome(fast=True)
sb.goto("https://hn.algolia.com/?query=seleniumbase")
elements = sb.find_elements("div.Story_title > a")
for element in elements:
    print("* " + element.text)
python raw_cdp_yc_news.py

SeleniumBase


📝 此脚本使用 UC + CDP 模式绕过 Cloudflare 的挑战页面:

from seleniumbase import SB

with SB(uc=True, test=True, locale="en") as sb:
    sb.activate_cdp_mode()
    sb.goto("https://gitlab.com/users/sign_in")
    sb.sleep(2)
    sb.solve_captcha()
    sb.highlight('h1:contains("GitLab")')
    sb.highlight('button:contains("Sign in")')
python raw_gitlab.py

SeleniumBase


🧪 端到端测试示例位于 ./examples/。

🐙 隐身 CDP 模式示例位于 ./examples/cdp_mode/。

🎭 隐身 Playwright 示例位于 ./examples/cdp_mode/playwright/。


🌐 支持的 Chromium 浏览器的 CLI 选项

💡 可以通过命令行参数设置要使用的 Chromium 浏览器:

python SCRIPT.py --chromium  # Use the unbranded Chromium browser
python SCRIPT.py --cft  # Use Chrome-for-testing
python SCRIPT.py --edge  # Use Microsoft Edge
python SCRIPT.py --brave  # Use Brave browser

Google Chrome 是默认浏览器。如果系统上尚未安装,只有未加品牌标识的 Chromium 和 Chrome-for-Testing 会自动下载。

也可以通过方法参数设置 Chromium 浏览器,例如:cft=True、use_chromium=True、browser="edge"、browser="brave" 等。例如:

sb = sb_cdp.Chrome(use_chromium=True)

⚙️ 隐身架构流程图:
隐身架构流程图
🧪 使用 pytest 进行全面的 E2E 测试:

📝 此脚本会测试一个电子商务网站:(通过 pytest 运行):

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)  # Call pytest

class MyTestClass(BaseCase):
    def test_swag_labs(self):
        self.goto("https://www.saucedemo.com")
        self.type("#user-name", "standard_user")
        self.type("#password", "secret_sauce\n")
        self.assert_element("div.inventory_list")
        self.click('button[name*="backpack"]')
        self.click("#shopping_cart_container a")
        self.assert_text("Backpack", "div.cart_item")
        self.click("button#checkout")
        self.type("input#first-name", "SeleniumBase")
        self.type("input#last-name", "Automation")
        self.type("input#postal-code", "77123")
        self.click("input#continue")
        self.click("button#finish")
        self.assert_text("Thank you for your order!")
pytest test_get_swag.py

SeleniumBase 测试

🥷 要在 pytest 中实现隐身模式,请添加命令行选项 --uc。


📝 此脚本使用 pytest 测试另一个电子商务网站:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class CoffeeCartTest(BaseCase):
    def test_coffee_cart(self):
        self.goto("https://seleniumbase.io/coffee/")
        self.assert_title("Coffee Cart")
        self.assert_element('button:contains("Total: $0.00")')
        self.click('div[data-sb="Cappuccino"]')
        self.assert_exact_text("cart (1)", 'a[aria-label="Cart page"]')
        self.click('div[data-sb="Flat-White"]')
        self.assert_exact_text("cart (2)", 'a[aria-label="Cart page"]')
        self.click('div[data-sb="Cafe-Latte"]')
        self.assert_exact_text("cart (3)", 'a[aria-label="Cart page"]')
        self.click('a[aria-label="Cart page"]')
        self.assert_exact_text("Total: $53.00", "button.pay")
        self.click("button.pay")
        self.type("input#name", "Selenium Coffee")
        self.type("input#email", "[email protected]")
        self.click("button#submit-payment")
        self.assert_text("Thanks for your purchase.", "#app .success")
pytest test_coffee_cart.py --demo

SeleniumBase 咖啡购物车测试

(--demo 模式会减慢测试速度并突出显示操作)


📝 此脚本使用 pytest 展示多种操作:

pytest test_demo_site.py

SeleniumBase 示例

可轻松输入、点击、选择、切换、拖放等。

📚 更多脚本请参阅 SeleniumBase/examples/ 文件夹。


SeleniumBase

浏览 README:


▶️ SeleniumBase 与原始 Selenium 有何不同?(点击展开)

💡 SeleniumBase 是一个用于浏览器自动化和测试的 Python 框架。SeleniumBase 使用 Selenium/WebDriver API,并集成了 pytest、pynose 和 behave 等测试运行器,提供有序的结构、测试发现、测试执行、测试状态(例如通过、失败或跳过),以及用于更改默认设置(例如浏览器选择)的命令行选项。使用原生 Selenium 时,你需要自行设置选项解析器,以便通过命令行配置测试。

💡 SeleniumBase 的驱动管理器让你能更好地控制驱动的自动下载。(在 pytest 运行命令中使用 --driver-version=VER 指定版本。)默认情况下,如果未设置,SeleniumBase 会下载与浏览器主版本匹配的驱动版本。

💡 SeleniumBase 会自动识别 CSS 选择器和 XPath,因此你无需在命令中指定选择器类型(但也可以选择指定)。

💡 SeleniumBase 的方法通常会在一次方法调用中执行多个操作。例如,self.type(selector, text) 会执行以下操作:
1. 等待元素可见。
2. 等待元素可交互。
3. 清空文本字段。
4. 输入新文本。
5. 如果文本以 "\n" 结尾,则按下 Enter/提交。
使用原生 Selenium 时,这些操作需要多次方法调用。

💡 未设置时,SeleniumBase 会使用默认超时值:
✅ self.click("button")
使用原生 Selenium 时,如果元素需要更多时间加载,方法会立即失败(默认情况下):
❌ self.driver.find_element(by="css selector", value="button").click()
(可靠的代码胜过不可靠的代码。)

💡 SeleniumBase 允许你更改方法的显式超时值:
✅ self.click("button", timeout=10)
使用原生 Selenium 时,则需要编写更多代码:
❌ WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()
(简洁的代码胜过复杂的代码。)

💡 测试失败时,SeleniumBase 会提供清晰的错误输出。使用原生 Selenium 时,错误消息可能会变得非常杂乱。

💡 SeleniumBase 让你可以为测试生成仪表板和报告。它还会将失败测试的屏幕截图保存到 ./latest_logs/ 文件夹。原生 Selenium 开箱即用时不提供这些选项。

💡 SeleniumBase 附带用于运行测试的桌面 GUI 应用,例如适用于 pytest 的 SeleniumBase Commander,以及适用于 behave 的 SeleniumBase Behave GUI。

💡 SeleniumBase 有自己的 Recorder / Test Generator,可根据手动浏览器操作创建测试。

💡 SeleniumBase 附带用于整理测试和步骤说明的测试用例管理软件(“CasePlans”)。

💡 SeleniumBase 包含用于构建数据应用(“ChartMaker”)的工具,可从 Python 生成 JavaScript。


📚 了解编写测试的不同方式:

📗📝 这是 test_simple_login.py,它使用 BaseCase 类继承,可通过 pytest 或 pynose 运行。(使用 self.driver 访问 Selenium 的原始 driver。)

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class TestSimpleLogin(BaseCase):
    def test_simple_login(self):
        self.goto("seleniumbase.io/simple/login")
        self.type("#username", "demo_user")
        self.type("#password", "secret_pass")
        self.click('a:contains("Sign in")')
        self.assert_exact_text("Welcome!", "h1")
        self.assert_element("img#image1")
        self.highlight("#image1")
        self.click_link("Sign out")
        self.assert_text("signed out", "#top_message")

📘📝 这是 raw_login_sb.py,它使用 SB 上下文管理器。可通过纯 python 运行。(使用 sb.driver 访问 Selenium 的原始 driver。)

from seleniumbase import SB

with SB() as sb:
    sb.goto("seleniumbase.io/simple/login")
    sb.type("#username", "demo_user")
    sb.type("#password", "secret_pass")
    sb.click('a:contains("Sign in")')
    sb.assert_exact_text("Welcome!", "h1")
    sb.assert_element("img#image1")
    sb.highlight("#image1")
    sb.click_link("Sign out")
    sb.assert_text("signed out", "#top_message")

📙📝 这是 raw_login_driver.py,它使用 Driver 管理器。可通过纯 python 运行。(此 driver 是 Selenium 原始 driver 的增强版本,包含更多方法。)

from seleniumbase import Driver

driver = Driver()
try:
    driver.goto("seleniumbase.io/simple/login")
    driver.type("#username", "demo_user")
    driver.type("#password", "secret_pass")
    driver.click('a:contains("Sign in")')
    driver.assert_exact_text("Welcome!", "h1")
    driver.assert_element("img#image1")
    driver.highlight("#image1")
    driver.click_link("Sign out")
    driver.assert_text("signed out", "#top_message")
finally:
    driver.quit()

SeleniumBase 设置 Python 和 Git:

Supported Python Versions

🔵 将 Python 和 Git 添加到系统 PATH。

🔵 建议使用 Python 虚拟环境。

SeleniumBase 安装 SeleniumBase:

🔵 如何使用 pip 从 PyPI 安装 seleniumbase:

pip install seleniumbase
  • (添加 --upgrade 或 -U 以升级 SeleniumBase。)
  • (添加 --force-reinstall 以升级间接依赖包。)

🔵 如何从 GitHub 克隆版本安装 seleniumbase:

git clone https://github.com/seleniumbase/SeleniumBase.git
cd SeleniumBase/
pip install -e .

🔵 如何从 GitHub 克隆版本升级现有安装:

git pull
pip install -e .

🔵 输入 seleniumbase 或 sbase,验证 SeleniumBase 是否已成功安装:

 ___      _          _             ___              
/ __| ___| |___ _ _ (_)_  _ _ __  | _ ) __ _ ______ 
\__ \/ -_) / -_) ' \| | \| | '  \ | _ \/ _` (_-< -_)
|___/\___|_\___|_||_|_|\_,_|_|_|_\|___/\__,_/__|___|
----------------------------------------------------

╭──────────────────────────────────────────────────╮
│  * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"  │
│  *    OR:        "sbase [COMMAND] [PARAMETERS]"  │
│                                                  │
│ COMMANDS:        PARAMETERS / DESCRIPTIONS:      │
│    get / install    [DRIVER_NAME] [OPTIONS]      │
│    methods          (List common Python methods) │
│    options          (List common pytest options) │
│    behave-options   (List common behave options) │
│    gui / commander  [OPTIONAL PATH or TEST FILE] │
│    behave-gui       (SBase Commander for Behave) │
│    caseplans        [OPTIONAL PATH or TEST FILE] │
│    mkdir            [DIRECTORY] [OPTIONS]        │
│    mkfile           [FILE.py] [OPTIONS]          │
│    mkrec / codegen  [FILE.py] [OPTIONS]          │
│    recorder         (Open Recorder Desktop App.) │
│    record           (If args: mkrec. Else: App.) │
│    mkpres           [FILE.py] [LANG]             │
│    mkchart          [FILE.py] [LANG]             │
│    print            [FILE] [OPTIONS]             │
│    translate        [SB_FILE.py] [LANG] [ACTION] │
│    convert          [WEBDRIVER_UNITTEST_FILE.py] │
│    extract-objects  [SB_FILE.py]                 │
│    inject-objects   [SB_FILE.py] [OPTIONS]       │
│    objectify        [SB_FILE.py] [OPTIONS]       │
│    revert-objects   [SB_FILE.py] [OPTIONS]       │
│    encrypt / obfuscate                           │
│    decrypt / unobfuscate                         │
│    proxy            (Start a basic proxy server) │
│    download server  (Get Selenium Grid JAR file) │
│    grid-hub         [start|stop] [OPTIONS]       │
│    grid-node        [start|stop] --hub=[HOST/IP] │
│                                                  │
│ *  EXAMPLE => "sbase get chromedriver stable"    │
│ *  For command info => "sbase help [COMMAND]"    │
│ *  For info on all commands => "sbase --help"    │
╰──────────────────────────────────────────────────╯
🔵 下载 WebDriver:

✅ SeleniumBase 会根据需要自动下载 WebDriver,例如 chromedriver。

▶️ 以下是下载 chromedriver 的示例输出。(点击展开)
*** Getting chromedriver 154.0.8037.57 (Latest Stable)

Downloading chromedriver-mac-arm64.zip from:
https://storage.googleapis.com/chrome-for-testing-public/154.0.8037.57/mac-arm64/chromedriver-mac-arm64.zip ...
Download Complete!

Extracting ['chromedriver'] from chromedriver-mac-arm64.zip ...
Unzip Complete!

The file [chromedriver] was saved to:
~/github/SeleniumBase/seleniumbase/drivers/
chromedriver

[chromedriver 154.0.8037.57] is ready for use!

SeleniumBase 基本示例 / 用法:

🔵 如果你已克隆 SeleniumBase,可以运行 examples/ 文件夹中的测试。

这是 my_first_test.py:

cd examples/
pytest my_first_test.py

SeleniumBase 测试

以下是 my_first_test.py 的完整代码:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class MyTestClass(BaseCase):
    def test_swag_labs(self):
        self.goto("https://www.saucedemo.com")
        self.type("#user-name", "standard_user")
        self.type("#password", "secret_sauce\n")
        self.assert_element("div.inventory_list")
        self.assert_exact_text("Products", "span.title")
        self.click('button[name*="backpack"]')
        self.click("#shopping_cart_container a")
        self.assert_exact_text("Your Cart", "span.title")
        self.assert_text("Backpack", "div.cart_item")
        self.click("button#checkout")
        self.type("#first-name", "SeleniumBase")
        self.type("#last-name", "Automation")
        self.type("#postal-code", "77123")
        self.click("input#continue")
        self.assert_text("Checkout: Overview")
        self.assert_text("Backpack", "div.cart_item")
        self.assert_text("29.99", "div.inventory_item_price")
        self.click("button#finish")
        self.assert_exact_text("Thank you for your order!", "h2")
        self.assert_element('img[alt="Pony Express"]')
        self.js_click("a#logout_sidebar_link")
        self.assert_element("div#login_button_container")

SeleniumBase 以下是一些常用的 SeleniumBase 方法:
self.goto(url)  # Navigate the browser window to the URL.
self.open(url)  # Same as `self.goto(url)`
self.activate_cdp_mode()  # Activate CDP Mode from UC Mode.
self.type(selector, text)  # Update the field with the text.
self.click(selector)  # Click the element with the selector.
self.click_link(link_text)  # Click the link containing text.
self.go_back()  # Navigate back to the previous URL.
self.select_option_by_text(dropdown_selector, option)
self.hover_and_click(hover_selector, click_selector)
self.drag_and_drop(drag_selector, drop_selector)
self.get_text(selector)  # Get the text from the element.
self.get_current_url()  # Get the URL of the current page.
self.get_page_source()  # Get the HTML of the current page.
self.get_attribute(selector, attribute)  # Get element attribute.
self.get_title()  # Get the title of the current page.
self.switch_to_frame(frame)  # Switch into the iframe container.
self.switch_to_default_content()  # Leave the iframe container.
self.open_new_window()  # Open a new window in the same browser.
self.switch_to_window(window)  # Switch to the browser window.
self.switch_to_default_window()  # Switch to the original window.
self.get_new_driver(OPTIONS)  # Open a new driver with OPTIONS.
self.switch_to_driver(driver)  # Switch to the browser driver.
self.switch_to_default_driver()  # Switch to the original driver.
self.wait_for_element(selector)  # Wait until element is visible.
self.is_element_visible(selector)  # Return element visibility.
self.is_text_visible(text, selector)  # Return text visibility.
self.sleep(seconds)  # Do nothing for the given amount of time.
self.save_screenshot(name)  # Save a screenshot in .png format.
self.assert_element(selector)  # Verify the element is visible.
self.assert_text(text, selector)  # Verify text in the element.
self.assert_exact_text(text, selector)  # Verify text is exact.
self.assert_title(title)  # Verify the title of the web page.
self.assert_downloaded_file(file)  # Verify file was downloaded.
self.assert_no_404_errors()  # Verify there are no broken links.
self.assert_no_js_errors()  # Verify there are no JS errors.

🔵 SeleniumBase 方法的完整列表,请参阅:方法摘要

SeleniumBase 趣闻 / 了解更多:

✅ SeleniumBase 会自动处理常见的 WebDriver 操作,例如在测试前启动 Web 浏览器、在测试失败时保存屏幕截图,以及在测试后关闭 Web 浏览器。

✅ SeleniumBase 支持通过命令行选项自定义测试。

✅ SeleniumBase 使用简洁的命令语法。例如:

self.type("input", "dogs\n")  # (The "\n" presses ENTER)

大多数 SeleniumBase 脚本都可以通过 pytest、pynose 或纯 python 运行。并非所有测试运行器都能运行所有测试格式。例如,使用 sb pytest fixture 的测试只能通过 pytest 运行。(参见 语法格式。)此外,还有一种 Gherkin 测试格式,可通过 behave 运行。

pytest coffee_cart_tests.py --rs
pytest test_sb_fixture.py --demo
pytest test_suite.py --rs --html=report.html --dashboard

pynose basic_test.py --mobile
pynose test_suite.py --headless --report --show-report

python raw_sb.py
python raw_test_scripts.py

behave realworld.feature
behave calculator.feature -D rs -D dashboard

✅ pytest 支持自动发现测试。如果你没有指定要运行的具体文件或文件夹,pytest 会根据以下规则自动搜索所有子目录中的测试:

  • 以 test_ 开头或以 _test.py 结尾的 Python 文件。
  • 以 test_ 开头的 Python 方法。

如果存在 SeleniumBase 的 pytest.ini 文件,你可以修改默认的发现设置。Python 类名可以任意设置,因为 seleniumbase.BaseCase 继承了 unittest.TestCase,以触发自动发现。

✅ 在实际运行前,你可以进行预检,查看 pytest 会发现哪些测试:

pytest --co -q

✅ 调用 pytest 或 pynose 执行文件时,可以指定更具体的路径:

pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]

pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]

✅ 不再有不稳定的测试!SeleniumBase 方法会在与页面元素交互前自动等待其完成加载(最长等待时间有限)。

不再有不稳定的测试! ✅ SeleniumBase 支持所有主流浏览器和操作系统:

浏览器:Chrome、Edge、Firefox 和 Safari。

系统:Linux/Ubuntu、macOS 和 Windows。

✅ SeleniumBase 适用于所有主流 CI/CD 平台:

GitHub Actions integration Jenkins integration Azure integration Google Cloud integration AWS integration Your Computer

✅ SeleniumBase 包含一种名为 MasterQA 的自动化/手动混合解决方案,可在手动测试人员进行验证的同时,通过自动化加快手动测试。

✅ SeleniumBase 支持离线运行测试(前提是之前联网时已下载 WebDriver)。

✅ 如需查看 SeleniumBase 的完整功能列表,请点击此处。

SeleniumBase 演示模式 / 调试:

🔵 演示模式可帮助你了解测试正在执行的操作。如果测试运行得太快,让你看不清楚,可以在演示模式下运行测试,让浏览器在每个操作之间短暂停顿、高亮显示正在操作的页面元素,并显示断言:

pytest my_first_test.py --demo

🔵 可以使用 time.sleep(seconds) 让测试在指定位置等待:

import time; time.sleep(3)  # Do nothing for 3 seconds.

🔵 使用 Python 内置的 pdb 库进入调试模式,帮助你调试测试:

breakpoint()  # Shortcut for "import pdb; pdb.set_trace()"

(pdb 命令:n、c、s、u、d => next、continue、step、up、down)

🔵 若要暂停抛出异常或错误的活动测试(并在控制台进入调试模式时保持浏览器窗口打开),请将 --pdb 添加为 pytest 选项:

pytest test_fail.py --pdb

🔵 若要在调试模式下启动测试,请将 --trace 添加为 pytest 选项:

pytest test_coffee_cart.py --trace

使用 pdbp (Pdb+) 调试器运行的 SeleniumBase 测试

🔵 命令行选项:

✅ 以下是 pytest 附带的一些实用命令行选项:

-v  # Verbose mode. Prints the full name of each test and shows more details.
-q  # Quiet mode. Print fewer details in the console output when running tests.
-x  # Stop running the tests after the first failure is reached.
--html=report.html  # Creates a detailed pytest-html report after tests finish.
--co | --collect-only  # Show what tests would get run. (Without running them)
--co -q  # (Both options together!) - Do a dry run with full test names shown.
-n=NUM  # Multithread the tests using that many threads. (Speed up test runs!)
-s  # See print statements. (Should be on by default with pytest.ini present.)
--junit-xml=report.xml  # Creates a junit-xml report after tests finish.
--pdb  # If a test fails, enter Post Mortem Debug Mode. (Don't use with CI!)
--trace  # Enter Debug Mode at the beginning of each test. (Don't use with CI!)
-m=MARKER  # Run tests with the specified pytest marker.

✅ SeleniumBase 为测试提供了其他 pytest 命令行选项:

--browser=BROWSER  # (The web browser to use. Default: "chrome".)
--chrome  # (Shortcut for "--browser=chrome". On by default.)
--edge  # (Shortcut for "--browser=edge".)
--firefox  # (Shortcut for "--browser=firefox".)
--safari  # (Shortcut for "--browser=safari".)
--opera  # (Shortcut for "--browser=opera".)
--brave  # (Shortcut for "--browser=brave".)
--comet  # (Shortcut for "--browser=comet".)
--chromium  # (Shortcut for using base `Chromium`)
--settings-file=FILE  # (Override default SeleniumBase settings.)
--env=ENV  # (Set the test env. Access with "self.env" in tests.)
--account=STR  # (Set account. Access with "self.account" in tests.)
--data=STRING  # (Extra test data. Access with "self.data" in tests.)
--var1=STRING  # (Extra test data. Access with "self.var1" in tests.)
--var2=STRING  # (Extra test data. Access with "self.var2" in tests.)
--var3=STRING  # (Extra test data. Access with "self.var3" in tests.)
--variables=DICT  # (Extra test data. Access with "self.variables".)
--user-data-dir=DIR  # (Set the Chrome user data directory to use.)
--protocol=PROTOCOL  # (The Selenium Grid protocol: http|https.)
--server=SERVER  # (The Selenium Grid server/IP used for tests.)
--port=PORT  # (The Selenium Grid port used by the test server.)
--cap-file=FILE  # (The web browser's desired capabilities to use.)
--cap-string=STRING  # (The web browser's desired capabilities to use.)
--proxy=SERVER:PORT  # (Connect to a proxy server:port as tests are running)
--proxy=USERNAME:PASSWORD@SERVER:PORT  # (Use an authenticated proxy server)
--proxy-bypass-list=STRING # (";"-separated hosts to bypass, Eg "*.foo.com")
--proxy-pac-url=URL  # (Connect to a proxy server using a PAC_URL.pac file.)
--proxy-pac-url=USERNAME:PASSWORD@URL  # (Authenticated proxy with PAC URL.)
--proxy-driver  # (If a driver download is needed, will use: --proxy=PROXY.)
--multi-proxy  # (Allow multiple authenticated proxies when multi-threaded.)
--agent=STRING  # (Modify the web browser's User-Agent string.)
--mobile  # (Use the mobile device emulator while running tests.)
--metrics=STRING  # (Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio".)
--chromium-arg="ARG=N,ARG2"  # (Set Chromium args, ","-separated, no spaces.)
--firefox-arg="ARG=N,ARG2"  # (Set Firefox args, comma-separated, no spaces.)
--firefox-pref=SET  # (Set a Firefox preference:value set, comma-separated.)
--extension-zip=ZIP  # (Load a Chrome Extension .zip|.crx, comma-separated.)
--extension-dir=DIR  # (Load a Chrome Extension directory, comma-separated.)
--disable-features="F1,F2"  # (Disable features, comma-separated, no spaces.)
--binary-location=PATH  # (Set path of the Chromium browser binary to use.)
--driver-version=VER  # (Set the chromedriver or uc_driver version to use.)
--sjw  # (Skip JS Waits for readyState to be "complete" or Angular to load.)
--wfa  # (Wait for AngularJS to be done loading after specific web actions.)
--pls=PLS  # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
--headless  # (The default headless mode. Linux uses this mode by default.)
--headless1  # (Use Chrome's old headless mode. Fast, but has limitations.)
--headless2  # (Use Chrome's new headless mode, which supports extensions.)
--headed  # (Run tests in headed/GUI mode on Linux OS, where not default.)
--xvfb  # (Run tests using the Xvfb virtual display server on Linux OS.)
--xvfb-metrics=STRING  # (Set Xvfb display size on Linux: "Width,Height".)
--locale=LOCALE_CODE  # (Set the Language Locale Code for the web browser.)
--interval=SECONDS  # (The autoplay interval for presentations & tour steps)
--start-page=URL  # (The starting URL for the web browser when tests begin.)
--archive-logs  # (Archive existing log files instead of deleting them.)
--archive-downloads  # (Archive old downloads instead of deleting them.)
--time-limit=SECONDS  # (Safely fail any test that exceeds the time limit.)
--fast  # (Run the automation at full speed. May impact stealth.)
--slow  # (Slow down the automation. Faster than using Demo Mode.)
--demo  # (Slow down and visually see test actions as they occur.)
--demo-sleep=SECONDS  # (Set the wait time after Slow & Demo Mode actions.)
--highlights=NUM  # (Number of highlight animations for Demo Mode actions.)
--message-duration=SECONDS  # (The time length for Messenger alerts.)
--check-js  # (Check for JavaScript errors after page loads.)
--ad-block  # (Block some types of display ads from loading.)
--host-resolver-rules=RULES  # (Set host-resolver-rules, comma-separated.)
--block-images  # (Block images from loading during tests.)
--do-not-track  # (Indicate to websites that you don't want to be tracked.)
--verify-delay=SECONDS  # (The delay before MasterQA verification checks.)
--ee | --esc-end  # (Lets the user end the current test via the ESC key.)
--recorder  # (Enables the Recorder for turning browser actions into code.)
--rec-sb-mgr  # (A Recorder Mode that generates SB() context manager code.)
--rec-sb-cdp  # (A Recorder Mode that generates Pure CDP Mode sb_cdp code.)
--rec-behave  # (Same as Recorder Mode, but also generates behave-gherkin.)
--rec-sleep  # (If the Recorder is enabled, also records self.sleep calls.)
--rec-print  # (If the Recorder is enabled, prints output after tests end.)
--disable-cookies  # (Disable Cookies on websites. Pages might break!)
--disable-js  # (Disable JavaScript on websites. Pages might break!)
--disable-csp  # (Disable the Content Security Policy of websites.)
--disable-ws  # (Disable Web Security on Chromium-based browsers.)
--enable-ws  # (Enable Web Security on Chromium-based browsers.)
--enable-sync  # (Enable "Chrome Sync" on websites.)
--uc | --undetected  # (Use undetected-chromedriver to evade bot-detection.)
--uc-cdp-events  # (Capture CDP events when running in "--undetected" mode.)
--log-cdp  # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
--remote-debug  # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--ftrace | --final-trace  # (Debug Mode after each test. Don't use with CI!)
--dashboard  # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
--dash-title=STRING  # (Set the title shown for the generated dashboard.)
--enable-3d-apis  # (Enables WebGL and 3D APIs.)
--swiftshader  # (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
--incognito  # (Enable Chrome's Incognito mode.)
--guest  # (Enable Chrome's Guest mode.)
--dark  # (Enable Chrome's Dark mode.)
--devtools  # (Open Chrome's DevTools when the browser opens.)
--rs | --reuse-session  # (Reuse browser session for all tests.)
--rcs | --reuse-class-session  # (Reuse session for tests in class.)
--crumbs  # (Delete all cookies between tests reusing a session.)
--disable-beforeunload  # (Disable the "beforeunload" event on Chrome.)
--window-position=X,Y  # (Set the browser's starting window position.)
--window-size=WIDTH,HEIGHT  # (Set the browser's starting window size.)
--maximize  # (Start tests with the browser window maximized.)
--screenshot  # (Save a screenshot at the end of each test.)
--no-screenshot  # (No screenshots saved unless tests directly ask it.)
--visual-baseline  # (Set the visual baseline for Visual/Layout tests.)
--external-pdf  # (Set Chromium "plugins.always_open_pdf_externally":True.)
--timeout-multiplier=MULTIPLIER  # (Multiplies the default timeout values.)
--list-fail-page  # (After each failing test, list the URL of the failure.)

(查看完整的命令行选项定义列表,请点击**此处**。有关命令行选项的详细示例,请参阅 customizing_test_runs.md)


🔵 测试失败时,最近一次测试运行的日志和截图会保存到 latest_logs/ 文件夹。如果在命令行选项中添加 --archive_logs,或在 settings.py 中将 ARCHIVE_EXISTING_LOGS 设置为 True,这些日志就会移至 archived_logs/;否则,下一次测试运行开始时会清理日志文件。test_suite.py 集合中包含一些故意失败的测试,供你查看日志记录的工作方式。

cd examples/

pytest test_suite.py --chrome

pytest test_suite.py --firefox

覆盖 seleniumbase/config/settings.py 的简便方法是使用自定义设置文件。 添加到测试中的命令行选项如下:(请参阅 examples/custom_settings.py) --settings_file=custom_settings.py (设置包括默认超时值、双因素身份验证密钥、DB 凭据、S3 凭据,以及测试使用的其他重要设置。)

🔵 如需从命令行向测试传递其他数据,请添加 --data="ANY STRING"。 在测试中,你可以使用 self.data 访问这些数据。

SeleniumBase 目录配置:

🔵 使用 pytest 运行测试时,你需要在根文件夹中放置一份 pytest.ini。使用 pynose 运行测试时,你需要在根文件夹中放置一份 setup.cfg。这些文件用于指定测试的默认配置。测试文件夹中还应包含一个空白的 init.py 文件,以便测试文件可以从该文件夹导入其他文件。

🔵 sbase mkdir DIR 会创建一个包含配置文件和示例测试的文件夹:

sbase mkdir ui_tests

新建文件夹中将包含以下文件:

ui_tests/
├── __init__.py
├── my_first_test.py
├── parameterized_test.py
├── pytest.ini
├── requirements.txt
├── setup.cfg
├── test_demo_site.py
└── boilerplates/
    ├── __init__.py
    ├── base_test_case.py
    ├── boilerplate_test.py
    ├── classic_obj_test.py
    ├── page_objects.py
    ├── sb_fixture_test.py
    └── samples/
        ├── __init__.py
        ├── google_objects.py
        ├── google_test.py
        ├── sb_swag_test.py
        └── swag_labs_test.py

ProTip™: 在 sbase mkdir 命令中添加 -b 或 --basic,也可以创建一个不含示例测试的模板文件夹:

sbase mkdir ui_tests --basic

新建文件夹中将包含以下文件:

ui_tests/
├── __init__.py
├── pytest.ini
├── requirements.txt
└── setup.cfg

这些文件中,pytest.ini 配置文件最为重要,其次是空白的 __init__.py 文件。此外还有一个 setup.cfg 文件(供 pynose 使用)。最后,requirements.txt 文件可用于帮助你在环境中安装 seleniumbase(如果尚未安装)。

ProTip™: 添加 --gha,即可包含一个使用默认设置的 GitHub Actions .yml 文件:

ui_tests/
└── .github                    
    └── workflows/             
        └── python-package.yml

SeleniumBase 失败测试的日志文件:

下面来看一个失败测试的示例:

""" test_fail.py """
from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class MyTestClass(BaseCase):

    def test_find_army_of_robots_on_xkcd_desert_island(self):
        self.goto("https://xkcd.com/731/")
        self.assert_element("div#ARMY_OF_ROBOTS", timeout=1)  # This should fail

你可以在 examples/ 文件夹中按如下方式运行它:

pytest test_fail.py

🔵 你会看到系统创建了一个日志文件夹 ./latest_logs/,用于保存有关失败测试的信息(和截图)。测试运行期间,如果你在 settings.py 中将 ARCHIVE_EXISTING_LOGS 设置为 True,或者运行测试时使用 --archive-logs,之前的结果就会移至 archived_logs 文件夹。如果选择不归档现有日志,它们就会被删除,并由最近一次测试运行的日志取代。


SeleniumBase SeleniumBase 仪表板:

🔵 pytest 的 --dashboard 选项会生成一个位于 dashboard.html 的 SeleniumBase 仪表板。测试运行并生成结果时,仪表板会自动更新。示例:

pytest --dashboard --rs --headless
SeleniumBase 仪表板

🔵 此外,你还可以在自选端口上托管自己的 SeleniumBase 仪表板服务。以下是使用 Python 的 http.server 托管的示例:

python -m http.server 1948

🔵 现在,你可以访问 http://localhost:1948/dashboard.html,以 Web 应用的形式查看仪表板。这需要打开两个不同的终端窗口:一个用于运行服务,另一个用于运行测试,且测试应从同一目录运行。(使用 Ctrl+C 停止 http 服务。)

🔵 以下是 SeleniumBase 仪表板的完整示例:

pytest test_suite.py test_image_saving.py --dashboard --rs --headless
SeleniumBase 仪表板

SeleniumBase 生成测试报告:

🔵 pytest HTML 报告:

✅ 使用 --html=report.html,测试套件完成后即可生成一份美观的报告,文件名由你指定。

pytest test_suite.py --html=report.html
Pytest 报告示例

✅ 将 pytest HTML 报告与 SeleniumBase 仪表板结合使用时,仪表板中的饼图也会添加到 HTML 报告中。此外,如果在使用仪表板时将 HTML 报告 URL 设置为与仪表板 URL 相同(例如:--dashboard --html=dashboard.html),那么所有测试完成后,仪表板就会成为一份增强版 HTML 报告。

✅ 以下是增强版 HTML 报告示例:

pytest test_suite.py --dashboard --html=report.html
仪表板 Pytest HTML 报告

如果要在 Jenkins 中查看 pytest HTML 报告,你可能需要配置 Jenkins 设置,以确保 HTML 正确呈现。这是由于 Jenkins CSP 变更导致的。

你也可以使用 --junit-xml=report.xml 生成 XML 报告。Jenkins 可以使用此文件更好地展示测试报告。

pytest test_suite.py --junit-xml=report.xml
🔵 pynose 报告:

--report 选项会在测试套件完成后生成一份美观的报告。

pynose test_suite.py --report
pynose 报告示例

(注意:你可以添加 --show-report,以便在测试套件完成后立即显示 pynose 报告。仅在本地运行测试时使用 --show-report,因为它会暂停测试运行。)

🔵 behave 仪表板和报告:

(可在 examples/ 文件夹中找到 behave_bdd/ 文件夹。)

behave behave_bdd/features/ -D dashboard -D headless
SeleniumBase

你还可以使用 --junit 为每个 behave 功能生成 .xml 报告。Jenkins 可以使用这些文件,为测试提供更完善的报告。

behave behave_bdd/features/ --junit -D rs -D headless
🔵 Allure 报告:

参见:https://allurereport.org/docs/pytest/

SeleniumBase 不再将 allure-pytest 作为已安装依赖的一部分。如果要使用它,请先安装:

pip install allure-pytest

现在,你的测试可以生成 Allure 结果文件,并由 Allure Reports 处理。

pytest test_suite.py --alluredir=allure_results

SeleniumBase 使用代理服务器:

如果希望在浏览器测试(Chromium 或 Firefox)中使用代理服务器,可以在命令行中添加 --proxy=IP_ADDRESS:PORT 参数。

pytest proxy_test.py --proxy=IP_ADDRESS:PORT

如果要使用的代理服务器需要身份验证,可以按以下方式操作(仅限 Chromium):

pytest proxy_test.py --proxy=USERNAME:PASSWORD@IP_ADDRESS:PORT

SeleniumBase 还支持 SOCKS4 和 SOCKS5 代理:

pytest proxy_test.py --proxy="socks4://IP_ADDRESS:PORT"

pytest proxy_test.py --proxy="socks5://IP_ADDRESS:PORT"

为方便使用,可以将常用代理添加到 proxy_list.py 中的 PROXY_LIST,然后使用 --proxy=KEY_FROM_PROXY_LIST 来使用该键对应的 IP_ADDRESS:PORT。

pytest proxy_test.py --proxy=proxy1
SeleniumBase 更改 User-Agent:

🔵 如果希望更改浏览器测试的 User-Agent(仅限 Chromium 和 Firefox),可以在命令行中添加 --agent="USER AGENT STRING" 参数。

pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU"
SeleniumBase 处理弹出警告:

🔵 self.accept_alert() 会自动等待并接受弹出警告。self.dismiss_alert() 会自动等待并关闭弹出警告。有时,某些方法(例如 self.click(SELECTOR))可能会自行关闭弹出窗口,因为它们会调用 JavaScript,以确保页面的 readyState 为 complete 后再继续。如果你想接受以这种方式被关闭的弹出窗口,请使用以下变通方法:改为调用 self.find_element(SELECTOR).click()(这样弹出窗口就会保留在屏幕上),然后使用 self.accept_alert() 接受弹出窗口(点击此处了解更多)。如果弹出窗口并非每次都会出现,请将代码放入 try/except 块中。

SeleniumBase 为网站构建引导式导览:

🔵 了解 SeleniumBase 交互式引导(位于 examples/tour_examples/ 文件夹中)。它非常适合用于网站新手引导体验的原型设计。


SeleniumBase 生产环境与集成:
▶️ 以下是一些可用于为测试搭建生产环境的方法。(点击展开)

下面是一个启用了某些附加功能的测试运行示例:

pytest [YOUR_TEST_FILE.py] --with-db-reporting --with-s3-logging

SeleniumBase 方法详细说明和示例:

🔵 导航到网页:(及相关命令)

self.goto("https://xkcd.com/378/")  # This method opens the specified page.

self.go_back()  # This method navigates the browser to the previous page.

self.go_forward()  # This method navigates the browser forward in history.

self.refresh_page()  # This method reloads the current page.

self.get_current_url()  # This method returns the current page URL.

self.get_page_source()  # This method returns the current page source.

ProTip™:你可以将 self.get_page_source() 方法与 Python 的 find() 命令配合使用,解析 HTML 并查找特定内容。(如需更高级的解析,请参阅 BeautifulSoup 示例。)

source = self.get_page_source()
head_open_tag = source.find('<head>')
head_close_tag = source.find('</head>', head_open_tag)
everything_inside_head = source[head_open_tag+len('<head>'):head_close_tag]

🔵 点击:

要点击页面上的元素:

self.click("div#my_id")

**ProTip™:**在大多数网页浏览器中,你可以右键点击页面并选择 Inspect Element,查看创建自定义脚本所需的 CSS 选择器详细信息。

🔵 输入文本:

self.type(selector, text) # 使用指定值更新指定元素中的文本。如果元素缺失或文本字段不可编辑,则会引发异常。示例:

self.type("input#id_value", "2012")

你也可以使用 self.add_text() 或 WebDriver 的 .send_keys() 命令,但如果文本框中已有内容,它们不会先清除文本。

🔵 获取页面上某个元素的文本:

text = self.get_text("header h2")

🔵 获取页面上某个元素的属性值:

attribute = self.get_attribute("#comic img", "title")

🔵 在指定秒数内断言页面上某个元素存在:

self.wait_for_element_present("div.my_class", timeout=10)

(注意:你也可以使用:self.assert_element_present(ELEMENT))

🔵 在指定秒数内断言页面上某个元素可见:

self.wait_for_element_visible("a.my_class", timeout=5)

(注意:简写形式为 self.find_element(ELEMENT) 和 self.assert_element(ELEMENT)。find_element() 版本会返回元素。)

由于上一行会返回元素,因此你可以像下面这样将它与 .click() 结合使用:

self.find_element("a.my_class", timeout=5).click()

# But you're better off using the following statement, which does the same thing:

self.click("a.my_class")  # DO IT THIS WAY!

实用提示™: 在 CSS 选择器中,可以用点号表示类名(例如:div.class_name),这是 div[class="class_name"] 的简写形式。

你也可以像下面这样使用 *=,在 CSS 选择器中搜索任意部分值:

self.click('a[name*="partial_name"]')

🔵 在指定秒数内断言页面上某个元素中的文本可见:

self.assert_text("Make it so!", "div#trek div.picard div.quotes")
self.assert_text("Tea. Earl Grey. Hot.", "div#trek div.picard div.quotes", timeout=3)

(注意:self.find_text(TEXT, ELEMENT) 和 self.wait_for_text(TEXT, ELEMENT) 也能实现此功能。为保持向后兼容,保留了旧的方法名称,但默认超时时间可能不同。)

🔵 断言任何内容:

self.assert_true(var1 == var2)

self.assert_false(var1 == var2)

self.assert_equal(var1, var2)

🔵 实用条件语句:(附创意示例)

❓ is_element_visible(selector):(元素在页面上可见)

if self.is_element_visible('div#warning'):
    print("Red Alert: Something bad might be happening!")

❓ is_element_present(selector):(元素存在于 HTML 中)

if self.is_element_present('div#top_secret img.tracking_cookie'):
    self.contact_cookie_monster()  # Not a real SeleniumBase method
else:
    current_url = self.get_current_url()
    self.contact_the_nsa(url=current_url, message="Dark Zone Found")  # Not a real SeleniumBase method
def is_there_a_cloaked_klingon_ship_on_this_page():
    if self.is_element_present("div.ships div.klingon"):
        return not self.is_element_visible("div.ships div.klingon")
    return False

❓ is_text_visible(text, selector):(元素上的文本可见)

if self.is_text_visible("You Shall Not Pass!", "h1"):
    self.goto("https://www.youtube.com/watch?v=3xYXUeSmb-Y")
▶️ 点击查看 is_text_visible(): 的详细示例
def get_mirror_universe_captain_picard_superbowl_ad(superbowl_year):
    selector = "div.superbowl_%s div.commercials div.transcript div.picard" % superbowl_year
    if self.is_text_visible("Yes, it was I who summoned you all here.", selector):
        return "Picard Paramount+ Superbowl Ad 2020"
    elif self.is_text_visible("Commander, signal the following: Our Network is Secure!"):
        return "Picard Mirror Universe iboss Superbowl Ad 2018"
    elif self.is_text_visible("For the Love of Marketing and Earl Grey Tea!", selector):
        return "Picard Mirror Universe HubSpot Superbowl Ad 2015"
    elif self.is_text_visible("Delivery Drones... Engage", selector):
        return "Picard Mirror Universe Amazon Superbowl Ad 2015"
    elif self.is_text_visible("Bing it on Screen!", selector):
        return "Picard Mirror Universe Microsoft Superbowl Ad 2015"
    elif self.is_text_visible("OK Glass, Make it So!", selector):
        return "Picard Mirror Universe Google Superbowl Ad 2015"
    elif self.is_text_visible("Number One, I've Never Seen Anything Like It.", selector):
        return "Picard Mirror Universe Tesla Superbowl Ad 2015"
    elif self.is_text_visible("Let us make sure history never forgets the name ... Facebook", selector):
        return "Picard Mirror Universe Facebook Superbowl Ad 2015"
    elif self.is_text_visible("""With the first link, the chain is forged.
                              The first speech censored, the first thought forbidden,
                              the first freedom denied, chains us all irrevocably.""", selector):
        return "Picard Mirror Universe Wikimedia Superbowl Ad 2015"
    else:
        raise Exception("Reports of my assimilation are greatly exaggerated.")

❓ is_link_text_visible(link_text):

if self.is_link_text_visible("Stop! Hammer time!"):
    self.click_link("Stop! Hammer time!")
🔵 切换标签页:

如果测试打开了新标签页或窗口,你可以切换到该页面。(SeleniumBase 会自动切换到网址不是 about:blank 的新标签页。)

self.switch_to_window(1)  # This switches to the new tab (0 is the first one)
🔵 如何处理 iframe:

🔵 iframe 遵循与新窗口相同的原则:如果要在 iframe 中执行操作,必须先切换到该 iframe:

self.switch_to_frame("iframe")
# ... Now perform actions inside the iframe
self.switch_to_parent_frame()  # Exit the current iframe

要退出多个 iframe,请使用 self.switch_to_default_content()。(如果当前位于单个 iframe 中,则效果与 self.switch_to_parent_frame() 相同。)

self.switch_to_frame('iframe[name="frame1"]')
self.switch_to_frame('iframe[name="frame2"]')
# ... Now perform actions inside the inner iframe
self.switch_to_default_content()  # Back to the main page

🔵 你也可以使用上下文管理器在 iframe 中执行操作:

with self.frame_switch("iframe"):
    # ... Now perform actions while inside the code block
# You have left the iframe

这也适用于嵌套 iframe:

with self.frame_switch('iframe[name="frame1"]'):
    with self.frame_switch('iframe[name="frame2"]'):
        # ... Now perform actions while inside the code block
    # You are now back inside the first iframe
# You have left all the iframes
🔵 如何执行自定义 jQuery 脚本:

jQuery 是一个功能强大的 JavaScript 库,可让你在网页浏览器中执行高级操作。 如果当前网页已经加载了 jQuery,你就可以立即开始执行 jQuery 脚本。 你可以通过检查网页 HTML 中是否包含类似以下内容来确认:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>

🔵 如果网页尚未加载 jQuery,也可以在页面上使用它。首先运行以下命令即可:

self.activate_jquery()
▶️ 以下是一些在脚本中使用 jQuery 的示例。(点击展开)
self.execute_script("jQuery, window.scrollTo(0, 600)")  # Scrolling the page

self.execute_script("jQuery('#annoying-widget').hide()")  # Hiding elements on a page

self.execute_script("jQuery('#hidden-widget').show(0)")  # Showing hidden elements on a page

self.execute_script("jQuery('#annoying-button a').remove()")  # Removing elements on a page

self.execute_script("jQuery('%s').mouseover()" % (mouse_over_item))  # Mouse-over elements on a page

self.execute_script("jQuery('input#the_id').val('my_text')")  # Fast text input on a page

self.execute_script("jQuery('div#dropdown a.link').click()")  # Click elements on a page

self.execute_script("return jQuery('div#amazing')[0].text")  # Returns the css "text" of the element given

self.execute_script("return jQuery('textarea')[2].value")  # Returns the css "value" of the 3rd textarea element on the page

(上述大多数命令都可以直接通过内置的 SeleniumBase 方法完成。)

🔵 如何处理限制性 CSP:

❗ 有些网站设有严格的内容安全策略,以阻止用户向网站加载 jQuery 和其他外部库。如果你需要在这些网站上使用 jQuery 或其他 JS 库,请将 --disable-csp 添加为 pytest 命令行选项,以加载可绕过 CSP 的 Chromium 扩展。

🔵 更多 JavaScript 乐趣:
▶️ 在此示例中,JavaScript 会在页面上创建一个推荐按钮,然后点击该按钮。(点击展开)
start_page = "https://xkcd.com/465/"
destination_page = "https://github.com/seleniumbase/SeleniumBase"
self.goto(start_page)
referral_link = '''<a class='analytics test' href='%s'>Free-Referral Button!</a>''' % destination_page
self.execute_script('''document.body.innerHTML = \"%s\"''' % referral_link)
self.click("a.analytics")  # Clicks the generated button

(应广大用户要求,SeleniumBase 已加入此流量生成示例,提供 self.generate_referral(start_page, end_page) 和 self.generate_traffic(start_page, end_page, loops) 方法。)

🔵 如何使用延迟断言:

假设你想在一次测试中验证网页上的多个不同元素,但不希望在同时验证多个元素之前测试就失败,这样你就不必重新运行测试,才能找到同一页面上更多缺失的元素。这时就可以使用延迟断言。示例如下:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class DeferredAssertTests(BaseCase):
    def test_deferred_asserts(self):
        self.goto("https://xkcd.com/993/")
        self.wait_for_element("#comic")
        self.deferred_assert_element('img[alt="Brand Identity"]')
        self.deferred_assert_element('img[alt="Rocket Ship"]')  # Will Fail
        self.deferred_assert_element("#comicmap")
        self.deferred_assert_text("Fake Item", "ul.comicNav")  # Will Fail
        self.deferred_assert_text("Random", "ul.comicNav")
        self.deferred_assert_element('a[name="Super Fake !!!"]')  # Will Fail
        self.deferred_assert_exact_text("Brand Identity", "#ctitle")
        self.deferred_assert_exact_text("Fake Food", "#comic")  # Will Fail
        self.process_deferred_asserts()

deferred_assert_element() 和 deferred_assert_text() 会保存所有原本会引发的异常。 若要将所有失败的延迟断言合并为一个异常,请务必在测试方法末尾调用 self.process_deferred_asserts()。如果测试涉及多个页面,可以在导航到新页面之前调用 self.process_deferred_asserts(),这样日志文件中的截图就会与执行延迟断言时的 URL 相匹配。

🔵 如何访问原始 WebDriver:

如果需要使用标准 WebDriver 提供的任何命令,可以像这样直接调用:

self.driver.delete_all_cookies()
capabilities = self.driver.capabilities
self.driver.find_elements("partial link text", "GitHub")

(通常情况下,如果有 SeleniumBase 版本的方法,建议使用它。)

🔵 如何自动重试失败的测试:

可以使用 pytest --reruns=NUM 重试失败的测试指定次数。添加 --reruns-delay=SECONDS 可设置每次重试之间的等待秒数。示例如下:

pytest --reruns=1 --reruns-delay=1

可以使用 @retry_on_exception() 装饰器重试失败的方法。(首先导入:from seleniumbase import decorators)。如需详细了解 SeleniumBase 装饰器,请点击此处。


“在将代码部署到生产环境之前,在 QA 中捕获错误!”

在将代码部署到生产环境之前,在 QA 中捕获错误!


SeleniumBase 总结

发现问题,就及时报告!
已关闭的问题 已关闭的拉取请求

SeleniumBase

支持的 Python 版本

SeleniumBase Playlist on YouTube SeleniumBase on GitHub SeleniumBase on Discord SeleniumBase on Facebook

SeleniumBase
Tested with SeleniumBase Views
SeleniumBase Docs SeleniumBase
SeleniumBase PyPI downloads README 配图
YouTube Channel

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。