Author: j...@google.com Date: Thu Jul 9 18:23:27 2009 New Revision: 5709 Added: branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java (contents, props changed) branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java (contents, props changed) Modified: branches/htmlunit/user/src/com/google/gwt/junit/JUnitShell.java
Log: Initial work on getting HTMLUnit integrated into JUnitShell. Modified: branches/htmlunit/user/src/com/google/gwt/junit/JUnitShell.java ============================================================================== --- branches/htmlunit/user/src/com/google/gwt/junit/JUnitShell.java (original) +++ branches/htmlunit/user/src/com/google/gwt/junit/JUnitShell.java Thu Jul 9 18:23:27 2009 @@ -211,6 +211,58 @@ registerHandler(new ArgHandlerString() { @Override public String getPurpose() { + return "Runs hosted mode via HTMLUnit given a list of browsers; " + + "e.g. IE6,IE7,FF2,FF3..."; + } + + @Override + public String getTag() { + return "-htmlunithosted"; + } + + @Override + public String[] getTagArgs() { + return new String[] {"browserNames"}; + } + + @Override + public boolean setString(String str) { + String[] targets = str.split(","); + numClients = targets.length; + runStyle = RunStyleHtmlUnitHosted.create(JUnitShell.this, targets); + return runStyle != null; + } + }); + + registerHandler(new ArgHandlerString() { + @Override + public String getPurpose() { + return "Runs web mode via HTMLUnit given a list of browsers; " + + "e.g. IE6,IE7,FF2,FF3..."; + } + + @Override + public String getTag() { + return "-htmlunit"; + } + + @Override + public String[] getTagArgs() { + return new String[] {"browserNames"}; + } + + @Override + public boolean setString(String str) { + String[] targets = str.split(","); + numClients = targets.length; + runStyle = RunStyleHtmlUnit.create(JUnitShell.this, targets); + return runStyle != null; + } + }); + + registerHandler(new ArgHandlerString() { + @Override + public String getPurpose() { return "Run external browsers in web mode (pass a comma separated list of executables.)"; } Added: branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java ============================================================================== --- (empty file) +++ branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java Thu Jul 9 18:23:27 2009 @@ -0,0 +1,160 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.junit; + +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.UnableToCompleteException; + +import com.gargoylesoftware.htmlunit.AlertHandler; +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.IncorrectnessListener; +import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController; +import com.gargoylesoftware.htmlunit.OnbeforeunloadHandler; +import com.gargoylesoftware.htmlunit.Page; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.HtmlPage; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Launches a web-mode test via HTMLUnit. + */ +public class RunStyleHtmlUnit extends RunStyleRemote { + + protected class HtmlUnitThread extends Thread implements AlertHandler, + IncorrectnessListener, OnbeforeunloadHandler { + + private BrowserVersion browser; + private String url; + private Object waitForUnload = new Object(); + + public HtmlUnitThread(BrowserVersion browser, String url) { + this.browser = browser; + this.url = url; + start(); + } + + public void handleAlert(Page page, String message) { + shell.getTopLogger().log(TreeLogger.ERROR, "Alert: " + message); + } + + public boolean handleEvent(Page page, String returnValue) { + synchronized (waitForUnload) { + waitForUnload.notifyAll(); + } + return true; + } + + public void notify(String message, Object origin) { + shell.getTopLogger().log(TreeLogger.WARN, message); + } + + @Override + public void run() { + WebClient webClient = new WebClient(browser); + webClient.setAlertHandler(this); + webClient.setIncorrectnessListener(this); + webClient.setThrowExceptionOnFailingStatusCode(false); + webClient.setThrowExceptionOnScriptError(true); + webClient.setOnbeforeunloadHandler(this); + webClient.setAjaxController(new NicelyResynchronizingAjaxController()); + setupWebClient(webClient); + try { + Page page = webClient.getPage(url); + // TODO(jat): is this necessary? + webClient.waitForBackgroundJavaScriptStartingBefore(2000); + page.getEnclosingWindow().getJobManager().waitForJobs(60000); + shell.getTopLogger().log(TreeLogger.INFO, "getPage returned " + + ((HtmlPage) page).asXml()); + } catch (FailingHttpStatusCodeException e) { + shell.getTopLogger().log(TreeLogger.ERROR, + "HTTP request failed", e); + return; + } catch (MalformedURLException e) { + shell.getTopLogger().log(TreeLogger.ERROR, + "Bad URL", e); + return; + } catch (IOException e) { + shell.getTopLogger().log(TreeLogger.ERROR, + "I/O error on HTTP request", e); + return; + } +// synchronized (waitForUnload) { +// try { +// waitForUnload.wait(); +// } catch (InterruptedException e) { +// shell.getTopLogger().log(TreeLogger.ERROR, "Interrupted wait", e); +// } +// } + } + + /** + * Additional setup of the WebClient before starting test. + * + * @param webClient + */ + protected void setupWebClient(WebClient webClient) { + } + } + + /** + * Create a RunStyleHtmlUnit instance with a list of browsers + * + * @param shell + * @param targetsIn + * @return RunStyle instance + */ + public static RunStyle create(JUnitShell shell, String[] targetsIn) { + BrowserVersion[] browsers = new BrowserVersion[targetsIn.length]; + for (int i = 0; i < targetsIn.length; ++i) { + String browserName = targetsIn[i]; + BrowserVersion browser = BrowserVersion.FIREFOX_2; + // TODO(jat): find the browser name in BrowserVersion + browsers[i] = browser; + } + RunStyleHtmlUnit runStyle = new RunStyleHtmlUnit(shell, browsers); + return runStyle; + } + + private BrowserVersion[] browsers; + private List<Thread> threads = new ArrayList<Thread>(); + + protected RunStyleHtmlUnit(JUnitShell shell, BrowserVersion[] browsers) { + super(shell); + this.browsers = browsers; + } + + @Override + public void launchModule(String moduleName) throws UnableToCompleteException { + for (BrowserVersion browser : browsers) { + String url = getMyUrl(moduleName); + shell.getTopLogger().log(TreeLogger.INFO, "Starting " + url + + " on browser " + browser); + threads.add(new HtmlUnitThread(browser, url)); + } + } + + @Override + public void maybeCompileModule(String moduleName) + throws UnableToCompleteException { + // TODO(jat): substitute appropriate user agent + shell.compileForWebMode(moduleName, "gecko1_8"); + } +} Added: branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java ============================================================================== --- (empty file) +++ branches/htmlunit/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java Thu Jul 9 18:23:27 2009 @@ -0,0 +1,153 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.junit; + +import com.google.gwt.core.ext.UnableToCompleteException; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.TopLevelWindow; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.javascript.host.Window; + +import net.sourceforge.htmlunit.corejs.javascript.Context; +import net.sourceforge.htmlunit.corejs.javascript.NativeJavaMethod; +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; +import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; + +import java.lang.reflect.Method; + +/** + * Runstyle for HTMLUnit in hosted mode. + */ +public class RunStyleHtmlUnitHosted extends RunStyleHtmlUnit { + + private static class PluginObject implements Scriptable { + + private Scriptable parent; + private Scriptable prototype; + + public PluginObject(Scriptable parent, Scriptable prototype) { + this.parent = parent; + this.prototype = prototype; + } + + public void delete(String name) { + } + + public void delete(int index) { + } + + public Object get(String name, Scriptable start) { + if (name.equals("connect")) { + Method connectMethod = null; + try { + connectMethod = PluginObject.class.getMethod("connect", + String.class, String.class, Object.class); + } catch (SecurityException e) { + // TODO(jat) Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO(jat) Auto-generated catch block + e.printStackTrace(); + } + return new NativeJavaMethod(connectMethod, "connect"); + } + return Context.getUndefinedValue(); + } + + public Object get(int index, Scriptable start) { + return Context.getUndefinedValue(); + } + + public String getClassName() { + return "Plugin"; + } + + public Object getDefaultValue(Class<?> hint) { + // TODO(jat) Auto-generated method stub + return Context.getUndefinedValue(); + } + + public Object[] getIds() { + return new Object[] { "connect" }; + } + + public Scriptable getParentScope() { + return parent; + } + + public Scriptable getPrototype() { + return prototype; + } + + public boolean has(String name, Scriptable start) { + return name.equals("connect"); + } + + public boolean has(int index, Scriptable start) { + return false; + } + + public boolean hasInstance(Scriptable instance) { + return false; + } + + public void put(String name, Scriptable start, Object value) { + } + + public void put(int index, Scriptable start, Object value) { + } + + public void setParentScope(Scriptable parent) { + this.parent = parent; + } + + public void setPrototype(Scriptable prototype) { + this.prototype = prototype; + } + } + + protected class HtmlUnitHostedThread extends HtmlUnitThread { + + public HtmlUnitHostedThread(BrowserVersion browser, String url) { + super(browser, url); + } + + @Override + protected void setupWebClient(WebClient webClient) { + TopLevelWindow topLevelWindow = new TopLevelWindow("", webClient); + Window scriptObject = (Window) topLevelWindow.getScriptObject(); + Scriptable objectPrototype = ScriptableObject.getObjectPrototype( + scriptObject); + Scriptable pluginObject = new PluginObject(scriptObject, + objectPrototype); + scriptObject.defineProperty("__gwt_HostedModePlugin", pluginObject, + ScriptableObject.READONLY); + webClient.setCurrentWindow(topLevelWindow); + } + } + + protected RunStyleHtmlUnitHosted(JUnitShell shell, + BrowserVersion[] browsers) { + super(shell, browsers); + } + + @Override + public void maybeCompileModule(String moduleName) + throws UnableToCompleteException { + // No compilation needed for hosted mode + } +} --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---