We have several issues and the key seems to be the no-sandbox option to Chrome. Below is a solution that works on the desktop and on a jenkins slave running in the foreground or via service.
Part One: Maven Unpack of Chrome & Driver
- Download PortableApps GoogleChrome
- Install
- Rename dir to generic name (GoogleChrome)
- Zip dir
- add to repository manager
setup maven-dependency-plugin executions to unpack
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>extract portable google chrome</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<skip>${skipWinChromeUnpack}</skip>
<markersDirectory>${project.build.directory}/dependency-maven-plugin-markers/googlechrome</markersDirectory>
<overWriteIfNewer>false</overWriteIfNewer>
<artifactItems>
<artifactItem>
<groupId>com.google.chromium</groupId>
<artifactId>chromedriver</artifactId>
<version>${win.chromedriver.version}</version>
<classifier>win32</classifier>
<type>zip</type>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>com.portableapps</groupId>
<artifactId>googlechrome</artifactId>
<version>${win.chrome.version}</version>
<classifier>win64</classifier>
<type>zip</type>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
Result
At test execution time we have target/chromedriver.exe and target/GooglePortable/Google...exe files to use
Part Two: Maven Surefire config
We set System properties for location of driver and chrome exe to pass down to all unit tests
<systemPropertyVariables>
<webdriver.chrome.driver>${project.build.directory}/chromedriver.exe</webdriver.chrome.driver>
<win.google.chrome.bin>${win.chrome.exe}</win.google.chrome.bin>
</systemPropertyVariables>
Part Three: Test Code
We use chrome driver service builder to set verbosity to 11 and start the driver using our favorite capabilities from that
public class ChromeLocator {
private static final Logger log = Logger.getLogger(ChromeLocator.class);
/**
* Obtain Chrome Configuration with location of binary
* @return
* @throws IOException
*/
public DesiredCapabilities getCapabilities() throws IOException {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setBinary(getChromeExecutableLocation().getAbsolutePath());
chromeOptions.addArguments("no-sandbox");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
return capabilities;
}
// Windows defaults to unpacked location
private File getChromeExecutableLocation() throws IOException {
File chromeExe;
if (SystemUtils.IS_OS_WINDOWS) {
chromeExe = new File(System.getProperty("win.google.chrome.bin"));
} else {
// Use the standard locator option for all other operating systems
GoogleChromeLocator locator = new GoogleChromeLocator();
BrowserInstallation installation = locator.findBrowserLocationOrFail();
chromeExe = new File(installation.launcherFilePath());
}
System.out.println("Chrome Exe: " + chromeExe.getAbsolutePath() + " Is File: " + chromeExe.isFile());
if (! chromeExe.exists() || ! chromeExe.isFile()) {
throw new IOException("Cannot locate Chrome Executable. Expected Location: " + chromeExe.getAbsolutePath());
}
return chromeExe;
}
}
public class WebTest
{
static ChromeDriverService service = null;
static WebDriver driver = null;
@BeforeClass
static public void setupOnce() throws IOException {
// Setup ChromeDriver with Verbosity on - perhaps control via system property - off by default?
service = new ChromeDriverService.Builder()
.withVerbose(true)
.usingAnyFreePort()
.build();
service.start();
// Setup locator to find unpacked Portable chrome exe
ChromeLocator locator = new ChromeLocator();
// Use service + capabilities from locator to open driver with settings and chrome bin
driver = new RemoteWebDriver(service.getUrl(), locator.getCapabilities());
}
@AfterClass
static public void teardownOnce() {
if (null != service) {
service.stop();
service = null;
}
}
@Test
public void testGoogleSearch() throws InterruptedException, IOException {
driver.get("http://www.google.com/xhtml");
assertEquals("Google", driver.getTitle());
WebElement searchBox = driver.findElement(By.name("q"));
String searchString = "ChromeDriver";
searchBox.sendKeys(searchString);
searchBox.submit();
String source = driver.getPageSource().toString();
assertTrue("Expected DOCTYPE in
" + source,
source.contains("DOCTYPE"));
driver.quit();
service.stop();
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…