使用chromedriver让Win Jenkins奴隶还可以吗?
我的测试从Maven存储库中提取chromedriver和便携式chrome,然后执行它们。在本地和当构建用户在构建系统上执行相同操作时,工作正常。
当jenkins做同样的事情时,即使在前台运行(不是svc),它也会失败,并显示以下错误。我尝试传递参数来提高详细程度无济于事。
org.openqa.selenium.WebDriverException: unknown error: Chrome failed to start: exited normally (Driver info: chromedriver=2.23.409699 (49b0fa931cda1caad0ae15b7d1b68004acd05129),platform=Windows NT 6.1.7601 SP1 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 62.63 seconds Build info: version: ‘2.41.0’, revision: ‘3192d8a6c4449dc285928ba024779344f5423c58’, time: ‘2014-03-27 11:29:39’ System info: host: ‘winengbld15’, ip: ‘10.2.2.105’, os.name: ‘Windows Server 2008 R2’, os.arch: ‘amd64’, os.version: ‘6.1’, java.version: ‘1.8.0_40’ Driver info: org.openqa.selenium.chrome.ChromeDriver at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:595) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:240) at org.openqa.selenium.chrome.ChromeDriver.startSession(ChromeDriver.java:181) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:126) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:139) at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:160) at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:128)
我这样设置Chrome驱动程序:
defaultPath = "target/drivers/chromedriver.exe"; System.setProperty("webdriver.chrome.driver", defaultPath); ChromeLocator locator = new ChromeLocator(); driver = new ChromeDriver(locator.getCapabilities()); 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 { Map<String, Object> chromeOptions = new HashMap<String, Object>(); chromeOptions.put("binary", getChromeExecutableLocation().getAbsolutePath()); 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")); log.info("*** win.google.chrome.bin: " + 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()); } log.info("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; } }
我们遇到了几个问题,关键似乎是Chrome的无沙箱选项。以下是在桌面和在前台或通过服务运行的jenkins从站上工作的解决方案。
第一部分:Chrome和驱动程序的Maven解压缩
<plugin>
org.apache.maven.plugins maven-dependency-plugin 2.8 extract portable google chrome process-test-resources unpack ${skipWinChromeUnpack} ${project.build.directory}/dependency-maven-plugin-markers/googlechrome false com.google.chromium chromedriver ${win.chromedriver.version} win32 zip ${project.build.directory} com.portableapps googlechrome ${win.chrome.version} win64 zip ${project.build.directory}
结果 在测试执行时,我们有target / chromedriver.exe和target / GooglePortable / Google … exe文件要使用
第二部分:Maven Surefire配置
我们为驱动程序和chrome exe的位置设置系统属性,以传递给所有单元测试
<systemPropertyVariables> <webdriver.chrome.driver>${project.build.directory}/chromedriver.exe</webdriver.chrome.driver> <win.google.chrome.bin>${win.chrome.exe}</win.google.chrome.bin> </systemPropertyVariables>
第三部分:测试代码
我们使用chrome驱动程序服务构建器将详细程度设置为11,然后使用我们最喜欢的功能启动驱动程序
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\n" + source, source.contains("DOCTYPE")); driver.quit(); service.stop(); }