package org.richfaces.integration.javascript;
import static org.junit.Assert.assertEquals;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.Graphene;
import org.jboss.arquillian.graphene.findby.FindByJQuery;
import org.jboss.arquillian.graphene.javascript.JavaScript;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.richfaces.deployment.CoreDeployment;
import org.richfaces.shrinkwrap.descriptor.FaceletAsset;
@RunWith(Arquillian.class)
@RunAsClient
public class ITAjaxSubmissionCallbacks {
@Drone
private WebDriver driver;
@ArquillianResource
private URL contextPath;
@JavaScript
private Callbacks callbacks;
@FindByJQuery("input:visible")
private WebElement input;
@FindBy(id = "out")
private WebElement output;
@FindBy(tagName = "body")
private WebElement body;
private static final String FORM_ID = "form1";
private static final List<String> EVENT_CALLBACKS = Arrays.asList(new String[]{ "ajaxsubmit", "ajaxbegin", "ajaxbeforedomupdate", "ajaxcomplete" });
@Deployment(testable = false)
public static WebArchive deployment() {
CoreDeployment deployment = new CoreDeployment(ITAjaxSubmissionCallbacks.class);
deployment.withA4jComponents();
deployment.archive().addAsWebResource(buildPage(true, true), "documentAndFormScoped.xhtml");
deployment.archive().addAsWebResource(buildPage(true, false), "formScoped.xhtml");
deployment.archive().addAsWebResource(buildPage(false, true), "documentScoped.xhtml");
return deployment.getFinalArchive();
}
@Test
public void should_register_ajax_callbacks_both_on_form_and_document_object() {
// when
loadThePageAndWriteTextToInput("documentAndFormScoped.jsf");
// then
assertCorrectCallbacks(true, callbacks.getDocumentScopedCallbacksCalled());
assertCorrectCallbacks(true, callbacks.getFormScopedCallbacksCalled());
}
@Test
public void should_register_ajax_callbacks_on_form() {
// when
loadThePageAndWriteTextToInput("formScoped.jsf");
// then
assertCorrectCallbacks(false, callbacks.getDocumentScopedCallbacksCalled());
assertCorrectCallbacks(true, callbacks.getFormScopedCallbacksCalled());
}
@Test
public void should_register_ajax_callbacks_on_document_object() {
// when
loadThePageAndWriteTextToInput("documentScoped.jsf");
// then
assertCorrectCallbacks(true, callbacks.getDocumentScopedCallbacksCalled());
assertCorrectCallbacks(false, callbacks.getFormScopedCallbacksCalled());
}
private void loadThePageAndWriteTextToInput(String pageName) {
driver.get(contextPath.toExternalForm() + pageName);
String toWrite = "text";
for (char ch : toWrite.toCharArray()) {
resetCallbacks();
Graphene.guardAjax(input).sendKeys(Character.toString(ch));
}
}
private void assertCorrectCallbacks(boolean registered, String callbacksToControll) {
if (registered) {
assertEquals(Arrays.asList(callbacksToControll.trim().split(" ")), EVENT_CALLBACKS);
} else {
assertEquals("Event callback was called even when it was not registered: " + callbacksToControll, " ", callbacksToControll);
}
}
private static FaceletAsset buildPage(boolean formScopedRegistration, boolean pageScopedRegistration) {
FaceletAsset p = new FaceletAsset();
p.head("<h:outputScript library='javax.faces' name='jsf.js' />");
p.head("<h:outputScript library='org.richfaces' name='jquery.js' />");
p.head("<h:outputScript library='org.richfaces' name='richfaces.js' />");
p.body("<h:outputScript>");
p.body(" window.RichFaces.jQuery(document).ready(function() {");
if (formScopedRegistration) {
for (String eventCallback : EVENT_CALLBACKS) {
registerCallBackToForm(p, eventCallback);
}
}
if (pageScopedRegistration) {
for (String eventCallback : EVENT_CALLBACKS) {
registerCallBackToDocumentObject(p, eventCallback);
}
}
p.body(" document.formScopedCallbacksCalled = ' ';");
p.body(" document.documentScopedCallbacksCalled = ' ';");
p.body("});");
p.body("</h:outputScript>");
p.body("<h:form prependId=\"false\" id=\"" + FORM_ID + "\">");
p.body(" <h:inputText value=\"#{requestScope.property}\">");
p.body(" <a4j:ajax event=\"keyup\" render=\"out\" />");
p.body(" </h:inputText>");
p.body(" <h:outputText value=\"#{requestScope.property}\" id=\"out\" />");
p.body("</h:form>");
return p;
}
private static void registerCallBackToForm(FaceletAsset p, String eventCallback) {
p.body(" window.RichFaces.jQuery(document.getElementById('" + FORM_ID + "')).on(\"" + eventCallback + "\", function() {");
p.body(" document.formScopedCallbacksCalled += '" + eventCallback + " ';");
p.body(" });");
}
private static void registerCallBackToDocumentObject(FaceletAsset p, String eventCallback) {
p.body(" window.RichFaces.jQuery(document).on(\"" + eventCallback + "\", function() {");
p.body(" document.documentScopedCallbacksCalled += '" + eventCallback + " ';");
p.body(" });");
}
private void resetCallbacks() {
callbacks.setDocumentScopedCallbacksCalled(" ");
callbacks.setFormScopedCallbacksCalled(" ");
}
@JavaScript("document")
public interface Callbacks {
String getFormScopedCallbacksCalled();
String getDocumentScopedCallbacksCalled();
void setFormScopedCallbacksCalled(String s);
void setDocumentScopedCallbacksCalled(String s);
}
}