obtain a working Docker image with Windows inside

如何有效的在docker 里面run selenium
https://blog.aerokube.com/selenium-on-windows-docker-revolution-f5a7eab205ad

start container 之前需要设置好docker proxy:
https://docs.docker.com/config/daemon/systemd/

  1. Create a systemd drop-in directory for the docker service:

    $ sudo mkdir -p /etc/systemd/system/docker.service.d
    
    
  2. Create a file named /etc/systemd/system/docker.service.d/http-proxy.conf that adds the HTTP_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"
    
    
  3. 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 and example.com:
      • example.com matches example.com and foo.example.com, and
      • .example.com matches only foo.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"
    
    
  4. Flush changes and restart Docker

    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker
    
    
  5. 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:

  1. Set proxy via systemd: https://docs.docker.com/config/daemon/systemd/
  2. 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"

  1. 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

  1. 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

你可能感兴趣的:(obtain a working Docker image with Windows inside)