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().__enter__().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().__enter__().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().__enter__().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().__enter__().chromium.launch(headless=True)
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().__enter__().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().__enter__().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().__enter__().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().__enter__().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().__enter__().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().__enter__().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().__enter__().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().__enter__().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

#用户存放数据的文件名
user_data_dir = '/path/to/your/data/folder'
#使用launch_persistent_context方法启动
#executable_path参数为用户存放chrome.exe的路径
browser = WebAuto().__enter__().chromium.launch_persistent_context(user_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文件后,将其解压至文件夹形式(请确保该文件夹目录下有manifest.json及其他所需文件)。然后进行如下配置:

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

(async () => {
    const path = '/path/to/your/extension'; //该路径为.crx文件解压后的文件夹路径
    const browser = await chromium.launchPersistentContext('', {
        headless: false,
        executablePath: "C:/Program Files/Google/Chrome/Application/chrome.exe",
        args: [`--disable-extensions-except=${path}`, `--load-extension=${path}`],
    });
})();
from leanproWeb import WebAuto

extension_dir = "/path/to/your/extension" #该路径为.crx文件解压后的文件夹路径
data_dir = "C:/Users/username/AppData/Local/Google/Chrome/User Data"
executable_dir = "C:/Program Files/Google/Chrome/Application/chrome.exe"
browser = webauto.chromium.launch_persistent_context(
    user_data_dir=data_dir, 
    headless=False, 
    executable_path=executable_dir, 
    args=[
        f'--disable-extensions-except={extension_dir}',
        f'--load-extension={extension_dir}'
    ]
)

配置一套浏览器

在用CukeTest进行Web自动化时,可能会因为每次都重启一个全新的干净浏览器而烦恼,可能会导致每次在业务测试脚本开始前先执行一大段配置脚本(比如登录、注册等等)。而如果启动一个跟平时使用没有区别、带用户数据的浏览器,就可以在执行业务测试时,使用已有的cookie或者保持住登录状态,来避免反复的配置操作。

下面介绍如何在测试时直接用上用户数据。

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

事实上,在设置用户数据文件夹一节我们在第一行就介绍了配置用户数据的方法。只要将其中的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"
    });
})();
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)

其中的username请替换为实际的用户的Windows登录名,以使上面的路径指向正确的已有路径。接着启动测试即可看到一套熟悉的、与平时使用一样的浏览器启动。

当然有时候你只会看到一串如下的报错

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

这通常是因为后台已经有一个浏览器实例正在使用该用户数据文件夹,这会导致读写冲突。但这其实只是因为你已经开了一个浏览器,而两个浏览器使用了同一个用户数据文件夹;或者后台仍有相关的进程在使用该用户数据(Chrome为了保证运行速度会在后台保持浏览器扩展,而扩展使用了用户数据)。因此可能需要用将这些Chrome进程结束掉,才能成功启动,这非常的麻烦,当然下面提供了另外一种方案,可以比较好的解决这个问题。

使用新增用户启动浏览器

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

新增用户

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'参数
});
#在args中添加'--disable-shared-workers'参数
browser = webauto.chromium.launch_persistent_context(user_data_dir=data_dir, headless=False, executable_path=executable_path, args=['--disable-shared-workers'])

results matching ""

    No results matching ""