/*
* Copyright 2017 OmniFaces
*
* 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 org.omnifaces.test;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.jboss.arquillian.graphene.Graphene.guardNoRequest;
import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
import static org.omnifaces.test.OmniFacesIT.FacesConfig.withMessageBundle;
import java.io.File;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@RunWith(Arquillian.class)
public abstract class OmniFacesIT {
@Drone
protected WebDriver browser;
@ArquillianResource
protected URL baseURL;
@Before
public void init() {
open(getClass().getSimpleName() + ".xhtml");
}
protected void open(String pageName) {
browser.get(baseURL + pageName);
waitGui(browser);
}
protected String openNewTab(WebElement elementWhichOpensNewTab) {
Set<String> oldTabs = browser.getWindowHandles();
guardNoRequest(elementWhichOpensNewTab).click();
Set<String> newTabs = new HashSet<>(browser.getWindowHandles());
newTabs.removeAll(oldTabs); // Just to be sure; it's nowhere in Selenium API specified whether tabs are ordered.
String newTab = newTabs.iterator().next();
browser.switchTo().window(newTab);
waitGui(browser);
return newTab;
}
protected void closeCurrentTabAndSwitchTo(String tabToSwitch) {
browser.close();
browser.switchTo().window(tabToSwitch);
}
/**
* Work around because Selenium WebDriver API doesn't support triggering JS events.
*/
protected void triggerOnchange(WebElement input, WebElement messages) {
clearMessages(messages);
executeScript("document.getElementById('" + input.getAttribute("id") + "').onchange();");
waitUntilMessages(messages);
}
/**
* Work around because Selenium WebDriver API doesn't recognize iframe based ajax upload in guard.
*/
protected void guardAjaxUpload(WebElement submit, WebElement messages) {
clearMessages(messages);
submit.click();
waitUntilMessages(messages);
}
protected void waitUntilMessages(WebElement messages) {
waitGui(browser).withTimeout(3, SECONDS).until().element(messages).text().not().equalTo("");
}
protected void executeScript(String script) {
((JavascriptExecutor) browser).executeScript(script);
}
private void clearMessages(WebElement messages) {
executeScript("document.getElementById('" + messages.getAttribute("id") + "').innerHTML='';");
}
protected static String stripJsessionid(String url) {
return url.split(";jsessionid=", 2)[0];
}
protected static boolean isTomee() {
return "tomee".equals(System.getProperty("profile.id"));
}
protected static <T extends OmniFacesIT> WebArchive createWebArchive(Class<T> testClass) {
return buildWebArchive(testClass).createDeployment();
}
protected static <T extends OmniFacesIT> ArchiveBuilder buildWebArchive(Class<T> testClass) {
return new ArchiveBuilder(testClass);
}
protected static class ArchiveBuilder {
private WebArchive archive;
private boolean facesConfigSet;
private boolean webXmlSet;
private <T extends OmniFacesIT> ArchiveBuilder(Class<T> testClass) {
String packageName = testClass.getPackage().getName();
String className = testClass.getSimpleName();
String warName = className + ".war";
archive = create(WebArchive.class, warName)
.addPackage(packageName)
.deleteClass(testClass)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsLibrary(new File(System.getProperty("omnifaces.jar")));
addWebResources(new File(testClass.getClassLoader().getResource(packageName).getFile()), "");
}
private void addWebResources(File root, String directory) {
for (File file : root.listFiles()) {
String path = directory + "/" + file.getName();
if (file.isFile()) {
archive.addAsWebResource(file, path);
}
else if (file.isDirectory()) {
addWebResources(file, path);
}
}
}
public ArchiveBuilder withFacesConfig(FacesConfig facesConfig) {
if (facesConfigSet) {
throw new IllegalStateException("There can be only one faces-config.xml");
}
archive.addAsWebInfResource("WEB-INF/faces-config.xml/" + facesConfig.name() + ".xml", "faces-config.xml");
if (facesConfig == withMessageBundle) {
archive.addAsResource("messages.properties");
}
facesConfigSet = true;
return this;
}
public ArchiveBuilder withWebXml(WebXml webXml) {
if (webXmlSet) {
throw new IllegalStateException("There can be only one web.xml");
}
archive.setWebXML("WEB-INF/web.xml/" + webXml.name() + ".xml");
switch (webXml) {
case withErrorPage:
archive.addAsWebInfResource("WEB-INF/500.xhtml");
break;
case withFacesViews:
case withMultiViews:
archive.addAsWebInfResource("WEB-INF/404.xhtml");
break;
default:
break;
}
webXmlSet = true;
return this;
}
public WebArchive createDeployment() {
if (!facesConfigSet) {
withFacesConfig(FacesConfig.basic);
}
if (!webXmlSet) {
withWebXml(WebXml.basic);
}
return archive;
}
}
public static enum FacesConfig {
basic,
withFullAjaxExceptionHandler,
withCombinedResourceHandler,
withMessageBundle,
withCDNResourceHandler;
}
public static enum WebXml {
basic,
withErrorPage,
withFacesViews,
withMultiViews,
withThreeViewsInSession,
withSocket,
withClientStateSaving,
withCDNResources;
}
}