selenoid

Selenoid 是一个强大的 Selenium hub 实现,使用 Docker 来启动浏览器容器。

selenoid优缺点

优点:
  • 开源
  • 安装简单
  • 运行过程可视化,支持多版本浏览器同时运行
  • 可以远程操作浏览器
  • 可以录像
缺点:
  • 不支持集群部署,这限制了浏览器并发上限,我自己的2c4g的腾讯云轻量服务器最多5个浏览器并行,虽然更高的单机配置可以让更多浏览器并行运行,但是不够灵活

一、准备工作

1、安装docker

简单介绍一下 Centos 7.x 的安装步骤,可自行安装,已安装docker请忽略该步骤

1.1 更新一下yum

yum update -y

1.2 安装需要的软件包

yum-util提供yum-config-manager功能,另外两个是devicemapper驱动依赖的

yum install -y yum-utils device-mapper-persistent-data lvm2

1.3 设置yum源为阿里云

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.4 安装docker

yum -y install docker-ce

2、拉取镜像
selenoid容器镜像

docker pull aerokube/selenoid

selenoid-ui容器镜像

docker pull aerokube/selenoid-ui:1.10.4

这里指定了1.10.4版本是因为这个版本容器列表可以正常显示容器的Sessions ID,方便区分容器,也可以根据需要使用最新的版本

在docker中安装 ie浏览器 docker ie 浏览器_selenium

浏览器容器镜像:

可以拉取自己需要的版本

docker pull selenoid/vnc:chrome_104.0

docker pull selenoid/vnc:firefox_103.0

录像容器镜像:

用于录制整个测试过程的浏览器画面

docker pull selenoid/video-recorder

3、编写配置文件

mkdir -p /selenoid/config

vi /selenoid/config/browsers.json

volumes可以做容器路径映射,让浏览器容器访问本地的文件

env可以指定一些环境变量,比如设置浏览器语言、时区

shmSize浏览器共享内存大小,默认值256Mb,设置的太小可能出现不稳定的情况(浏览器崩溃、闪退等),设置的太大占用的服务器会资源更多

更多的参数请参考:官方文档

{
    "chrome": {
        "default": "103.0",
        "versions": {
            "chrome_104": {
                "image": "selenoid/vnc:chrome_104.0",
                "privileged": "true",
                "volumes": ["/data:/boot"],
                "port": "4444",
                "path": "/",
                "shmSize": 1073741824,
                "mem": "1024m",
                "env": ["LANG=chn_CHN.UTF-8", "LANGUAGE=chn:zh", "LC_ALL=chn_CHN.UTF-8", "TZ=Asia/Shanghai"]
            },
            "chrome_103": {
                "image": "selenoid/vnc:chrome_103.0",
                "privileged": "true",
                "volumes": ["/data:/boot"],
                "port": "4444",
                "path": "/",
                "env": ["LANG=chn_CHN.UTF-8", "LANGUAGE=chn:zh", "LC_ALL=chn_CHN.UTF-8"]
            },
            "firefox_103": {
                "image": "selenoid/vnc:firefox_103.0",
                "privileged": "true",
                "volumes": ["/data:/boot"],
                "port": "4444",
                "path": "/",
                "env": ["LANG=chn_CHN.UTF-8", "LANGUAGE=chn:zh", "LC_ALL=chn_CHN.UTF-8"]
            }
        }
    }
}

二、启动容器

selenoid容器
docker run -d --name selenoid -p 5555:4444 \
	-v /var/run/docker.sock:/var/run/docker.sock \
	-v /selenoid/config/:/etc/selenoid/:ro \
	aerokube/selenoid

一些可选参数:

启动一个可以录像的selenoid容器

-limit浏览器最大图像数量

-timeout会话超时时间

更多参数参考:官方文档

# 录像前提 1、已拉取录像容器 2、创建一个/selenoid/video路径
docker run -d --name selenoid -p 5555:4444 \
	-v /var/run/docker.sock:/var/run/docker.sock \
	-v /selenoid/config/:/etc/selenoid/:ro \
    -v /selenoid/video/:/opt/selenoid/video/ \
    -e OVERRIDE_VIDEO_OUTPUT_DIR=/selenoid/video/ \
	aerokube/selenoid -limit 10 -timeout 2m
启动selenoid-ui

注意这里的IP是你服务器的公网IP

docker run -d --name selenoid-ui -p 8080:8080 \
	aerokube/selenoid-ui:1.10.4 
	--selenoid-uri http://123.123.123.123:5555

打开浏览器访问:http://123.123.123.123:8080

注意自己服务器的端口访问策略,提前开启服务器端口访问,避免无法访问的情况

可以看到:

在docker中安装 ie浏览器 docker ie 浏览器_在docker中安装 ie浏览器_02

CAPABILITIES里面可以看到不同语言的连接示例

在docker中安装 ie浏览器 docker ie 浏览器_selenium_03

使用小技巧

修改browsers.json之后,重新加载browsers.json的方法:

docker kill -s HUP selenoid

剪切板访问

获取剪切板内容:

curl http://123.123.123.123:5555/clipboard/b635e0329c2e5235903798dcdd3ba036

向见剪切板发送内容:

curl -X POST --data 'some-clipboard-value' http://123.123.123.123:5555/clipboard/b635e0329c2e5235903798dcdd3ba036

b635e0329c2e5235903798dcdd3ba036是浏览器容器的 Session ID 可以在日志里面查看

在docker中安装 ie浏览器 docker ie 浏览器_自动化_04

三、pytest中使用

在conftest.py中写一个get_driver()方法

更多capabilities配置参考:谷歌官方文档 可能需要一点魔法才能访问~

import pytest
from selenium import webdriver

@pytest.fixture()
def get_driver():
    """启动浏览器"""
    capabilities = {
        "browserName": "chrome",
        "browserVersion": "chrome_103",
        "selenoid:options": {
            "enableVNC": True,
            "enableVideo": False
            }
        }

    driver = webdriver.Remote(
    	command_executor="http://123.123.123.123:5555/wd/hub",
        desired_capabilities=capabilities)

    driver.implicitly_wait(10)
    driver.maximize_window()

    return driver

用例中使用:

import os
import pytest

class TestCase:
    
    def test_load_baidu(self, get_driver):
        """访问百度"""
        self.driver = get_driver
        self.driver.get("https://www.baidu.com/")

if __name__ == '__main__':
    real_path = os.path.realpath(__file__)
    my_path = os.path.relpath(real_path)
    pytest.main([my_path])