HOWTO: Chrome带配置项启动

在使用CukeTest进行Web自动化测试时,启动的浏览器(这里以Chrome为例)是一个纯净的实例,没有任何浏览器扩展。而我们常常会对浏览器有些特殊的需求,就需要对浏览器进行配置。本文主要介绍:

  • 浏览器配置项及其在自动化测试中的配置方法
  • 配置Chrome专用用户的方案

配置方法

在JavaScript中,我们使用leanpro.web提供的API来配置这些选项;在Python中,我们使用leanproWeb中的WebAuto来配置这些选项。具体的实现如下:

配置浏览器及上下文

leanpro.webleanproWeb.WebAuto中,我们可以通过传递配置选项给chromium.launch()方法来配置浏览器,并配置浏览器上下文,例如:

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch();//配置浏览器
    const context = await browser.newContext();//配置上下文
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch() #配置浏览器
context = browser.new_context() #配置上下文

如果我们需要Chrome以最大化的状态启动,需要添加启动参数。可以在launch()newContext()中添加所需的启动参数。

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false, //禁用无头模式使测试过程中能看到浏览器;默认为true,即启用无头模式
        args: ['--start-maximized'] //启用最大化
    });
    const context = await browser.newContext({
        viewport: null //使viewport参数匹配屏幕尺寸
    });
})();
from leanproWeb import WebAuto

#禁用无头模式使测试过程中能看到浏览器;默认为true,即启用无头模式
#args中添加'--start-maximized'参数启用最大化
browser = webauto.chromium.launch(headless=False, args=["--start-maximized"])
#启用no_viewport使viewport参数匹配屏幕尺寸,相当于js中的viewport: null
context = browser.new_context(no_viewport=True)

如果还想隐身模式启动浏览器,可设置--incognito启动参数:

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false, //禁用无头模式使测试过程中能看到浏览器
        args: ['--incognito'] //使用隐身模式
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

#禁用无头模式使测试过程中能看到浏览器
#args中添加'--incognito'参数启用最大化
browser = webauto.chromium.launch(headless=False, args=["--incognito"])
context = browser.new_context()

常用配置项

Chrome的配置项非常多,添加启动参数属于比较简单的配置,另外还可以配置浏览器的功能和偏好(Preference)、可执行文件路径、代理等。

常用启动参数

可以配置的启动参数非常多,完整版的可以访问此网站。但是这里我们只列举常用的一些参数配置方法。

设置无头模式

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({headless: true});
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=True)
context = browser.new_context()

控制回放速度

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        slowMo: 1000
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False, slow_mo=1000)
context = browser.new_context()

禁用GPU加速

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        args: ['--disable-gpu']
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False, args=['--disable-gpu'])
context = browser.new_context()

隐藏滚动条(应对一些特殊页面)

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        args: ['--hide-scrollbars']
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False, args=['--hide-scrollbars'])
context = browser.new_context()

跳过证书检查

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        args: ['--ignore-certificate-errors']
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False, args=['--ignore-certificate-errors'])
context = browser.new_context()

不加载图片, 提升速度

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        args: ['--blink-settings=imagesEnabled=false']
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto

def block_images(page):
    page.route("**/*", lambda route: route.abort() if route.request.resource_type == "image" else route.continue_())

browser = webauto.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
block_images(page)

设置浏览器分辨率(窗口大小)

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({headless: false});
    //设置屏幕大小为1080x720
    const context = await browser.newContext({
        viewport: {width: 1080, height: 720}
    });
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False)
#设置屏幕大小为1080x720
context = browser.new_context(viewport={"width": 1080, "height": 720})

设置请求头的User-Agent

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({headless: false});
    const context = await browser.newContext({userAgent: ""});
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False)
context = browser.new_context(user_agent="")

禁用Javascript

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({headless: false});
    const context = await browser.newContext({javaScriptEnabled: false});
})();
from leanproWeb import WebAuto

browser = webauto.chromium.launch(headless=False)
context = browser.new_context(java_script_enabled=False)

日志记录级别

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const browser = await chromium.launch({
        headless: false,
        logger: {
            isEnabled: (name, severity) => name === 'browser' && severity === 'error'
            //日志记录级别,severity可设置为"verbose","info","warning"或"error"
        }
    });
    const context = await browser.newContext();
})();
from leanproWeb import WebAuto
import logging

logging.basicConfig(level=logging.ERROR)

browser = webauto.chromium.launch(headless=False)
context = browser.new_context()

