HOWTO: Chrome带配置项启动
在使用CukeTest进行Web自动化测试时,启动的浏览器(这里以Chrome为例)是一个纯净的实例,没有任何浏览器扩展。而我们常常会对浏览器有些特殊的需求,就需要对浏览器进行配置。本文主要介绍:
- 浏览器配置项及其在自动化测试中的配置方法
- 配置Chrome专用用户的方案
配置方法
在JavaScript中,我们使用leanpro.web
提供的API来配置这些选项;在Python中,我们使用leanproWeb
中的WebAuto
来配置这些选项。具体的实现如下:
配置浏览器及上下文
在leanpro.web
或leanproWeb.WebAuto
中,我们可以通过传递配置选项给chromium.launch()
方法来配置浏览器,并配置浏览器上下文,例如:
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()
中添加所需的启动参数。
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
启动参数:
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)、可执行文件路径、代理等。
常用启动参数
可以配置的启动参数非常多,完整版的可以访问此网站。但是这里我们只列举常用的一些参数配置方法。
设置无头模式
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()
控制回放速度
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加速
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()
隐藏滚动条(应对一些特殊页面)
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()
跳过证书检查
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()
不加载图片, 提升速度
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)
设置浏览器分辨率(窗口大小)
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
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
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)
日志记录级别
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()
设置用户数据文件夹
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
参数,可以为浏览器加载扩展程序。以下步骤详细说明如何操作:
准备扩展文件:
- 下载所需的
.crx
文件(Chrome 扩展的安装文件)。 - 将
.crx
文件解压为文件夹形式,确保解压后的目录包含manifest.json
及其他必要的文件(例如图像、脚本等)。可以使用工具(如 7-Zip 或 Chrome 的开发者模式)完成解压。
- 下载所需的
配置代码:
- 将解压后的文件夹路径指定为扩展加载路径,并在
launchPersistentContext()
的args
参数中添加相关选项。
- 将解压后的文件夹路径指定为扩展加载路径,并在
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
文件夹,从而启动与日常使用一致的浏览器。以下是配置代码示例:
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.
原因: 错误通常由用户数据目录的读写冲突引起。这可能是因为:
- 当前有一个 Chrome 实例正在使用
C:/Users/username/AppData/Local/Google/Chrome/User Data
。 - 后台仍有 Chrome 进程(如扩展或更新进程)未关闭。
解决方法:
- 关闭 Chrome:打开任务管理器,结束所有
chrome.exe
进程,确保无后台实例。 - 替代方案:创建用户数据目录的副本,避免干扰日常使用:
然后更新代码中的xcopy "C:\Users\username\AppData\Local\Google\Chrome\User Data" "C:\Users\username\playwright-user-data" /E /H /C /I
data_dir
为新路径:JavaScriptconst data_dir = "C:/Users/username/playwright-user-data";
使用新增用户启动浏览器
在上一节中,报错的原因是因为有另一个实例占用了用户数据文件夹,因此我们只要另起一个用户数据文件夹——也就是新建一个浏览器用户,具体的方法如下:
新增用户
在data_dir
中配置一个新文件夹Profile1
(无需在该目录下手动添加该文件夹)
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
解决
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'参数
)