org.richfaces.tests.metamer.ftest.AbstractGrapheneTest.java Source code

Java tutorial

Introduction

Here is the source code for org.richfaces.tests.metamer.ftest.AbstractGrapheneTest.java

Source

/*******************************************************************************
 * JBoss, Home of Professional Open Source
 * Copyright 2010-2013, 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.richfaces.tests.metamer.ftest;

import static org.jboss.arquillian.ajocado.Graphene.alertPresent;
import static org.jboss.arquillian.ajocado.Graphene.elementPresent;
import static org.jboss.arquillian.ajocado.Graphene.guardHttp;
import static org.jboss.arquillian.ajocado.Graphene.guardXhr;
import static org.jboss.arquillian.ajocado.Graphene.id;
import static org.jboss.arquillian.ajocado.Graphene.jq;
import static org.jboss.arquillian.ajocado.Graphene.waitGui;
import static org.jboss.arquillian.ajocado.dom.Event.CLICK;
import static org.jboss.arquillian.ajocado.dom.Event.DBLCLICK;
import static org.jboss.arquillian.ajocado.dom.Event.MOUSEDOWN;
import static org.jboss.arquillian.ajocado.dom.Event.MOUSEMOVE;
import static org.jboss.arquillian.ajocado.dom.Event.MOUSEOUT;
import static org.jboss.arquillian.ajocado.dom.Event.MOUSEOVER;
import static org.jboss.arquillian.ajocado.dom.Event.MOUSEUP;
import static org.jboss.arquillian.ajocado.format.SimplifiedFormat.format;
import static org.jboss.arquillian.ajocado.utils.URLUtils.buildUrl;
import static org.jboss.test.selenium.locator.reference.ReferencedLocator.ref;
import static org.richfaces.tests.metamer.ftest.attributes.AttributeList.basicAttributes;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.LocaleUtils;
import org.jboss.arquillian.ajocado.browser.BrowserType;
import org.jboss.arquillian.ajocado.dom.Attribute;
import org.jboss.arquillian.ajocado.dom.Event;
import org.jboss.arquillian.ajocado.framework.GrapheneSelenium;
import org.jboss.arquillian.ajocado.framework.SystemPropertiesConfiguration;
import org.jboss.arquillian.ajocado.javascript.JavaScript;
import org.jboss.arquillian.ajocado.locator.JQueryLocator;
import org.jboss.arquillian.ajocado.locator.attribute.AttributeLocator;
import org.jboss.arquillian.ajocado.locator.element.ElementLocator;
import org.jboss.arquillian.ajocado.locator.element.ExtendedLocator;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.test.selenium.ScreenshotInterceptor;
import org.jboss.test.selenium.locator.reference.ReferencedLocator;
import org.jboss.test.selenium.waiting.EventFiredCondition;
import org.richfaces.tests.metamer.ftest.attributes.AttributeEnum;
import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;

/**
 * Abstract test case used as a basis for majority of test cases.
 *
 * @author <a href="mailto:ppitonak@redhat.com">Pavol Pitonak</a>
 * @version $Revision: 22749 $
 */
public abstract class AbstractGrapheneTest extends AbstractMetamerTest {

    @Drone
    protected GrapheneSelenium selenium;
    protected ScreenshotInterceptor screenshotInterceptor = new ScreenshotInterceptor();
    protected PhaseInfo phaseInfo = new PhaseInfo();

    /**
     * Opens the tested page. If templates is not empty nor null, it appends url parameter with templates.
     *
     * @param templates
     *            templates that will be used for test, e.g. "red_div"
     */
    @BeforeMethod(alwaysRun = true)
    public void loadPage(Object[] templates) {
        if (selenium == null) {
            throw new SkipException("selenium isn't initialized");
        }

        selenium.open(buildUrl(getTestUrl() + "?templates=" + template.toString()));
        selenium.waitForPageToLoad(TIMEOUT);
    }

    @Parameters("takeScreenshots")
    @BeforeMethod(alwaysRun = true, dependsOnMethods = { "loadPage" })
    public void enableScreenshots(@Optional("false") String takeScreenshots, Method method) {
        if (!"false".equals(takeScreenshots)) {
            screenshotInterceptor.setMethod(method);
            selenium.getCommandInterceptionProxy().registerInterceptor(screenshotInterceptor);
        }
    }

    /**
     * Invalidates session by clicking on a button on tested page.
     */
    @AfterMethod(alwaysRun = true)
    public void invalidateSession() {
        selenium.deleteAllVisibleCookies();
    }