设置用户数据文件夹

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const data_dir = '/path/to/your/data/folder'; //用户存放数据的文件名
    //使用launchPersistentContext方法启动
    const browser = await chromium.launchPersistentContext(data_dir, {
        headless: false,
        executablePath: "C:/Program Files/Google/Chrome/Application/chrome.exe"
        //用户存放chrome.exe的路径
    });
    //使用launchPersistentContext方法可以不配置上下文newCcontext() 
})();
from leanproWeb import WebAuto

#用户存放数据的文件名
data_dir = '/path/to/your/data/folder'
#使用launch_persistent_context方法启动
#executable_path参数为用户存放chrome.exe的路径
browser = WebAuto().__enter__().chromium.launch_persistent_context(
    user_data_dir=data_dir,
    headless=False,
    executable_path="C:/Program Files/Google/Chrome/Application/chrome.exe"
)

#使用launch_persistent_context方法可以不配置上下文new_context()

添加扩展

通过在 launchPersistentContext() 方法中添加 --disable-extensions-except--load-extension 参数,可以为浏览器加载扩展程序。以下步骤详细说明如何操作:

  1. 准备扩展文件

    • 下载所需的 .crx 文件(Chrome 扩展的安装文件)。
    • .crx 文件解压为文件夹形式,确保解压后的目录包含 manifest.json 及其他必要的文件(例如图像、脚本等)。可以使用工具(如 7-Zip 或 Chrome 的开发者模式)完成解压。
  2. 配置代码

    • 将解压后的文件夹路径指定为扩展加载路径,并在 launchPersistentContext()args 参数中添加相关选项。

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const extensionPath = 'C:/path/to/your/extension'; // 替换为 .crx 文件解压后的文件夹路径
    const userDataDir = 'C:/Users/username/AppData/Local/Google/Chrome/User Data'; // 可选:指定用户数据目录
    const executablePath = 'C:/Program Files/Google/Chrome/Application/chrome.exe'; // 指定 Chrome 可执行文件路径

    const browser = await chromium.launchPersistentContext(userDataDir, {
        headless: false,
        executablePath: executablePath,
        args: [
            `--disable-extensions-except=${extensionPath}`, // 禁用除指定扩展外的所有扩展
            `--load-extension=${extensionPath}` // 加载指定的扩展
        ],
    });
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await browser.close();
})();
from leanproWeb import WebAuto

extension_path = 'C:/path/to/your/extension'  # 替换为 .crx 文件解压后的文件夹路径
user_data_dir = 'C:/Users/username/AppData/Local/Google/Chrome/User Data'  # 可选:指定用户数据目录
executable_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe'  # 指定 Chrome 可执行文件路径

browser = WebAuto().__enter__().chromium.launch_persistent_context(
    user_data_dir=user_data_dir,
    headless=False, 
    executable_path=executable_path,
    args=[
        f'--disable-extensions-except={extension_path}',  # 禁用除指定扩展外的所有扩展
        f'--load-extension={extension_path}'  # 加载指定的扩展
    ]
)

page = browser.new_page()
page.goto('https://example.com')
browser.close()

配置一套浏览器

在用 CukeTest 进行 Web 自动化测试时,频繁重启全新浏览器可能会带来不便,因为每次运行业务测试脚本前都需要执行冗长的配置脚本(如登录、注册等)。通过启动一个带有用户数据的浏览器,可以复用现有 Cookies 或保持登录状态,从而避免重复配置操作。这种方式能模拟日常使用的浏览器环境,提升测试效率。

以下介绍如何在测试中直接利用用户数据。

直接使用默认用户启动浏览器

设置用户数据文件夹一节中,已介绍如何配置用户数据的方法。你可以将其中的 user_data_dir 替换为 Chrome 安装目录下的 User Data 文件夹,从而启动与日常使用一致的浏览器。以下是配置代码示例:

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const data_dir = "C:/Users/username/AppData/Local/Google/Chrome/User Data";
    const browser = await chromium.launchPersistentContext(data_dir, {
        headless: false,
        executablePath: "C:/Program Files/Google/Chrome/Application/chrome.exe"
    });
    const page = await browser.newPage(); // 创建页面
    await page.goto("https://example.com"); // 示例:访问网页
    await browser.close(); // 关闭浏览器
})();
from leanproWeb import WebAuto

data_dir = "C:/Users/username/AppData/Local/Google/Chrome/User Data"
executable_path = "C:/Program Files/Google/Chrome/Application/chrome.exe"

browser = WebAuto().__enter__().chromium.launch_persistent_context(
    user_data_dir=data_dir,
    headless=False,
    executable_path=executable_path
)
page = browser.new_page()
page.goto("https://example.com")
browser.close()  # 关闭浏览器

  • 路径替换:将 username 替换为你的实际 Windows 用户名,确保路径指向正确的 Chrome 用户数据目录。
  • 效果:启动后,你将看到与日常使用相同的浏览器,包括书签、扩展和登录状态。

