/* * $Id$ * JBoss, Home of Professional Open Source * Copyright 2010, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.test.qunit; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.MockWebConnection; import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController; import com.gargoylesoftware.htmlunit.ScriptResult; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlPage; /** * <p class="changed_added_4_0">This class represents qunit test environment ( html page, java script libraries ... ) </p> * @author asmirnov@exadel.com * */ public class Qunit implements MethodRule { /** * <p class="changed_added_4_0"></p> * @author asmirnov@exadel.com * */ public static final class Builder { private final Qunit rule = new Qunit(); public Builder content(String content) { rule.setHtmlContent(new ContentRef(content)); return this; } public Builder contentResource(String src){ rule.setHtmlContent(new ResourceRef(src)); return this; } public Builder load(URL src) { rule.addScript(new URLRef(src)); return this; } public Builder loadResource(String src) { rule.addScript(new ResourceRef(src)); return this; } public Builder loadJsfResource(String name) { rule.addScript(new ResourceRef("/META-INF/resources/"+name)); return this; } public Builder loadJsfResource(String name,String library) { rule.addScript(new ResourceRef("/META-INF/resources/"+library+"/"+name)); return this; } public Builder loadExternal(String src) { rule.addScript(new ExternalRef(src)); return this; } public Builder loadContent(String foo) { rule.addScript(new ContentRef(foo)); return this; } public Builder emulate(BrowserVersion browser){ rule.browser = browser; return this; } public Qunit build(){ return rule; } } /** * <p class="changed_added_4_0">Html content for JavaScript tests.</p> * */ private ScriptRef htmlContent = new ContentRef(""); private BrowserVersion browser = BrowserVersion.getDefault(); private List<ScriptRef> scripts = new ArrayList<ScriptRef>(); private WebClient webClient; private HtmlPage page; private MockWebConnection mockConnection; public static final String DEFAULT_URL = "http://localhost"; protected Qunit(){ ; } public Statement apply(final Statement base, final FrameworkMethod method, final Object target) { return new Statement() { @Override public void evaluate() throws Throwable { try { System.out.println("Run Statement "+base.getClass().getName()+" for method "+method.getName()); setupQunit(method,target); base.evaluate(); } finally { thearDownQunit(method,target); } } }; } protected void thearDownQunit(FrameworkMethod method, Object target) { if(null != page){ webClient.closeAllWindows(); } } protected void setupQunit(FrameworkMethod method, Object target) throws FailingHttpStatusCodeException, IOException { URL URL = new URL(DEFAULT_URL+"/"); setupWebClient(); String content = buildContent(method,target); mockConnection.setResponse(URL, content); page = webClient.getPage(URL); webClient.waitForBackgroundJavaScriptStartingBefore(4 * 60 * 1000); } private void setupWebClient() { webClient = new WebClient(browser); mockConnection = new MockWebConnection(); webClient.setWebConnection(mockConnection); webClient.setAjaxController(new NicelyResynchronizingAjaxController()); } private String buildContent(FrameworkMethod method, Object target) { StringBuilder content = new StringBuilder(); content.append("<html><head><title>").append(method.getName()).append("</title>"); appendScripts(content,target); content.append("</head><body>").append(getHtmlContent(target)).append("</body></html>"); return content.toString(); } private void appendScripts(StringBuilder content, Object target) { for (ScriptRef script : this.scripts) { content.append("<script type=\"text/javascript\" src=\""); URL url = script.getScript(target); content.append(url.toExternalForm()); content.append("\" ></script>\n"); mockConnection.setResponse(url, script.getContent(target), "application/javascript"); } } private URL calculateDefaultURL(Object target){ Class<? extends Object> targetClass = target.getClass(); String resourceName = targetClass.getSimpleName()+".class"; return targetClass.getResource(resourceName); } /** * <p class="changed_added_4_0"></p> * @param target * @return the htmlContent */ protected String getHtmlContent(Object target) { return this.htmlContent.getContent(target); } /** * <p class="changed_added_4_0"></p> * @param htmlContent the htmlContent to set */ private void setHtmlContent(ScriptRef htmlContent) { this.htmlContent = htmlContent; } /** * <p class="changed_added_4_0">Append script to page libraries by URL</p> * @param src */ private void addScript(ScriptRef src){ scripts.add(src); } /** * <p class="changed_added_4_0">Run JavaScript expression in page context and returns result</p> * @param script * @return */ public Object runScript(String script){ ScriptResult scriptResult = page.executeJavaScript(script); page = (HtmlPage) scriptResult.getNewPage(); return scriptResult.getJavaScriptResult(); } /** * <p class="changed_added_4_0"></p> * @return the page */ public HtmlPage getPage() { return this.page; } public static Builder builder(){ return new Builder(); } }