    /**
     * Forces the current thread sleep for given time.
     *
     * @param millis
     *            number of miliseconds for which the thread will sleep
     */
    protected void waitFor(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Do a full page refresh (regular HTTP request) by triggering a command with no action bound.
     */
    public void fullPageRefresh() {
        waitGui.until(elementPresent.locator(fullPageRefreshIcon));
        guardHttp(selenium).click(fullPageRefreshIcon);
    }

    /**
     * Rerender all content of the page (AJAX request) by trigerring a command with no action but render bound.
     */
    public void rerenderAll() {
        waitGui.until(elementPresent.locator(rerenderAllIcon));
        guardXhr(selenium).click(rerenderAllIcon);
    }

    /**
     * A helper method for testing javascripts events. It sets alert('testedevent') to the input field for given event
     * and fires the event. Then it checks the message in the alert dialog.
     *
     * @param event
     *            JavaScript event to be tested
     * @param element
     *            locator of tested element
     */
    protected void testFireEvent(Event event, ElementLocator<?> element) {
        testFireEvent(event, element, event.getEventName());
    }

    /**
     * A helper method for testing javascripts events. It sets alert('testedevent') to the input field for given event
     * and fires the event. Then it checks the message in the alert dialog.
     *
     * @param event
     *            JavaScript event to be tested
     * @param element
     *            locator of tested element
     * @param attributeName
     *            name of the attribute that should be set
     */
    protected void testFireEvent(Event event, ElementLocator<?> element, String attributeName) {
        ElementLocator<?> eventInput = pjq("input[id$=on" + attributeName + "Input]");
        String value = "metamerEvents += \"" + event.getEventName() + " \"";

        guardHttp(selenium).type(eventInput, value);

        selenium.fireEvent(element, event);

        waitGui.failWith("Attribute on" + attributeName + " does not work correctly")
                .until(new EventFiredCondition(event));
    }

    /**
     * Returns the locale of the tested page
     *
     * @return the locale of the tested page
     */
    public Locale getLocale() {
        String localeString = selenium.getText(id("locale"));
        return LocaleUtils.toLocale(localeString);
    }

    /**
     * A helper method for testing attribute "style" or similar. It sets "background-color: yellow; font-size: 1.5em;"
     * to the input field and checks that it was changed on the page.
     *
     * @param element
     *            locator of tested element
     * @param attribute
     *            name of the attribute that will be set (e.g. style, headerStyle, itemContentStyle)
     */
    protected void testStyle(ElementLocator<?> element, BasicAttributes attribute) {
        final String value = "background-color: yellow; font-size: 1.5em;";

        basicAttributes.set(attribute, value);

        AttributeLocator<?> styleAttr = element.getAttribute(Attribute.STYLE);
        assertTrue(selenium.getAttribute(styleAttr).contains(value),
                "Attribute style should contain \"" + value + "\"");
    }

    /**
     * A helper method for testing attribute "style". It sets "background-color: yellow; font-size: 1.5em;" to the input
     * field and checks that it was changed on the page.
     *
     * @param element
     *            locator of tested element
     */
    protected void testStyle(ElementLocator<?> element) {
        testStyle(element, BasicAttributes.style);
    }

    /**
     * A helper method for testing attribute "class" or similar. It sets "metamer-ftest-class" to the input field and
     * checks that it was changed on the page.
     *
     * @param element
     *            locator of tested element
     * @param attribute
     *            name of the attribute that will be set (e.g. styleClass, headerClass, itemContentClass)
     */
    protected void testStyleClass(ExtendedLocator<JQueryLocator> element, BasicAttributes attribute) {
        final String styleClass = "metamer-ftest-class";

        basicAttributes.set(attribute, styleClass);

        JQueryLocator elementWhichHasntThatClass = jq(element.getRawLocator() + ":not(.{0})").format(styleClass);
        assertTrue(selenium.isElementPresent(element));
        assertFalse(selenium.isElementPresent(elementWhichHasntThatClass));
    }

    /**
     * A helper method for testing attribute "class". It sets "metamer-ftest-class" to the input field and checks that
     * it was changed on the page. This method is wrapping {@link #testStyleClass(ExtendedLocator, BasicAttributes)}
     *
     * @param element
     *            locator of tested element
     */
    protected void testStyleClass(ExtendedLocator<JQueryLocator> element) {
        testStyleClass(element, BasicAttributes.styleClass);
    }

    /**
     * Tests onrequest (e.g. onsubmit, onrequest...) events by using javascript functions. First fills Metamer's input
     * for according component attribute with testing value, then does an action, which should end by throwing a testing
     * event and then wait for the event if it was really launched
     *
     * @param eventAttribute
     *            event attribute (e.g. onsubmit, onrequest, onbeforedomupdate...)
     * @param action
     *            action wich leads to launching an event
     */
    public void testRequestEvent(AttributeEnum eventAttribute, IEventLaunchAction action) {
        testRequestEventBefore(eventAttribute);
        action.launchAction();
        testRequestEventAfter(eventAttribute);
    }

    public void testRequestEventsBefore(String... events) {
        for (String event : events) {
            ReferencedLocator<JQueryLocator> input = ref(attributesRoot, "input[type=text][id$=on{0}Input]");
            input = input.format(event);
            selenium.type(input, format("metamerEvents += \"{0} \"", event));
            selenium.waitForPageToLoad();
        }

        selenium.getEval(new JavaScript("window.metamerEvents = \"\";"));
    }

    public void testRequestEventBefore(AttributeEnum eventAttribute) {
        ReferencedLocator<JQueryLocator> input = ref(attributesRoot, "input[type=text][id$={0}Input]");
        input = input.format(eventAttribute.toString().trim());
        selenium.type(input, format("metamerEvents += \"{0} \"", eventAttribute.toString()));
        selenium.waitForPageToLoad();
        selenium.getEval(new JavaScript("window.metamerEvents = \"\";"));
    }

    public void testRequestEventsBeforeByAlert(String... events) {
        for (String event : events) {
            ReferencedLocator<JQueryLocator> input = ref(attributesRoot, "input[type=text][id$=on{0}Input]");
            input = input.format(event);
            selenium.type(input, format("alert('{0}')", event));
            selenium.waitForPageToLoad();
        }
    }

    public void testRequestEventsAfter(String... events) {
        String[] actualEvents = selenium.getEval(new JavaScript("window.metamerEvents")).split(" ");
        assertEquals(actualEvents, events, format("The events ({0}) don't came in right order ({1})",
                Arrays.deepToString(actualEvents), Arrays.deepToString(events)));
    }

    public void testRequestEventAfter(AttributeEnum eventAttribute) {
        waitGui.failWith("Attribute on" + eventAttribute + " does not work correctly")
                .until(new EventFiredCondition(new Event(eventAttribute.toString())));
    }

    public void testRequestEventsAfterByAlert(String... events) {
        List<String> list = new LinkedList<String>();

        for (int i = 0; i < events.length; i++) {
            waitGui.dontFail().until(alertPresent);
            if (selenium.isAlertPresent()) {
                list.add(selenium.getAlert());
            }
        }

        String[] actualEvents = list.toArray(new String[list.size()]);
        assertEquals(actualEvents, events, format("The events ({0}) don't came in right order ({1})",
                Arrays.deepToString(actualEvents), Arrays.deepToString(events)));
    }

    /**
     * A helper method for testing attribute "dir". It tries null, ltr and rtl.
     *
     * @param element
     *            locator of tested element
     */
    protected void testDir(ElementLocator<?> element) {
        ElementLocator<?> ltrInput = ref(attributesRoot, "input[type=radio][name$=dirInput][value=ltr]");
        ElementLocator<?> rtlInput = ref(attributesRoot, "input[type=radio][name$=dirInput][value=rtl]");

        AttributeLocator<?> dirAttribute = element.getAttribute(new Attribute("dir"));

        // dir = null
        assertFalse(selenium.isAttributePresent(dirAttribute), "Attribute dir should not be present.");

        // dir = ltr
        selenium.click(ltrInput);
        selenium.waitForPageToLoad();
        assertTrue(selenium.isAttributePresent(dirAttribute), "Attribute dir should be present.");
        String value = selenium.getAttribute(dirAttribute);
        assertEquals(value.toLowerCase(), "ltr", "Attribute dir");

        // dir = rtl
        selenium.click(rtlInput);
        selenium.waitForPageToLoad();
        assertTrue(selenium.isAttributePresent(dirAttribute), "Attribute dir should be present.");
        value = selenium.getAttribute(dirAttribute);
        assertEquals(value.toLowerCase(), "rtl", "Attribute dir");
    }

    /**
     * A helper method for testing attribute "lang".
     *
     * @param element
     *            locator of tested element
     */
    protected void testLang(ElementLocator<?> element) {
        JavaScript getAttributeLang = null;
        SystemPropertiesConfiguration config = new SystemPropertiesConfiguration();

        if (config.getBrowser().getType() == BrowserType.FIREFOX) {
            getAttributeLang = new JavaScript("window.jQuery('" + element.getRawLocator() + "').attr('lang')");
        } else {
            getAttributeLang = new JavaScript("window.jQuery('" + element.getRawLocator() + "').attr('xml:lang')");
        }

        // lang = null
        String langAttr = selenium.getEval(getAttributeLang);
        assertTrue("null".equals(langAttr) || "".equals(langAttr), "Attribute xml:lang should not be present.");

        selenium.type(pjq("input[type=text][id$=langInput]"), "sk");
        selenium.waitForPageToLoad();

        // lang = sk
        assertEquals(selenium.getEval(getAttributeLang), "sk", "Attribute xml:lang should be present.");
    }

    /**
     * A helper method for testing attribute "title".
     *
     * @param element
     *            locator of tested element
     */
    protected void testTitle(ElementLocator<?> element) {
        ElementLocator<?> input = ref(attributesRoot, "input[type=text][id$=titleInput]");
        AttributeLocator<?> attribute = element.getAttribute(new Attribute("title"));

        // title = null
        assertFalse(selenium.isAttributePresent(attribute), "Attribute title should not be present.");

        // title = "RichFaces 4"
        selenium.type(input, "RichFaces 4");
        selenium.waitForPageToLoad(TIMEOUT);

        assertTrue(selenium.isAttributePresent(attribute), "Attribute title should be present.");
        String value = selenium.getAttribute(attribute);
        assertEquals(value, "RichFaces 4", "Attribute title");
    }

    /**
     * A helper method for testing standard HTML attributes (RichFaces attributes that are directly put into markup),
     * e.g. hreflang.
     *
     * @param element
     *            locator of tested element
     * @param attribute
     *            tested attribute, e.g. "hreflang"
     * @param value
     *            value that should be set, e.g. "cs"
     */
    protected void testHtmlAttribute(ElementLocator<?> element, String attribute, String value) {
        AttributeLocator<?> attr = element.getAttribute(new Attribute(attribute));

        selenium.type(pjq("input[id$=" + attribute + "Input]"), value);
        selenium.waitForPageToLoad();

        assertTrue(selenium.getAttribute(attr).contains(value),
                "Attribute " + attribute + " should contain \"" + value + "\".");
    }

    /**
     * Hides header, footer and inputs for attributes.
     */
    protected void hideControls() {
        selenium.getEval(new JavaScript("window.hideControls()"));
    }

    /**
     * Shows header, footer and inputs for attributes.
     */
    protected void showControls() {
        selenium.getEval(new JavaScript("window.showControls()"));
    }

    protected void fireEventNatively(ElementLocator<?> target, Event event) {
        if (event == CLICK) {
            selenium.click(target);
        } else if (event == DBLCLICK) {
            selenium.doubleClick(target);
        } else if (event == MOUSEMOVE) {
            selenium.mouseMove(target);
        } else if (event == MOUSEDOWN) {
            selenium.mouseDown(target);
        } else if (event == MOUSEUP) {
            selenium.mouseUp(target);
        } else if (event == MOUSEOVER) {
            selenium.mouseOver(target);
        } else if (event == MOUSEOUT) {
            selenium.mouseOut(target);
        } else {
            selenium.fireEvent(target, event);
        }
    }

    /**
     * Abstract ReloadTester for testing
     *
     * @param <T>
     *            the type of input values which will be set, sent and then verified
     */
    public abstract class ReloadTester<T> {

        public abstract void doRequest(T inputValue);

        public abstract void verifyResponse(T inputValue);

        public abstract T[] getInputValues();

        public void testRerenderAll() {
            for (T inputValue : getInputValues()) {
                doRequest(inputValue);
                verifyResponse(inputValue);
                AbstractGrapheneTest.this.rerenderAll();
                verifyResponse(inputValue);
            }
        }

        public void testFullPageRefresh() {
            for (T inputValue : getInputValues()) {
                doRequest(inputValue);
                verifyResponse(inputValue);
                AbstractGrapheneTest.this.fullPageRefresh();
                verifyResponse(inputValue);
            }
        }
    }

    protected interface IEventLaunchAction {

        void launchAction();
    }
}