All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lazerycode.selenium.SeleniumServerMojo Maven / Gradle / Ivy

Go to download

A plugin to automatically download individual selenium standalone binaries (e.g. chromedriver.exe) for your mavenised selenium project.

There is a newer version: 1.0.18
Show newest version
package com.lazerycode.selenium;

import com.lazerycode.selenium.download.DownloadHandler;
import com.lazerycode.selenium.repository.*;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceCreationException;
import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;

import static com.lazerycode.selenium.repository.FileRepository.buildDownloadableFileRepository;
import static com.lazerycode.selenium.repository.OperatingSystem.getOperatingSystem;
import static com.lazerycode.selenium.repository.SystemArchitecture.getCurrentSystemArcitecture;

/**
 * Selenium Standalone Server Maven Plugin
 *
 * @author Mark Collin
 */

@Mojo(name = "selenium", defaultPhase = LifecyclePhase.TEST_COMPILE)
@SuppressWarnings({"UnusedDeclaration"})
public class SeleniumServerMojo extends AbstractMojo {
    /**
     * 

Root directory where the standalone server file structure will be created and files will be saved

*

<rootStandaloneServerDirectory>${project.basedir}/src/test/resources/webdriver/binaries</rootStandaloneServerDirectory>

*/ @Parameter(defaultValue = "${project.basedir}/src/test/resources/webdriver/binaries") protected File rootStandaloneServerDirectory; /** *

Directory where downloaded standalone executable zip files will be saved

*

<downloadedZipFileDirectory>${project.basedir}/src/test/resources/webdriver/compressed_files</downloadedZipFileDirectory>

*/ @Parameter(defaultValue = "${project.basedir}/src/test/resources/webdriver/compressed_files") protected File downloadedZipFileDirectory; /** *

Path to the XML RepositoryMap

*

<xmlRepositoryMap>${project.basedir}/src/test/resources/RepositoryMap.xml</xmlRepositoryMap>

*/ @Parameter protected String customRepositoryMap; /** *

Only get drivers that are compatible with the operating system running the plugin

*

<onlyGetDriversForHostOperatingSystem>true</onlyGetDriversForHostOperatingSystem>

*

If set to false this will download binary executables for all operating systems

*/ @Parameter(defaultValue = "true") protected boolean onlyGetDriversForHostOperatingSystem; /** *

The Operating systems you would like to download a standalone executable for

*

<operatingSystems>

*

<windows>true</windows>

*

<linux>true</linux>

*

<mac>true</mac>

*

</operatingSystems>

*

Unknown operating systems will cause an error to be thrown, only use the options shown above.

*

WARNINGif onlyGetDriversForHostOperatingSystem is true, this will be ignored!

*/ @Parameter protected Map operatingSystems; /** *

Force download of 32 bit standalone executable

. *

<thirtyTwoBitBinaries>true</thirtyTwoBitBinaries>

*/ @Parameter(defaultValue = "false") protected boolean thirtyTwoBitBinaries; /** *

Force download of 64 bit standalone executable

*

<sixtyFourBitBinaries>true</sixtyFourBitBinaries>

*/ @Parameter(defaultValue = "false") protected boolean sixtyFourBitBinaries; /** *

Force download of arm standalone executable

. *

<armBinaries>true</armBinaries>

*/ @Parameter(defaultValue = "false") protected boolean armBinaries; /** *

Only get the latest version of each standalone executable in RepositoryMap.xml

*

<onlyGetLatestVersions>true</onlyGetLatestVersions>

*

If set to false this will download all versions specified in the RepositoryMap.xml

*

This will be ignored if specific executable versions have been specified

*/ @Parameter(defaultValue = "true") protected boolean onlyGetLatestVersions; /** *

A map of driver standalone versions to download

*

<getSpecificExecutableVersions>

*

<googlechrome>19</googlechrome>

*

<internetexplorer>2.21.0</internetexplorer>

*

</getSpecificExecutableVersions>

*

Unrecognised browser names/versions will be ignored by default

*/ @Parameter protected Map getSpecificExecutableVersions; /** *

Throw an exception if any of the specified standalone versions do not exist in the repository map

*

* <throwExceptionIfSpecifiedVersionIsNotFound>false</throwExceptionIfSpecifiedVersionIsNotFound> *

*

This will cause a MojoFailureException to be thrown if any specific executable versions that have been specified do not exist in the RepositoryMap.xml

*/ @Parameter(defaultValue = "false") protected boolean throwExceptionIfSpecifiedVersionIsNotFound; /** *

Number of times to retry the file download of each executable

*

<fileDownloadRetryAttempts>1</fileDownloadRetryAttempts>

*/ @Parameter(defaultValue = "1") protected int fileDownloadRetryAttempts; /** *

the number of milliseconds until this method will timeout if no connection could be established to remote file location

*

<fileDownloadConnectTimeout>15000</fileDownloadConnectTimeout>

*/ @Parameter(defaultValue = "15000") protected int fileDownloadConnectTimeout; /** *

the number of milliseconds until this method will timeout if if no data could be read from remote file location

*

<fileDownloadReadTimeout>15000</fileDownloadReadTimeout>

*/ @Parameter(defaultValue = "15000") protected int fileDownloadReadTimeout; /** *

If the environmental variables http.proxyHost, and http.proxyPort are set they will be used for http/https calls

*

<useSystemProxy>true</useSystemProxy>

*/ @Parameter(defaultValue = "true") protected boolean useSystemProxy; /** *

Force the plugin to overwrite any files that have already been extracted from a valid zip file

*

<overwriteFilesThatExist>false</overwriteFilesThatExist>

*

crc checks are not performed on files that have been extracted from valid zips, they are assumed to be valid. * This will force the plugin to extract everything from valid zips again and overwrite any existing files.

*

This does not clean out old files, it only writes new files over the top of existing ones.

*/ @Parameter(defaultValue = "false") protected boolean overwriteFilesThatExist; /** *

Enable the file hash check for downloaded files

*

<checkFileHashes>false</checkFileHashes>

*

Setting this to false will skip all hash checks on downloaded files, this is not recommended.

*

If you do not check the file hash there is no guarantee that the downloaded file is the correct file

*/ @Parameter(defaultValue = "true") protected boolean checkFileHashes; @Parameter(defaultValue = "${project}", required = true, readonly = true) protected MavenProject project; @Component private ResourceManager locator; protected InputStream xmlRepositoryMap = null; private static final Logger LOG = Logger.getLogger(SeleniumServerMojo.class); @Override public void execute() throws MojoExecutionException, MojoFailureException { BasicConfigurator.configure(new MavenLoggerLog4jBridge(getLog())); LOG.info(" "); LOG.info("--------------------------------------------------------"); LOG.info(" DOWNLOADING SELENIUM STAND-ALONE EXECUTABLE BINARIES..."); LOG.info("--------------------------------------------------------"); LOG.info(" "); setRepositoryMapFile(); if (fileDownloadRetryAttempts < 1) { LOG.warn("Invalid number of retry attempts specified, defaulting to '1'..."); fileDownloadRetryAttempts = 1; } Map selectedOperatingSystems = new HashMap(); LOG.info("Only get drivers for current Operating System: " + this.onlyGetDriversForHostOperatingSystem); //Calculate operating systems Set osTypeList = new HashSet(); if (onlyGetDriversForHostOperatingSystem || null == operatingSystems || operatingSystems.size() < 1) { LOG.info("Getting drivers for current operating system only."); osTypeList = OperatingSystem.getCurrentOperatingSystemAsAHashSet(); } else { for (Map.Entry os : this.operatingSystems.entrySet()) { if (os.getValue().toLowerCase().equals("true")) { osTypeList.add(getOperatingSystem(os.getKey())); } } } //Calculate system architecture if (!thirtyTwoBitBinaries && !sixtyFourBitBinaries && !armBinaries) { //TODO clean this up, maybe pass in a list of valid architectures later on if (getCurrentSystemArcitecture().equals(SystemArchitecture.ARCHITECTURE_64_BIT)) { sixtyFourBitBinaries = true; } else if (getCurrentSystemArcitecture().equals(SystemArchitecture.ARCHITECTURE_ARM)) { armBinaries = true; } else { thirtyTwoBitBinaries = true; } } DriverMap driverRepository; XMLParser parser = new XMLParser(xmlRepositoryMap, osTypeList, getSpecificExecutableVersions, thirtyTwoBitBinaries, sixtyFourBitBinaries); try { DownloadHandler standaloneExecutableDownloader = new DownloadHandler( this.rootStandaloneServerDirectory, this.downloadedZipFileDirectory, this.fileDownloadRetryAttempts, this.fileDownloadConnectTimeout, this.fileDownloadReadTimeout, buildDownloadableFileRepository(parser.getAllNodesInScope(), thirtyTwoBitBinaries, sixtyFourBitBinaries, armBinaries), this.overwriteFilesThatExist, this.checkFileHashes, this.useSystemProxy, this.onlyGetLatestVersions); driverRepository = standaloneExecutableDownloader.ensureStandaloneExecutableFilesExist(); } catch (IOException e) { throw new MojoExecutionException("Failed to download all of the standalone executables: " + e.getLocalizedMessage()); } catch (URISyntaxException e) { throw new MojoExecutionException("Invalid URI detected: " + e.getLocalizedMessage()); } catch (XPathExpressionException | JAXBException rethrow) { throw new MojoExecutionException(rethrow.getMessage()); } setSystemProperties(driverRepository); LOG.info(" "); LOG.info("--------------------------------------------------------"); LOG.info("SELENIUM STAND-ALONE EXECUTABLE DOWNLOADS COMPLETE"); LOG.info("--------------------------------------------------------"); LOG.info(" "); } /** * Set the system property webdriver.*.driver for the latest revision of each binary extracted. * * @param driverRepository map of drivers that system properties will be set for */ protected void setSystemProperties(DriverMap driverRepository) { ArrayList driverContextsForCurrentOperatingSystem = driverRepository.getDriverContextsForCurrentOperatingSystem(); if (driverContextsForCurrentOperatingSystem.size() == 0) { LOG.warn("No driver contexts detected for the current operating system, no maven properties set!"); } for (DriverContext driverContext : driverContextsForCurrentOperatingSystem) { DriverDetails driverDetails = driverRepository.getDetailsForLatestVersionOfDriverContext(driverContext); LOG.info("Setting maven property - ${" + driverContext.getBinaryTypeForContext().getDriverSystemProperty() + "} = " + driverDetails.extractedLocation); project.getProperties().setProperty(driverContext.getBinaryTypeForContext().getDriverSystemProperty(), driverDetails.extractedLocation); } } private File getRepositoryMapFile(String customRepositoryMap) { File repositoryMap; try { repositoryMap = locator.getResourceAsFile(customRepositoryMap); } catch (ResourceNotFoundException | FileResourceCreationException e) { LOG.info("Unable to find the specified custom repository map in dependencies, attempting to use value as a file path..."); LOG.info(" "); repositoryMap = new File(customRepositoryMap); } return repositoryMap; } /** * Set the RepositoryMap used to get file information. * If the supplied map is invalid it will default to the pre-packaged one here. * * @throws MojoExecutionException */ private void setRepositoryMapFile() throws MojoExecutionException { if (this.customRepositoryMap != null && !this.customRepositoryMap.isEmpty()) { File repositoryMap = getRepositoryMapFile(this.customRepositoryMap); if (repositoryMap.exists()) { checkRepositoryMapIsValid(repositoryMap); try { this.xmlRepositoryMap = repositoryMap.toURI().toURL().openStream(); } catch (IOException ioe) { throw new MojoExecutionException(ioe.getLocalizedMessage()); } } else { throw new MojoExecutionException("Repository map '" + repositoryMap.getAbsolutePath() + "' does not exist"); } } if (this.xmlRepositoryMap == null) { this.xmlRepositoryMap = this.getClass().getResourceAsStream("/RepositoryMap.xml"); } } /** * Validate any custom repository maps that are supplied against the xsd. * Throw an error and stop if it is not valid. * Assume it doesn't exist if we get an IOError and fall back to default file. * * @throws MojoExecutionException thrown if customRepositoryMap is not valid */ protected void checkRepositoryMapIsValid(File repositoryMap) throws MojoExecutionException { URL schemaFile = this.getClass().getResource("/RepositoryMap.xsd"); Source xmlFile = new StreamSource(repositoryMap); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); try { Schema schema = schemaFactory.newSchema(schemaFile); Validator validator = schema.newValidator(); validator.validate(xmlFile); LOG.info("Repository map '" + xmlFile.getSystemId() + "' is valid"); LOG.info(" "); } catch (SAXException | IOException ex) { throw new MojoExecutionException(repositoryMap.getName() + " is not valid: " + ex.getLocalizedMessage()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy