package net.jsunit; import com.thoughtworks.selenium.DefaultSelenium; import com.thoughtworks.selenium.Selenium; import com.thoughtworks.selenium.Wait; import junit.framework.TestCase; import net.jsunit.configuration.CompositeConfigurationSource; import net.jsunit.configuration.DelegatingConfigurationSource; import net.jsunit.configuration.ServerConfiguration; import org.ho.yaml.Yaml; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SeleniumTest extends TestCase { protected JsUnitServer server; protected static Selenium selenium; protected Process tunnel_process; protected String tunnel_id; protected HashMap<String, String> seleniumConfig; public void setUp() throws Exception { super.setUp(); seleniumConfig = loadSeleniumConfig(System.getProperty("seleniumEnvironment")); startJsUnitServer(); if (seleniumConfig.get("selenium_server_address").equals("saucelabs.com")) { startSauceTunnel(); } startSeleniumClient(); } public void tearDown() throws Exception { stopSeleniumClient(); if (seleniumConfig.get("selenium_server_address").equals("saucelabs.com")) { stopSauceTunnel(); } stopJsUnitServer(); super.tearDown(); } private void startSauceTunnel() throws IOException { System.out.println("Starting sauce tunnel..."); tunnel_process = Runtime.getRuntime().exec("ruby sauce-tunnel-setup.rb"); String line; BufferedReader input = new BufferedReader (new InputStreamReader(tunnel_process.getInputStream())); Pattern pattern = Pattern.compile("\\[saucelabs-adapter\\] Tunnel ID (.*) for (.*) is up\\.$"); while ((line = input.readLine()) != null) { System.out.println(line); Matcher matcher = pattern.matcher(line); if (matcher.find()) { tunnel_id = matcher.group(1); seleniumConfig.put("application_address", matcher.group(2)); break; } } System.out.println("done starting tunnel, remote end is '" + seleniumConfig.get("application_address") + "'"); } private void stopSauceTunnel() throws IOException { System.out.println("stopping tunnel"); tunnel_process = Runtime.getRuntime().exec("ruby sauce-tunnel-delete.rb " + tunnel_id); String line; BufferedReader input = new BufferedReader (new InputStreamReader(tunnel_process.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } } public void testStandaloneRun() throws Exception { selenium.open("/jsunit/testRunner.html?testPage=/jsunit/tests/jsUnitTestSuite.html&autorun=true"); waitForStatus(); // window.frames['mainFrame'].frames['mainCounts'].frames['mainCountsRuns'].document.getElementById('content').innerHTML String runs = selenium.getEval("window.mainFrame.mainCounts.mainCountsRuns.document.getElementById('content').innerHTML").trim(); String fails = selenium.getEval("window.mainFrame.mainCounts.mainCountsFailures.document.getElementById('content').innerHTML").trim(); String errors = selenium.getEval("window.mainFrame.mainCounts.mainCountsErrors.document.getElementById('content').innerHTML").trim(); Pattern pattern = Pattern.compile("\\d+$"); Matcher matcher = pattern.matcher(runs); matcher.find(); Integer runCount = new Integer(matcher.group()); matcher = pattern.matcher(fails); matcher.find(); Integer failCount = new Integer(matcher.group()); matcher = pattern.matcher(errors); matcher.find(); Integer errorCount = new Integer(matcher.group()); System.out.printf("********** JSUnit tests complete, Runs: %s, Fails: %s, Errors: %s **********\n", runCount, failCount, errorCount); if (failCount + errorCount > 0) { String errorMessages = selenium.getEval("window.mainFrame.mainErrors.document.getElementsByName('problemsList')[0].innerHTML"); System.out.printf("Error messages: %s\n", errorMessages); } assertEquals(0, failCount + errorCount); } private HashMap<String, String>loadSeleniumConfig(String environment) throws Exception { String seleniumConfigFilePath = System.getProperty("seleniumConfigFilePath"); HashMap<String, Object> environments = (HashMap<String, Object>)Yaml.load(new File(seleniumConfigFilePath)); HashMap<String, String> config = (HashMap<String, String>)environments.get(environment); return config; } private void startJsUnitServer() throws Exception { server = new JsUnitServer(new ServerConfiguration(new DelegatingConfigurationSource(CompositeConfigurationSource.resolve()))); server.start(); } private void stopJsUnitServer() { if (server != null) { server.dispose(); } } private void startSeleniumClient() throws Exception { String host = seleniumConfig.get("selenium_server_address"); int port = Integer.parseInt(seleniumConfig.get("selenium_server_port")); String start_command; if (host.equals("saucelabs.com")) { start_command = "{" + "\"username\": \"" + seleniumConfig.get("saucelabs_username") + "\", " + "\"access-key\": \"" + seleniumConfig.get("saucelabs_access_key") + "\", " + "\"os\": \"" + seleniumConfig.get("saucelabs_browser_os") + "\", " + "\"browser\": \"" + seleniumConfig.get("saucelabs_browser") + "\", " + "\"browser-version\": \"" + seleniumConfig.get("saucelabs_browser_version") + "\"}"; } else { start_command = seleniumConfig.get("selenium_browser_key"); } String browser_url = "http://" + seleniumConfig.get("application_address") + ":" + seleniumConfig.get("application_port"); selenium = new DefaultSelenium(host, port, start_command, browser_url); selenium.start(); } private void stopSeleniumClient() { selenium.stop(); } private void waitForStatus() throws InterruptedException { new Wait() { public boolean until() { String statusContent = selenium.getEval("window.mainFrame.mainStatus.document.getElementById('content').innerHTML"); return statusContent.indexOf("Done") != -1; } }.wait("This didn't quite work"); } }