Package jp.vmi.selenium.selenese

Source Code of jp.vmi.selenium.selenese.Main$SROptions

package jp.vmi.selenium.selenese;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jp.vmi.selenium.selenese.command.ICommandFactory;
import jp.vmi.selenium.selenese.log.CookieFilter;
import jp.vmi.selenium.selenese.log.CookieFilter.FilterType;
import jp.vmi.selenium.selenese.result.Result;
import jp.vmi.selenium.selenese.utils.LoggerUtils;
import jp.vmi.selenium.webdriver.DriverOptions;
import jp.vmi.selenium.webdriver.DriverOptions.DriverOption;
import jp.vmi.selenium.webdriver.WebDriverManager;

/**
* Provide command line interface.
*/
public class Main {

    private static final Logger log = LoggerFactory.getLogger(Main.class);

    private static final int HELP_WIDTH = 78;

    private static final String PROG_TITLE = "Selenese Runner";

    private static final String HEADER = "Selenese script interpreter implemented by Java.";

    private static final String FOOTER = "[Note]" + SystemUtils.LINE_SEPARATOR
        + "* If you want to use basic and/or proxy authentication on Firefox, "
        + "then create new profile, "
        + "install AutoAuth plugin, "
        + "configure all settings, "
        + "access test site with the profile, "
        + "and specify the profile by --profile option."
        + SystemUtils.LINE_SEPARATOR
        + "** Use \"java -cp ..." + SystemUtils.PATH_SEPARATOR + "selenese-runner.jar Main --command-factory ...\". "
        + "Because \"java\" command ignores all class path settings, when using \"-jar\" option.";

    private static final String DEFAULT_TIMEOUT_MILLISEC = "30000";

    private static class SROptions extends Options {
        private static final long serialVersionUID = 1L;

        private int i = 0;

        public final Map<Option, Integer> optionOrder = new HashMap<Option, Integer>();

        @Override
        public Options addOption(Option opt) {
            optionOrder.put(opt, ++i);
            return super.addOption(opt);
        }

        public Comparator<Option> getOptionComparator() {
            return new Comparator<Option>() {
                @Override
                public int compare(Option o1, Option o2) {
                    return optionOrder.get(o1) - optionOrder.get(o2);
                }
            };
        }
    }

    private final SROptions options = new SROptions();

