Java tutorial
/* * Copyright (c) 2015 Andrew Breksa (abreksa4@gmail.com) * * This file is part of BeanTest. * * BeanTest is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * BeanTest is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with BeanTest. If not, see <http://www.gnu.org/licenses/>. */ package edu.abreksa.BeanTest.components; import bsh.EvalError; import bsh.Interpreter; import com.esotericsoftware.minlog.Log; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.IncorrectnessListener; import com.gargoylesoftware.htmlunit.ScriptException; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HTMLParserListener; import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.javascript.JavaScriptErrorListener; import com.google.gson.annotations.Expose; import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; import edu.abreksa.BeanTest.Main; import org.apache.commons.logging.LogFactory; import org.openqa.selenium.Proxy; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.w3c.css.sac.CSSException; import org.w3c.css.sac.CSSParseException; import org.w3c.css.sac.ErrorHandler; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.sql.Timestamp; import java.util.*; import java.util.logging.Level; public class Test { @Expose private Driver driver; //todo: fix serialization issue @Expose private BrowserVersion browserVersion = BrowserVersion.FIREFOX_24; public enum Driver { WebDriver, HTMLUnit } public static HashMap<String, Object> data = new HashMap<String, Object>(); /** * The Script code. */ public String scriptCode; /** * The Base url. */ @Expose private String baseUrl = Main.url; /** * The scripts to include, in order from first to last */ @Expose private List<String> before = new ArrayList<String>(); /** * The scripts to include after */ @Expose private List<String> after = new ArrayList<String>(); /** * The Proxy. */ @Expose public boolean proxy = false; /** * The Locators used in the test, form of key=>css selector */ @Expose public HashMap<String, String> locators = new HashMap<String, String>(); /** * The Properties used in the test, form of key=>value */ @Expose public HashMap<String, String> properties = new HashMap<String, String>(); /** * The Name. */ @Expose public String name; /** * The Author. */ @Expose public String author; /** * The Script location */ @Expose public String script; private TestHandle testHandle; public static Test testLoader(String filepath) throws IOException { Log.debug("Loading test \"" + filepath + "\""); File testFile = new File(filepath); if (!testFile.exists()) { throw new FileNotFoundException("The test definition file \"" + filepath + "\" does not exist."); } Test test = Main.gson.fromJson(Main.Utils.readFile(testFile.getAbsolutePath()), Test.class); StringBuilder stringBuilder = new StringBuilder(); Queue<Object> queue = new LinkedList<Object>(); if (!Main.config.disableHelperMethods) { queue.add("imports(){import *;}\r\nimports();\r\n"); //Add log methods queue.add("debug(string){com.esotericsoftware.minlog.Log.debug(testHandle.getName(), string);}"); queue.add("error(string){com.esotericsoftware.minlog.Log.error(testHandle.getName(), string);}"); queue.add("warn(string){com.esotericsoftware.minlog.Log.warn(testHandle.getName(), string);}"); queue.add("info(string){com.esotericsoftware.minlog.Log.info(testHandle.getName(), string);}"); queue.add("trace(string){com.esotericsoftware.minlog.Log.trace(testHandle.getName(), string);}"); //Add (webDriver/selenium)/webClient variables queue.add( "if(testHandle.getDriver().equals(\"WebDriver\")){webDriver = testHandle.getWebDriver();} else if(testHandle.getDriver().equals(\"HTMLUnit\")){webClient = testHandle.getWebClient();}"); } //The before scripts for (String string : Main.config.before) { queue.add(new File(string)); } //The test before for (String string : test.before) { queue.add(new File(string)); } if (test.scriptCode != null) { queue.add(test.scriptCode); } //The test File scriptFile = new File(test.script); if (!scriptFile.exists()) { throw new FileNotFoundException("The script file \"" + test.script + "\" does not exist."); } else { queue.add(new File(scriptFile.getAbsolutePath())); } //The test after for (String string : test.after) { queue.add(new File(string)); } //The after for (String string : Main.config.after) { queue.add(new File(string)); } Log.debug("Queued " + Main.gson.toJson(queue)); Log.debug("Loading " + queue.size() + " external scripts"); for (Object object : queue) { if (object instanceof File) { if (((File) object).exists()) { Log.debug("Loading external script file \"" + object + "\""); stringBuilder.append("\r\n" + Main.Utils.readFile(((File) object).getAbsolutePath())); } else { Log.warn("External script file \"" + object + "\" does not exist."); } } else if (object instanceof String) { stringBuilder.append("\r\n" + object); } } test.scriptCode = stringBuilder.toString().replace("\r\n\r\n", "\r\n"); Log.debug("Final script \"" + test.scriptCode + "\""); return test; } public String getReport() { return testHandle.getReport(); } public Object execute() throws EvalError { Log.info("Starting " + name + " by " + author); Interpreter interpreter = new Interpreter(); this.testHandle = new TestHandle(this); interpreter.set("testHandle", testHandle); try { testHandle.report.result = interpreter.eval(this.scriptCode); } catch (Exception e) { testHandle.addNote(e.getMessage()); Log.warn(e.getMessage()); } testHandle.close(); return testHandle.report.result; } public class TestHandle { private WebDriver webDriver; private Report report; private WebDriverBackedSelenium selenium; public String getDriver() { return driver.name(); } private Driver driver = Driver.WebDriver; private WebClient webClient; public TestHandle(Test test) { this.report = new Report(test); this.driver = test.driver; this.initialize(); } public void setData(String key, Object data) { Test.data.put(key, data); } public Object getData(String key) { Log.debug("Getting data \"" + key + "\""); if (Test.data.containsKey(key)) { return Test.data.get(key); } return null; } public WebClient getWebClient() { Log.debug("Getting webClient"); if (!driver.equals(Driver.HTMLUnit)) { return null; } return webClient; } public String getName() { return name; } public void success() { this.report.result = true; } public void fail() throws TestFailException { this.report.result = false; throw new TestFailException(Main.Utils.getTimestamp()); } public String getReport() { return Main.gson.toJson(report); } public void addNote(String note) { addNote(note, Main.Utils.getTimestamp()); } public void addNote(String note, Timestamp timestamp) { this.report.notes.put(timestamp, note); } public String getLocator(String key) { Log.debug("Getting locator for \"" + key + "\""); if (locators.containsKey(key)) { return locators.get(key); } Log.warn("There was no locator present for \"" + key + "\""); return null; } public void log(LogLevel logLevel, String string) { switch (logLevel) { case error: Log.error(name, string); break; case warn: Log.warn(name, string); break; case info: Log.info(name, string); break; case debug: Log.debug(name, string); break; case trace: Log.trace(name, string); break; } } public String getProperty(String key) { Log.debug("Getting property \"" + key + "\""); if (properties.containsKey(key)) { return properties.get(key); } Log.warn("There was no property \"" + key + "\" present"); return null; } public WebDriverBackedSelenium getSelenium() { Log.debug("Getting selenium"); if (!driver.equals(Driver.WebDriver)) { return null; } return selenium; } public WebDriver getWebDriver() { Log.debug("Getting webDriver"); if (!driver.equals(Driver.WebDriver)) { return null; } return webDriver; } private void initialize() { Log.trace("initilizing testHandle"); switch (driver) { case WebDriver: if (proxy) { if (Main.config.proxySupport) { try { String proxyString = Main.Utils.Proxies.getProxy(); Proxy proxy = new org.openqa.selenium.Proxy(); proxy.setHttpProxy(proxyString).setFtpProxy(proxyString).setSslProxy(proxyString); DesiredCapabilities cap = new DesiredCapabilities(); cap.setCapability(CapabilityType.PROXY, proxy); webDriver = new FirefoxDriver(cap); } catch (Main.Utils.Proxies.NoProxyException e) { Log.error(e.getMessage() + " (continuing without one)"); webDriver = new FirefoxDriver(); } } else { Log.warn("Proxy is required by test, no proxies provided. Continuing without proxy"); webDriver = new FirefoxDriver(); } } else { webDriver = new FirefoxDriver(); } this.selenium = new WebDriverBackedSelenium(this.webDriver, baseUrl); break; case HTMLUnit: if (!Main.config.enableHTMLUnitWarnings) { LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(Level.OFF); java.util.logging.Logger.getLogger("org.apache.commons.httpclient").setLevel(Level.OFF); } if (proxy) { if (Main.config.proxySupport) { try { String proxyString = Main.Utils.Proxies.getProxy(); webClient = new WebClient(browserVersion, proxyString.split(":")[0], Integer.valueOf(proxyString.split(":")[1])); } catch (Main.Utils.Proxies.NoProxyException e) { Log.error(e.getMessage() + " (continuing without one)"); webClient = new WebClient(browserVersion); } } else { Log.warn("Proxy is required by test, no proxies provided. Continuing without proxy"); webClient = new WebClient(browserVersion); } } else { webClient = new WebClient(browserVersion); } if (!Main.config.enableHTMLUnitWarnings) { webClient.setIncorrectnessListener(new IncorrectnessListener() { @Override public void notify(String arg0, Object arg1) { // TODO Auto-generated method stub } }); webClient.setCssErrorHandler(new ErrorHandler() { @Override public void warning(CSSParseException exception) throws CSSException { } @Override public void error(CSSParseException exception) throws CSSException { } @Override public void fatalError(CSSParseException exception) throws CSSException { } }); webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() { @Override public void timeoutError(HtmlPage arg0, long arg1, long arg2) { // TODO Auto-generated method stub } @Override public void scriptException(HtmlPage arg0, ScriptException arg1) { // TODO Auto-generated method stub } @Override public void malformedScriptURL(HtmlPage arg0, String arg1, MalformedURLException arg2) { // TODO Auto-generated method stub } @Override public void loadScriptError(HtmlPage arg0, URL arg1, Exception arg2) { // TODO Auto-generated method stub } }); webClient.setHTMLParserListener(new HTMLParserListener() { @Override public void error(String s, URL url, String s1, int i, int i1, String s2) { } @Override public void warning(String s, URL url, String s1, int i, int i1, String s2) { } }); } break; } } private void close() { switch (driver) { case WebDriver: webDriver.close(); break; case HTMLUnit: webClient.closeAllWindows(); } } public class TestFailException extends Exception { public TestFailException(Timestamp timestamp) { addNote("Test failed.", timestamp); } } public class Report { @Expose public String test; @Expose public HashMap<Timestamp, String> notes = new HashMap<Timestamp, String>(); @Expose public Object result; public Report(Test test) { this.test = test.name; } } } }