如何有效的在docker 里面run selenium
https://blog.aerokube.com/selenium-on-windows-docker-revolution-f5a7eab205ad
start container 之前需要设置好docker proxy:
https://docs.docker.com/config/daemon/systemd/
-
Create a systemd drop-in directory for the docker service:
$ sudo mkdir -p /etc/systemd/system/docker.service.d
-
Create a file named
/etc/systemd/system/docker.service.d/http-proxy.conf
that adds theHTTP_PROXY
environment variable:[Service] Environment="HTTP_PROXY=http://proxy.example.com:80"
If you are behind an HTTPS proxy server, set the
HTTPS_PROXY
environment variable:[Service] Environment="HTTPS_PROXY=https://proxy.example.com:443"
Multiple environment variables can be set; to set both a non-HTTPS and a HTTPs proxy;
[Service] Environment="HTTP_PROXY=http://proxy.example.com:80" Environment="HTTPS_PROXY=https://proxy.example.com:443"
-
If you have internal Docker registries that you need to contact without proxying you can specify them via the
NO_PROXY
environment variable.The
NO_PROXY
variable specifies a string that contains comma-separated values for hosts that should be excluded from proxying. These are the options you can specify to exclude hosts:- IP address prefix (
1.2.3.4
) - Domain name, or a special DNS label (
*
) - A domain name matches that name and all subdomains. A domain name with a leading “.” matches subdomains only. For example, given the domains
foo.example.com
andexample.com
:-
example.com
matchesexample.com
andfoo.example.com
, and -
.example.com
matches onlyfoo.example.com
-
- A single asterisk (
*
) indicates that no proxying should be done - Literal port numbers are accepted by IP address prefixes (
1.2.3.4:80
) and domain names (foo.example.com:80
)
Config example:
[Service] Environment="HTTP_PROXY=http://proxy.example.com:80" Environment="HTTPS_PROXY=https://proxy.example.com:443" Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
- IP address prefix (
-
Flush changes and restart Docker
$ sudo systemctl daemon-reload $ sudo systemctl restart docker
-
Verify that the configuration has been loaded and matches the changes you made, for example:
$ sudo systemctl show --property=Environment docker Environment=HTTP_PROXY=http://proxy.example.com:80 HTTPS_PROXY=https://proxy.example.com:443 NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp
start the selenoid container:
docker run -d \
--name selenoid \
-p 4444:4444 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD:/etc/selenoid/:ro \
-v /opt/selenoid/video/:/opt/selenoid/video/ \
-v /opt/selenoid/logs/:/opt/selenoid/logs/ \
-v /home/admin/selenium/files/Certificate:/home/admin/selenium/files/Certificate \
-e OVERRIDE_VIDEO_OUTPUT_DIR=/opt/selenoid/video/ \
aerokube/selenoid:latest-release -limit 300 -log-output-dir /opt/selenoid/logs -save-all-logs \
-video-output-dir /opt/selenoid/video/ -mem 1g -cpu 1.0
start the selenoid-ui container:
docker run -d --name selenoid-ui --link selenoid -p 8080:8080 aerokube/selenoid-ui --selenoid-uri=http://172.17.0.1:4444
可用的cmd:
docker run -d \
--name selenoid \
-p 4444:4444 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD:/etc/selenoid/:ro \
-v /opt/selenoid/video/:/opt/selenoid/video/ \
-v /opt/selenoid/logs/:/opt/selenoid/logs/ \
-v /home/admin/selenium/files/Certificate:/home/admin/selenium/files/Certificate \
-e OVERRIDE_VIDEO_OUTPUT_DIR=/opt/selenoid/video/ \
aerokube/selenoid:latest-release -limit 300 -timeout 45m -log-output-dir /opt/selenoid/logs -save-all-logs \
-video-output-dir /opt/selenoid/video/
参考:docker run -d --name selenoid -p 4444:4444 -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd)/config/:/etc/selenoid/:ro aerokube/selenoid:latest-release -timeout 3m0s -conf /etc/selenoid/browsers.json
docker run -d --name selenoid-ui --link selenoid -p 8080:8080 --restart=always aerokube/selenoid-ui --selenoid-uri=http://172.17.0.1:4444
第二种方法 -- 二进制文件的方法:
wget https://github.com/aerokube/cm/releases/download/1.8.1/cm_linux_amd64
mv cm_linux_amd64 cm
chmod +x cm
http_proxy=http://web-proxy.us.softwaregrp.net:8080
HTTP_PROXY=http://web-proxy.us.softwaregrp.net:8080/ ./cm selenoid start --vnc --tmpfs 128
HTTP_PROXY=http://web-proxy.us.softwaregrp.net:8080/ ./cm selenoid-ui start
删除docker container的方法:
docker kill $(docker ps -a | grep sele)
docker rm $(docker ps -a | grep sele)
docker ps -a | grep sele
docker kill $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker ps -a
https://aerokube.com/moon-cloud/
docker run 加proxy:
https://blog.csdn.net/chang_harry/article/details/53464778
youtube:
https://www.youtube.com/watch?v=RJCvvfSE2FE
selenoid-ui not loading running sessions with error:
是因为docker代理问题导致的
在docker pull到所需的image之后要删除docker proxy
cmd
i. Enable the service, run: systemctl enable docker.service
ii. Run: mkdir -p /usr/lib/systemd/system/docker.service.d
iii. Run:cat /usr/lib/systemd/system/docker.service.d/http_proxy.conf
vi /usr/lib/systemd/system/docker.service.d/http_proxy.conf
Environment="HTTP_PROXY=http://web-proxy.us.softwaregrp.net:8080" "https_proxy=http://web-proxy.us.softwaregrp.net:8080"
变成:
空
iv. Reload the configuration:
systemctl daemon-reload
service docker restart
v. Restart docker:
service docker restart
vi. Check if you can pull images from Docker Hub:
docker pull hello-world
couldn't it be because of some proxies configured on your host?
然后按照这个文档一步步进行下去:
http://aerokube.com/selenoid-ui/latest/#_quick_start_guide
selenoid 属性设置:
https://github.com/aerokube/selenoid/blob/master/docs/special-capabilities.adoc
selenoid example:
https://www.pawangaria.com/post/docker/selenoid-as-alternative-selenium-grid-with-docker/
https://medium.com/javarevisited/selenide-in-testing-process-automatisation-through-selenoid-in-the-docker-container-48e659d2ee72
Since now we have the Configuration.browser = “chrome” property, we delete Property baseurl which defined the browser for running our tests:
@BeforeClass
public static void setUp() {
Configuration.remote = "http://10.0.75.1:4444/wd/hub";
Configuration.browser = "chrome";
Configuration.browserSize = "1920x1080";
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(capabilityName: "enableVNC", value: true);
capabilities.setCapability(capabilityName: "enableVideo", value: true);
Configuration.browserCapabilities = capabilities;
Selenoid advanced capabilities
Data storage in RAM: Selenoid stores all temporary files in Tmpfs. It is a temporary file repository that allows storing files in RAM. As we know, access to RAM is performed much faster than to the file system of the hard drive.
Various screen resolution types: we can configure the appropriate screen resolution for a running container on its own by setting the required parameters in the Browser Capabilities.
Video recording of tests: it’s possible to record the video of the tests performed. For instance, the activation in the Google Chrome browser is implemented by setting the parameter true in the Browser Capabilities:
ChromeOptions options = new ChromeOptions ();
options.setCapability (“enableVideo”, true);
seleniod 设置代理和其他参数:
https://github.com/aerokube/cm/blob/master/docs/selenoid-commands.adoc
selenoid 参数设置:
https://www.swtestacademy.com/selenoid-tutorial/
docker run -d --name selenoid \
-p 4444:4444 \
-v ~/.aerokube/selenoid/:/etc/selenoid/:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
aerokube/selenoid:latest-release \
-conf /etc/selenoid/browsers.json -limit 10 \
-video-output-dir /opt/selenoid/video/ -mem 1g -cpu 1.0
Note: If you are using selenoid binary instead of the docker image, you should pass arguments as :
./selenoid -conf /etc/selenoid/browsers.json \
-limit 10 -video-output-dir /opt/selenoid/video/ \
-mem 1g -cpu 1.0
开始跑java代码的时候设置capbilitity 属性代码:
https://www.lambdatest.com/blog/desired-capabilities-in-selenium-testing/
This will download VNC included images and start the selenoid. Don’t forget to set enableVNC capability in your test, which in my case:
package com.lambdatest;
//TestNG Todo : Sample App
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import org.testng.asserts.Assertion;
import com.beust.jcommander.Parameter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class Test2{
public String username = "Your_LambdaTest_Username";
public String accesskey = "Your_LambdaTest_Access_Key";
public static RemoteWebDriver driver = null;
public String gridURL = "@hub.lambdatest.com/wd/hub";
boolean status = false;
//Setting up capabilities to run our test script
@Parameters(value= {"browser","version"})
@BeforeClass
public void setUp(String browser, String version) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("browserName", browser);
capabilities.setCapability("version", version);
capabilities.setCapability("platform", "win10"); // If this cap isn't specified, it will just get the any available one
capabilities.setCapability("build", "LambdaTestSampleApp");
capabilities.setCapability("name", "LambdaTestJavaSample");
capabilities.setCapability("network", true); // To enable network logs
capabilities.setCapability("visual", true); // To enable step by step screenshot
capabilities.setCapability("video", true); // To enable video recording
capabilities.setCapability("console", true); // To capture console logs
capabilities.setCapability("selenium_version","4.0.0-alpha-2");
capabilities.setCapability("timezone","UTC+05:30");
capabilities.setCapability("geoLocation","IN");
capabilities.setCapability("chrome.driver","78.0");
try {
driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
} catch (MalformedURLException e) {
System.out.println("Invalid grid URL");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
//Opening browser with the given URL and navigate to Registration Page
@BeforeMethod
public void openBrowser()
{
// driver.manage().deleteAllCookies();
driver.get("https://www.lambdatest.com/");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
WebElement signUpButton = driver.findElement(By.xpath("//a[contains(text(),'Start Free Testing')]"));
signUpButton.click();
}
//Verifying elements on Registration page
@Test
public void verifyElementsOnPageTest()
{
WebElement lambdaTestLogo = driver.findElement(By.xpath("//p[@class='signup-titel']"));
lambdaTestLogo.isDisplayed();
WebElement signUpTitle = driver.findElement(By.xpath("//p[@class='signup-titel']"));
signUpTitle.isDisplayed();
WebElement termsText = driver.findElement(By.xpath("//label[@class='woo']"));
termsText.isDisplayed();
WebElement loginLinkText = driver.findElement(By.xpath("//p[@class='login-in-link test-left']"));
loginLinkText.isDisplayed();
}
// Closing the browser session after completing each test case
@AfterClass
public void tearDown() throws Exception {
if (driver != null) {
((JavascriptExecutor) driver).executeScript("lambda-status=" + status);
driver.quit();
}
}
}
https://www.tabnine.com/code/java/methods/org.openqa.selenium.remote.RemoteWebDriver/%3Cinit%3E
设置video 的属性:
https://www.swtestacademy.com/selenoid-tutorial/
https://www.pawangaria.com/post/docker/selenoid-as-alternative-selenium-grid-with-docker/
https://testerhome.com/topics/27203
https://medium.com/javarevisited/selenide-in-testing-process-automatisation-through-selenoid-in-the-docker-container-48e659d2ee72
增加录制视频属性:
https://github.com/aerokube/selenoid/blob/master/docs/video.adoc
增加保存logs属性:
https://github.com/aerokube/selenoid/blob/68ce8aa754e473fe4c961178e5974edd337e625c/docs/logs.adoc
import time
from selenium import webdriver
class TestClass:
def test_baidu_chrome(self):
capabilities = {
# 测试用例名称
"name": "test_baidu_chrome",
# 浏览器类型
"browserName": "chrome",
# 版本号
"version": "85.0",
# 开启远程VNC实时画面
"enableVNC": True,
# 开启视频录制
"enableVideo": True,
# 保存视频名称
"videoName": "test_baidu_chrome.mp4"
}
driver = webdriver.Remote(
command_executor="http://10.118.80.65:4444/wd/hub",
desired_capabilities=capabilities)
driver.get('https://www.baidu.com')
driver.find_element_by_id('kw').send_keys('selenoid')
time.sleep(2)
def test_baidu_firefox(self):
capabilities = {
# 测试用例名称
"name": "test_baidu_firefox",
# 浏览器类型
"browserName": "firefox",
# 版本号
"version": "79.0",
# 开启远程VNC实时画面
"enableVNC": True,
# 开启视频录制
"enableVideo": True,
# 保存视频名称
"videoName": "test_baidu_firefox.mp4"
}
driver = webdriver.Remote(
command_executor="http://10.118.80.65:4444/wd/hub",
desired_capabilities=capabilities)
driver.get('https://www.baidu.com')
driver.find_element_by_id('kw').send_keys('selenoid')
time.sleep(2)
def test_baidu_opera(self):
capabilities = {
# 测试用例名称
"name": "test_baidu_opera",
# 浏览器类型
"browserName": "opera",
# 版本号
"version": "79.0",
# 开启远程VNC实时画面
"enableVNC": True,
# 开启视频录制
"enableVideo": True,
# 保存视频名称
"videoName": "test_baidu_opera.mp4",
# opera浏览器需要额外参数
"operaOptions": {"binary": "/usr/bin/opera"}
}
driver = webdriver.Remote(
command_executor="http://10.118.80.65:4444/wd/hub",
desired_capabilities=capabilities)
driver.get('https://www.baidu.com')
driver.find_element_by_id('kw').send_keys('selenoid')
time.sleep(2)
给selenoid container add proxy的方法:
https://github.com/aerokube/selenoid/issues/139
https://github.com/serenity-bdd/serenity-core/issues/2058
-ea
-Dwebdriver.remote.url=http://shcallencdfrh76vm02.hpeswlab.net:4444/wd/hub
-Dstory.names=DemoUIIdmAdmin
-Dwebdriver.remote.driver=chrome
-Dsuite.installer.url=https://autorh78vm00.hpeswlab.net:3000/
-Dui.demo.singleinstall.master=shcrh75vm00.hpeswlab.net
-Dchrome.switches="--ignore-certificate-errors"
-Dserenity.driver.capabilities="enableVNC:true;enableVideo:true;videoName:"DemoUIIdmAdmin.mp4";enableLog:true;logName:"DemoUIIdmAdmin.log";name:"DemoUIIdmAdmin""
-Dserenity.proxy.http=web-proxy.us.softwaregrp.net
-Dserenity.proxy.http_port=8080
-Dserenity.proxy.ssl=web-proxy.us.softwaregrp.net
-Dserenity.proxy.sslProxyPort=8080
My actions:
- Set proxy via systemd: https://docs.docker.com/config/daemon/systemd/
- Start Selenoid via cm:
./cm selenoid cleanup && ./cm selenoid configure --vnc --browsers "firefox;chrome;opera" --last-versions 5 --tmpfs 128 && ./cm selenoid start --port 4444 --args "-limit 5 -service-startup-timeout 90s -session-attempt-timeout 90s -session-delete-timeout 90s -timeout 120s"
- Start selenoid-ui via docker (not cm), when using cm --> selenoid-ui still not up connection with selenoid
DOCKER_GATEWAY_ADDR=`docker inspect selenoid -f {{.NetworkSettings.Gateway}}`
echo $DOCKER_GATEWAY_ADDR
docker run -d --name selenoid-ui -p 8080:8080 aerokube/selenoid-ui --selenoid-uri http://${DOCKER_GATEWAY_ADDR}:4444
- Set selenium proxy capabilities
for execute selenoid container (with proxy):
docker run --rm -e HTTP_PROXY=proxy:8080 -v /var/run/docker.sock:/var/run/docker.sock -v ${HOME}:/root aerokube/cm:latest selenoid start --vnc --tmpfs 128
for execute selenoid-ui container (without proxy)
docker run --rm -d --name selenoid-ui --link selenoid -p 8080:8080 aerokube/selenoid-ui --selenoid-uri=http://selenoid:4444
Ui container was able to obtain data from selenoid. I saw a list of browsers on the UI:
Passing a Capabilities object to the ChromeDriver() constructor is deprecated
. You can find new official doc here.
ChromeOptions chromeOptions = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.setAutodetect(false);
proxy.setHttpProxy("http_proxy-url:port");
proxy.setSslProxy("https_proxy-url:port");
proxy.setNoProxy("no_proxy-var");
chromeOptions.setCapability("proxy", proxy);
driver = new ChromeDriver(chromeOptions);
https://www.selenium.dev/selenium/docs/api/py/_modules/selenium/webdriver/common/proxy.html
DIRECT = ProxyTypeFactory.make(0, 'DIRECT') # Direct connection, no proxy (default on Windows).
MANUAL = ProxyTypeFactory.make(1, 'MANUAL') # Manual proxy settings (e.g., for httpProxy).
PAC = ProxyTypeFactory.make(2, 'PAC') # Proxy autoconfiguration from URL.
RESERVED_1 = ProxyTypeFactory.make(3, 'RESERVED1') # Never used.
AUTODETECT = ProxyTypeFactory.make(4, 'AUTODETECT') # Proxy autodetection (presumably with WPAD).
SYSTEM = ProxyTypeFactory.make(5, 'SYSTEM') # Use system settings (default on Linux).
UNSPECIFIED = ProxyTypeFactory.make(6, 'UNSPECIFIED') # Not initialized (for internal use).
如何解决 session timeout的问题:
-service-startup-timeout 30s - Docker container or driver process startup timeout
-session-attempt-timeout 30s - New session attempt timeout, i.e. POST /wd/hub/session HTTP request timeout.
-session-delete-timeout 10s - Session removal HTTP request timeout
-timeout 60s - Session idle timeout, i.e. time between separate HTTP requests to Selenium API which automatically causes session to be closed.
https://github.com/aerokube/selenoid/issues/210
https://github.com/aerokube/selenoid/issues/262
如何解决selenoid container 内部Chrome文件上传的问题:
1. Manually edit `browsers.json` of working Selenoid and add `"volumes": ["/home/app/uploadFiles:/home/app/uploadFiles"]` as shown here: [https://aerokube.com/selenoid/latest/#_browsers_configuration_file](https://aerokube.com/selenoid/latest/#_browsers_configuration_file)
2. Restart Selenoid container
https://github.com/aerokube/selenoid/issues/561
https://github.com/aerokube/selenoid/issues/76
https://saucelabs.com/blog/selenium-tips-uploading-files-in-remote-webdriver
browsers.json 中 browsers 的设置:
https://aerokube.com/images/latest/#_browser_image_information