    /**
     * Constructor.
     */
    @SuppressWarnings("static-access")
    public Main() {
        options.addOption(OptionBuilder
            .withLongOpt("driver")
            .hasArg()
            .withArgName("driver")
            .withDescription(
                "firefox (default) | chrome | ie | safari | htmlunit | phantomjs | remote | appium | FQCN-of-WebDriverFactory")
            .create('d'));
        options.addOption(OptionBuilder.withLongOpt("profile")
            .hasArg().withArgName("name")
            .withDescription("profile name (Firefox only)")
            .create('p'));
        options.addOption(OptionBuilder.withLongOpt("profile-dir")
            .hasArg().withArgName("dir")
            .withDescription("profile directory (Firefox only)")
            .create('P'));
        options.addOption(OptionBuilder.withLongOpt("proxy")
            .hasArg().withArgName("proxy")
            .withDescription("proxy host and port (HOST:PORT) (excepting IE)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("proxy-user")
            .hasArg().withArgName("user")
            .withDescription("proxy username (HtmlUnit only *)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("proxy-password")
            .hasArg().withArgName("password")
            .withDescription("proxy password (HtmlUnit only *)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("no-proxy")
            .hasArg().withArgName("no-proxy")
            .withDescription("no-proxy hosts")
            .create());
        options.addOption(OptionBuilder.withLongOpt("cli-args")
            .hasArg().withArgName("cli-args")
            .withDescription("add command line arguments at starting up driver (multiple)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("remote-url")
            .hasArg().withArgName("url")
            .withDescription("Remote test runner URL (Remote only)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("remote-platform")
            .hasArg().withArgName("platform")
            .withDescription("Desired remote platform (Remote only)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("remote-browser")
            .hasArg().withArgName("browser")
            .withDescription("Desired remote browser (Remote only)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("remote-version")
            .hasArg().withArgName("browser-version")
            .withDescription("Desired remote browser version (Remote only)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("highlight")
            .withDescription("highlight locator always.")
            .create('H'));
        options.addOption(OptionBuilder.withLongOpt("screenshot-dir")
            .hasArg().withArgName("dir")
            .withDescription("override captureEntirePageScreenshot directory.")
            .create('s'));
        options.addOption(OptionBuilder.withLongOpt("screenshot-all")
            .hasArg().withArgName("dir")
            .withDescription("take screenshot at all commands to specified directory.")
            .create('S'));
        options.addOption(OptionBuilder.withLongOpt("screenshot-on-fail")
            .hasArg().withArgName("dir")
            .withDescription("take screenshot on fail commands to specified directory.")
            .create());
        options.addOption(OptionBuilder.withLongOpt("ignore-screenshot-command")
            .withDescription("ignore captureEntirePageScreenshot command.")
            .create());
        options.addOption(OptionBuilder.withLongOpt("baseurl")
            .hasArg().withArgName("baseURL")
            .withDescription("override base URL set in selenese.")
            .create('b'));
        options.addOption(OptionBuilder.withLongOpt("firefox")
            .hasArg().withArgName("path")
            .withDescription("path to 'firefox' binary. (implies '--driver firefox')")
            .create());
        options.addOption(OptionBuilder.withLongOpt("chromedriver")
            .hasArg().withArgName("path")
            .withDescription("path to 'chromedriver' binary. (implies '--driver chrome')")
            .create());
        options.addOption(OptionBuilder.withLongOpt("iedriver")
            .hasArg().withArgName("path")
            .withDescription("path to 'IEDriverServer' binary. (implies '--driver ie')")
            .create());
        options.addOption(OptionBuilder.withLongOpt("phantomjs")
            .hasArg().withArgName("path")
            .withDescription("path to 'phantomjs' binary. (implies '--driver phantomjs')")
            .create());
        options.addOption(OptionBuilder.withLongOpt("xml-result")
            .hasArg().withArgName("dir")
            .withDescription("output XML JUnit results to specified directory.")
            .create());
        options.addOption(OptionBuilder.withLongOpt("html-result")
            .hasArg().withArgName("dir")
            .withDescription("output HTML results to specified directory.")
            .create());
        options.addOption(OptionBuilder.withLongOpt("timeout")
            .hasArg().withArgName("timeout")
            .withDescription("set timeout (ms) for waiting. (default: " + DEFAULT_TIMEOUT_MILLISEC + " ms)")
            .create('t'));
        options.addOption(OptionBuilder.withLongOpt("set-speed")
            .hasArg().withArgName("speed")
            .withDescription("same as executing setSpeed(ms) command first.")
            .create());
        options.addOption(OptionBuilder.withLongOpt("height")
            .hasArg().withArgName("height")
            .withDescription("set initial height. (excluding mobile)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("width")
            .hasArg().withArgName("width")
            .withDescription("set initial width. (excluding mobile)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("define")
            .hasArg().withArgName("key=value or key+=value")
            .withDescription("define parameters for capabilities. (multiple)")
            .create('D'));
        options.addOption(OptionBuilder.withLongOpt("rollup")
            .hasArg().withArgName("file")
            .withDescription("define rollup rule by JavaScript. (multiple)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("cookie-filter")
            .hasArg().withArgName("+RE|-RE")
            .withDescription("filter cookies to log by RE matching the name. (\"+\" is passing, \"-\" is ignoring)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("command-factory")
            .hasArg().withArgName("FQCN")
            .withDescription("register user defined command factory. (See Note **)")
            .create());
        options.addOption(OptionBuilder.withLongOpt("help")
            .withDescription("show this message.")
            .create('h'));
    }

    /**
     * Get version of Selenese Runner.
     * <p>
     * This information is provided by maven generated property file.
     * </p>
     * @return version string.
     */
    public String getVersion() {
        InputStream is = getClass().getResourceAsStream("/META-INF/maven/jp.vmi/selenese-runner-java/pom.properties");
        if (is != null) {
            try {
                Properties prop = new Properties();
                prop.load(is);
                return prop.getProperty("version");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(is);
            }
        }
        return "(missing version information)";
    }

    private int getHelpWidth() {
        String columns = System.getenv("COLUMNS");
        if (columns != null && columns.matches("\\d+")) {
            try {
                return Integer.parseInt(columns) - 2;
            } catch (NumberFormatException e) {
                // no operation
            }
        }
        return HELP_WIDTH;
    }

    private void help(String... msgs) {
        if (msgs.length > 0) {
            for (String msg : msgs)
                System.out.println(msg);
            System.out.println();
        }

        int helpWidth = getHelpWidth();
        String progName = System.getenv("PROG_NAME");
        if (StringUtils.isBlank(progName))
            progName = "java -jar selenese-runner.jar";
        HelpFormatter fmt = new HelpFormatter();
        fmt.setOptionComparator(options.getOptionComparator());
        PrintWriter pw = new PrintWriter(System.out);
        pw.format(PROG_TITLE + " %s%n%n" + HEADER + "%n%n", getVersion());
        fmt.setSyntaxPrefix("Usage: ");
        fmt.printHelp(pw, helpWidth, progName + " <option> ... <test-case|test-suite> ...\n",
            null, options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null);
        pw.println();
        fmt.printWrapped(pw, helpWidth, FOOTER);
        pw.flush();
        exit(1);
    }

    /**
     * Parse command line arguments.
     *
     * @param args command line arguments.
     * @return parsed command line information.
     * @throws IllegalArgumentException invalid options.
     */
    public CommandLine parseCommandLine(String... args) throws IllegalArgumentException {
        CommandLine cli = null;
        try {
            cli = new PosixParser().parse(options, args);
            log.debug("Specified options:");
            for (Option opt : cli.getOptions())
                log.debug("[{}]=[{}]", opt.getLongOpt(), opt.getValue());
        } catch (ParseException e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
        return cli;
    }

    /**
     * Start Selenese Runner.
     *
     * @param args command line arguments.
     */
    public void run(String[] args) {
        int exitCode = 1;
        try {
            CommandLine cli = parseCommandLine(args);
            String[] filenames = cli.getArgs();
            if (filenames.length == 0)
                help();
            log.info("Start: " + PROG_TITLE + " {}", getVersion());
            String driverName = cli.getOptionValue("driver");
            DriverOptions driverOptions = new DriverOptions(cli);
            if (driverName == null) {
                if (driverOptions.has(DriverOption.FIREFOX))
                    driverName = WebDriverManager.FIREFOX;
                else if (driverOptions.has(DriverOption.CHROMEDRIVER))
                    driverName = WebDriverManager.CHROME;
                else if (driverOptions.has(DriverOption.IEDRIVER))
                    driverName = WebDriverManager.IE;
                else if (driverOptions.has(DriverOption.PHANTOMJS))
                    driverName = WebDriverManager.PHANTOMJS;
            }
            WebDriverManager manager = WebDriverManager.getInstance();
            manager.setWebDriverFactory(driverName);
            manager.setDriverOptions(driverOptions);
            Runner runner = new Runner();
            if (cli.hasOption("command-factory")) {
                String factoryName = cli.getOptionValue("command-factory");
                ICommandFactory factory;
                try {
                    Class<?> factoryClass = Class.forName(factoryName);
                    factory = (ICommandFactory) factoryClass.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new IllegalArgumentException("invalid user defined command factory: " + factoryName);
                }
                runner.getCommandFactory().registerCommandFactory(factory);
                log.info("Registered: {}", factoryName);
            }
            runner.setCommandLineArgs(args);
            runner.setDriver(manager.get());
            runner.setWebDriverPreparator(manager);
            runner.setHighlight(cli.hasOption("highlight"));
            runner.setScreenshotDir(cli.getOptionValue("screenshot-dir"));
            runner.setScreenshotAllDir(cli.getOptionValue("screenshot-all"));
            runner.setScreenshotOnFailDir(cli.getOptionValue("screenshot-on-fail"));
            runner.setOverridingBaseURL(cli.getOptionValue("baseurl"));
            runner.setIgnoredScreenshotCommand(cli.hasOption("ignore-screenshot-command"));
            if (cli.hasOption("rollup")) {
                String[] rollups = cli.getOptionValues("rollup");
                for (String rollup : rollups)
                    runner.getRollupRules().load(rollup);
            }
            if (cli.hasOption("cookie-filter")) {
                String cookieFilter = cli.getOptionValue("cookie-filter");
                if (cookieFilter.length() < 2)
                    throw new IllegalArgumentException("invalid cookie filter format: " + cookieFilter);
                FilterType filterType;
                switch (cookieFilter.charAt(0)) {
                case '+':
                    filterType = FilterType.PASS;
                    break;
                case '-':
                    filterType = FilterType.SKIP;
                    break;
                default:
                    throw new IllegalArgumentException("invalid cookie filter format: " + cookieFilter);
                }
                String pattern = cookieFilter.substring(1);
                runner.setCookieFilter(new CookieFilter(filterType, pattern));
            }
            runner.setJUnitResultDir(cli.getOptionValue("xml-result"));
            runner.setHtmlResultDir(cli.getOptionValue("html-result"));
            int timeout = NumberUtils.toInt(cli.getOptionValue("timeout", DEFAULT_TIMEOUT_MILLISEC));
            if (timeout <= 0)
                throw new IllegalArgumentException("Invalid timeout value. (" + cli.getOptionValue("timeout") + ")");
            runner.setTimeout(timeout);
            int speed = NumberUtils.toInt(cli.getOptionValue("set-speed", "0"));
            if (speed < 0)
                throw new IllegalArgumentException("Invalid speed value. (" + cli.getOptionValue("set-speed") + ")");
            runner.setInitialSpeed(speed);
            runner.setPrintStream(System.out);
            Result totalResult = runner.run(filenames);
            runner.finish();
            exitCode = totalResult.getLevel().exitCode;
        } catch (IllegalArgumentException e) {
            help("Error: " + e.getMessage());
        } catch (Throwable t) {
            t.printStackTrace();
        }
        exit(exitCode);
    }

    protected void exit(int exitCode) {
        System.exit(exitCode);
    }

    /**
     * Selenese Runner main.
     *
     * @param args command line arguments.
     */
    public static void main(String[] args) {
        LoggerUtils.initLogger();
        new Main().run(args);
    }
}
TOP

Related Classes of jp.vmi.selenium.selenese.Main$SROptions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.