001/*
002 * (C) Copyright 2011-2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Sun Seng David TAN
016 *     Florent Guillaume
017 *     Benoit Delbosc
018 *     Antoine Taillefer
019 *     Anahide Tchertchian
020 *     Guillaume Renard
021 *     Mathieu Guillaume
022 *     Julien Carsique
023 */
024package org.nuxeo.functionaltests.drivers;
025
026import java.io.File;
027import java.util.Arrays;
028
029import org.apache.commons.lang3.SystemUtils;
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.openqa.selenium.chrome.ChromeDriver;
033import org.openqa.selenium.chrome.ChromeOptions;
034import org.openqa.selenium.remote.DesiredCapabilities;
035import org.openqa.selenium.remote.RemoteWebDriver;
036
037/**
038 * Driver provider for chrome.
039 *
040 * @since 8.3
041 */
042public class ChromeDriverProvider implements DriverProvider {
043
044    private static final Log log = LogFactory.getLog(DriverProvider.class);
045
046    public static final String CHROME_DRIVER_DEFAULT_PATH_LINUX = "/usr/bin/chromedriver";
047
048    /**
049     * "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" doesn't work
050     */
051    public static final String CHROME_DRIVER_DEFAULT_PATH_MAC = "/Applications/chromedriver";
052
053    public static final String CHROME_DRIVER_DEFAULT_PATH_WINVISTA = SystemUtils.getUserHome().getPath()
054            + "\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe";
055
056    public static final String CHROME_DRIVER_DEFAULT_PATH_WINXP = SystemUtils.getUserHome().getPath()
057            + "\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chromedriver.exe";
058
059    public static final String CHROME_DRIVER_DEFAULT_EXECUTABLE_NAME = "chromedriver";
060
061    public static final String CHROME_DRIVER_WINDOWS_EXECUTABLE_NAME = "chromedriver.exe";
062
063    public static final String SYSPROP_CHROME_DRIVER_PATH = "webdriver.chrome.driver";
064
065    protected ChromeDriver driver;
066
067    @Override
068    public RemoteWebDriver init(DesiredCapabilities dc) throws Exception {
069        if (System.getProperty(SYSPROP_CHROME_DRIVER_PATH) == null) {
070            String chromeDriverDefaultPath = null;
071            String chromeDriverExecutableName = CHROME_DRIVER_DEFAULT_EXECUTABLE_NAME;
072            if (SystemUtils.IS_OS_LINUX) {
073                chromeDriverDefaultPath = CHROME_DRIVER_DEFAULT_PATH_LINUX;
074            } else if (SystemUtils.IS_OS_MAC) {
075                chromeDriverDefaultPath = CHROME_DRIVER_DEFAULT_PATH_MAC;
076            } else if (SystemUtils.IS_OS_WINDOWS_XP) {
077                chromeDriverDefaultPath = CHROME_DRIVER_DEFAULT_PATH_WINXP;
078                chromeDriverExecutableName = CHROME_DRIVER_WINDOWS_EXECUTABLE_NAME;
079            } else if (SystemUtils.IS_OS_WINDOWS_VISTA) {
080                chromeDriverDefaultPath = CHROME_DRIVER_DEFAULT_PATH_WINVISTA;
081                chromeDriverExecutableName = CHROME_DRIVER_WINDOWS_EXECUTABLE_NAME;
082            } else if (SystemUtils.IS_OS_WINDOWS) {
083                // Unknown default path on other Windows OS. To be completed.
084                chromeDriverDefaultPath = CHROME_DRIVER_DEFAULT_PATH_WINVISTA;
085                chromeDriverExecutableName = CHROME_DRIVER_WINDOWS_EXECUTABLE_NAME;
086            }
087
088            if (chromeDriverDefaultPath != null && new File(chromeDriverDefaultPath).exists()) {
089                log.warn(String.format("Missing property %s but found %s. Using it...", SYSPROP_CHROME_DRIVER_PATH,
090                        chromeDriverDefaultPath));
091                System.setProperty(SYSPROP_CHROME_DRIVER_PATH, chromeDriverDefaultPath);
092            } else {
093                // Can't find chromedriver in default location, check system
094                // path
095                File chromeDriverExecutable = findExecutableOnPath(chromeDriverExecutableName);
096                if ((chromeDriverExecutable != null) && (chromeDriverExecutable.exists())) {
097                    log.warn(String.format("Missing property %s but found %s. Using it...", SYSPROP_CHROME_DRIVER_PATH,
098                            chromeDriverExecutable.getCanonicalPath()));
099                    System.setProperty(SYSPROP_CHROME_DRIVER_PATH, chromeDriverExecutable.getCanonicalPath());
100                } else {
101                    log.error(String.format(
102                            "Could not find the Chrome driver looking at %s or system path."
103                                    + " Download it from %s and set its path with " + "the System property %s.",
104                            chromeDriverDefaultPath, "http://code.google.com/p/chromedriver/downloads/list",
105                            SYSPROP_CHROME_DRIVER_PATH));
106                }
107            }
108        }
109        ChromeOptions options = new ChromeOptions();
110        options.addArguments(Arrays.asList("--ignore-certificate-errors"));
111        dc.setCapability(ChromeOptions.CAPABILITY, options);
112        driver = new ChromeDriver(dc);
113        return driver;
114    }
115
116    /**
117     * @since 5.7
118     */
119    protected static File findExecutableOnPath(String executableName) {
120        String systemPath = System.getenv("PATH");
121        String[] pathDirs = systemPath.split(File.pathSeparator);
122        File fullyQualifiedExecutable = null;
123        for (String pathDir : pathDirs) {
124            File file = new File(pathDir, executableName);
125            if (file.isFile()) {
126                fullyQualifiedExecutable = file;
127                break;
128            }
129        }
130        return fullyQualifiedExecutable;
131    }
132
133    @Override
134    public RemoteWebDriver get() {
135        return driver;
136    }
137
138    @Override
139    public void quit() {
140        if (driver != null) {
141            driver.quit();
142            driver = null;
143        }
144    }
145
146}