关于 BrowserContext 的说明

什么是 BrowserContext

  • BrowserContext 是 Playwright 提供的一个隔离环境,类似于 Chrome 的“隐身模式”或独立配置文件。每个 BrowserContext 可以有自己的 Cookies、缓存、权限设置等。
  • launchPersistentContext 中,Playwright 会自动创建一个 BrowserContext,并将用户数据(例如 User Data 目录)加载到该上下文中。后续创建的页面(newPage())都属于这个上下文。

是否需要手动创建 BrowserContext

  • 不需要手动创建 BrowserContext。当使用 launchPersistentContext 时,Playwright 已经为你创建了一个持久化上下文,并将其与指定的用户数据目录绑定。直接调用 browser.newPage() 即可在该上下文中创建页面。
  • 如果你需要多个隔离的上下文(例如测试不同用户),可以在 browser.newContext() 创建额外的上下文,但这会忽略 launchPersistentContext 的用户数据。

可能遇到的报错

运行上述代码时,可能会遇到以下错误:

(node:19824) UnhandledPromiseRejectionWarning: browserType.launchPersistentContext: Browser closed.

原因: 错误通常由用户数据目录的读写冲突引起。这可能是因为:

  1. 当前有一个 Chrome 实例正在使用 C:/Users/username/AppData/Local/Google/Chrome/User Data
  2. 后台仍有 Chrome 进程(如扩展或更新进程)未关闭。

解决方法

  1. 关闭 Chrome:打开任务管理器,结束所有 chrome.exe 进程,确保无后台实例。
  2. 替代方案:创建用户数据目录的副本,避免干扰日常使用:
     xcopy "C:\Users\username\AppData\Local\Google\Chrome\User Data" "C:\Users\username\playwright-user-data" /E /H /C /I
    
    然后更新代码中的 data_dir 为新路径:
    JavaScript
    const data_dir = "C:/Users/username/playwright-user-data";

使用新增用户启动浏览器

在上一节中,报错的原因是因为有另一个实例占用了用户数据文件夹,因此我们只要另起一个用户数据文件夹——也就是新建一个浏览器用户,具体的方法如下:

新增用户

data_dir中配置一个新文件夹Profile1(无需在该目录下手动添加该文件夹)

JavaScript
Python
const { chromium } = require('leanpro.web');

(async () => {
    const data_dir = "C:/Users/username/AppData/Local/Google/Chrome/User Data/Profile1";
    const browser = await chromium.launchPersistentContext(data_dir, {
        headless: false,
        executablePath: "C:/Program Files/Google/Chrome/Application/chrome.exe"
    });

    const page = await browser.newPage();
    page.goto("https://github.com/"); //假设用户先前已在chrome浏览器上登录了GitHub账号A
})();
from leanproWeb import WebAuto

data_dir = "C:/Users/username/AppData/Local/Google/Chrome/User Data/Profile1"
executable_path = "C:/Program Files/Google/Chrome/Application/chrome.exe"

browser = WebAuto().__enter__().chromium.launch_persistent_context(user_data_dir=data_dir, headless=False, executable_path=executable_path)

page = browser.new_page()
page.goto("https://github.com/") #假设用户先前已在chrome浏览器上登录了GitHub账号A

新增的用户数据文件夹

运行测试,这时会开启一个新的浏览器并出现一个未登录状态的https://github.com首页,同时C:/Users/username/AppData/Local/Google/Chrome/User Data目录下会自动生成一个Profile1文件夹。

检查是否能保存浏览数据

在该页面登录另一个Github账号B并关闭浏览器,接着之后再运行测试就都可以看到保持在账号B登录中的状态了。

这个方法也可以有效的隔离用户数据,以Github举例,你可能有个自己的账号,但还有另外一个测试账号。在原来的情况,可能需要经常在Github上切换账号,但是现在就不需要了,两个账号的登录状态保存在不同的用户数据文件夹中,不会产生任何冲突。

*有时用户会遇见这样的报错:

(node:41500) UnhandledPromiseRejectionWarning: Error: Unknown target type: shared_worker

可以通过在启动参数中添加--disable-shared-workers解决

JavaScript
Python
browser = await chromium.launchPersistentContext(data_dir, {
    headless: false,
    executablePath: "C:/Program Files/Google/Chrome/Application/chrome.exe",
    args: ['--disable-shared-workers'] // 在此处添加'--disable-shared-workers'参数
});
browser = WebAuto().__enter__().chromium.launch_persistent_context(
    user_data_dir=data_dir,
    headless=False,
    executable_path=executable_path,
    args=['--disable-shared-workers'] # 在此处添加'--disable-shared-workers'参数
)

results matching ""

    No results matching ""