Selenium Gridをdockerコンテナでリモートブラウザを起動するやり方で使用する。
ソースコードと手順
docker-compose.yml
DockerでSelenium Gridを構築してクロスブラウザテストを自動化するを参考にdocker-compose.ymlを作成する。
version: '3.8' services: selenium-hub: image: selenium/hub:4.7.2 ports: - 4444:4444 - 4442:4442 - 4443:4443 node-chrome: image: selenium/node-chrome:4.7.2 depends_on: - selenium-hub environment: - TZ=Asia/Tokyo - HUB_HOST=selenium-hub - SE_EVENT_BUS_HOST=selenium-hub - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 node-firefox: image: selenium/node-firefox:4.7.2 depends_on: - selenium-hub environment: - TZ=Asia/Tokyo - HUB_HOST=selenium-hub - SE_EVENT_BUS_HOST=selenium-hub - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
docker-compose up
で起動して http://localhost:4444/ui で下記キャプチャのようなコンソールが開けばOK.
java
plugins { id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.seleniumhq.selenium:selenium-java:4.7.2' }
https://transit.yahoo.co.jp/ にアクセスしてtitle出力するだけのサンプルコード。
import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class RemoteSeleniumSample { public static void main(String[] args) throws MalformedURLException { URL address = new URL("http://localhost:4444"); ChromeOptions chromeOption = new ChromeOptions(); chromeOption.setHeadless(true); chromeOption.addArguments("--disable-gpu", "--disable-dev-shm-usage"); RemoteWebDriver driver = new RemoteWebDriver(address, chromeOption); try { driver.get("https://transit.yahoo.co.jp/"); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.name("from"))); System.out.println(driver.getTitle()); } finally { driver.quit(); } } }
複数コンテナ起動
設定で複数ブラウザセッションを起動出来るし、複数コンテナ起動して並列実行も出来る。
docker-compose up --scale node-chrome=3
javaから3スレッドでseleinumを起動する。
import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class RemoteSeleniumSample2 { public static void main(String[] args) throws MalformedURLException, InterruptedException, ExecutionException { ExecutorService es = Executors.newFixedThreadPool(3); Future<?> f1 = es.submit(() -> execute()); Future<?> f2 = es.submit(() -> execute()); Future<?> f3 = es.submit(() -> execute()); f1.get(); f2.get(); f3.get(); es.shutdown(); } static void execute() { RemoteWebDriver driver = null; try { URL address = new URL("http://localhost:4444"); ChromeOptions chromeOption = new ChromeOptions(); chromeOption.setHeadless(true); chromeOption.addArguments("--disable-gpu", "--disable-dev-shm-usage"); driver = new RemoteWebDriver(address, chromeOption); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); driver.get("https://transit.yahoo.co.jp/"); wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.name("from"))); System.out.println(driver.getTitle()); } catch (MalformedURLException e) { e.printStackTrace(); } finally { driver.quit(); } } }
コンソール画面は下記のように3個のchromeブラウザ用インスタンスが作成される。また、実行中かどうかも分かる。
ハマった点
unknown error: session deleted because of page crash from tab crashed
メモリ省力化設定を入れて「Selenium::WebDriver::Error::UnknownError: unknown error: session deleted because of page crash」が出ないようにする に従って各種オプションを設定する。