/**
 * License Agreement.
 *
 * JBoss RichFaces - Ajax4jsf Component Library
 *
 * Copyright (C) 2007 Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */ 
package org.richfaces.testng;

import org.ajax4jsf.template.Template;
import org.richfaces.SeleniumTestBase;
import org.testng.Assert;
import org.testng.annotations.Test;

/**
 * Ajax Output Panel selenium test
 * 
 * @author Alexandr Levkovsky
 * 
 */
public class AjaxOutputPanelTest extends SeleniumTestBase {

    private final static String FORM_ID = "form:";

    private final static String PANEL1_ID = "panel_1";

    private final static String PANEL2_ID = "panel_2";

    private final static String PANEL3_ID = "panel_3";

    private final static String PANEL4_ID = "panel_4";

    private final static String BUTTON1_ID = "b1";

    private final static String BUTTON2_ID = "b2";

    private final static String BUTTON3_ID = "b3";

    private final static String BUTTON4_ID = "b4";

    private final static String RESET_BUTTON_ID = "reset";

    private final static String TEXT_SUFFIX = "_text";

    private final static String RESULT_SUFFIX = "_result";

    public String getTestUrl() {
	return "pages/ajaxOutputPanel/ajaxOutputPanelTest.xhtml";
    }

    @Test
    public void testLayoutAttribute(Template template) throws Exception {
	renderPage(template);
	// panel_1 has layout=inline(default)
	// panel_2 has layout=block
	// panel_3 has layout=none
	writeStatus("Testing layout attribute...");

	String panelId = getParentId() + FORM_ID + PANEL1_ID;
	String panel2Id = getParentId() + FORM_ID + PANEL2_ID;
	String panel3Id = getParentId() + FORM_ID + PANEL3_ID;

	Assert.assertTrue(isPresentById(panelId));
	Number type = selenium.getXpathCount("//*[@id='" + panelId + "' and (name()='span' or name()='SPAN')]");
	Assert.assertTrue(type.intValue() == 1, "panel_1 has layout=inline(default) and should be 'span' element");

	Assert.assertTrue(isPresentById(panel2Id));
	type = selenium.getXpathCount("//*[@id='" + panel2Id + "' and (name()='DIV' or name()='div')]");
	Assert.assertTrue(type.intValue() == 1, "panel_2 has layout=block and should be 'div' element");

	// panel_3 has layout=none and should not present if a child component
	// is rendered
	Assert.assertFalse(isPresentById(panel3Id), "panel_3 has layout=none and should not peresent if a child component is rendered ");

	// remove child component rendering
	writeStatus("Click button 3");
	String buttonId = getParentId() + FORM_ID + BUTTON3_ID;
	clickById(buttonId);
	waitForAjaxCompletion();

	// panel_3 has layout=none and should present if no child component is
	// rendered with id of a child component and display:none style
	Assert.assertTrue(isPresentById(panel3Id + "_text"), "panel_3 has layout=none and should peresent if no child component is rendered with id of a child component");
	Assert.assertFalse(isVisibleById(panel3Id + "_text"), "panel_3 has layout=none and should peresent if no child component is rendered with display:none style");
	clickReset();
    }

    @Test
    public void testRenderedAttribute(Template template) throws Exception {
	renderPage(template);
	writeStatus("Testing rendered attribute...");

	String panelId = getParentId() + FORM_ID + PANEL4_ID;

	// panel_4 has rendered=true and should present on page
	AssertRendered(panelId);

	// change rendered attribute to false
	writeStatus("Click button 4");
	String buttonId = getParentId() + FORM_ID + BUTTON4_ID;
	clickCommandAndWait(buttonId);

	// panel_4 has rendered=false and should not present on page
	AssertNotRendered(panelId);
	clickReset();
    }

    @Test
    public void testAjaxRenderedAttribute(Template template) throws Exception {
	renderPage(template);
	// panel_1 has ajaxRendered=false and is reRender by b1
	// panel_2 has ajaxRendered=true
	writeStatus("Testing ajaxRendered attribute...");

	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + PANEL1_ID + TEXT_SUFFIX;
	String panelId2 = parentId + PANEL2_ID + TEXT_SUFFIX;
	String buttonId = parentId + BUTTON2_ID;
	writeStatus("Click button 2");
	// set panel_1 text visible flag to false
	clickById(buttonId);
	waitForAjaxCompletion();
	// panel_1 text should be visible as it reRendered only by b1
	Assert.assertTrue(isPresentById(panelId), "panel_1 text should be visible as it reRendered only by b1");

	// panel_2 text should not be visible as it has ajaxRendered=true
	Assert.assertFalse(isPresentById(panelId2), "panel_2 text should not be visible as it has ajaxRendered=true");

	buttonId = parentId + BUTTON1_ID;
	writeStatus("Click button 1");
	clickById(buttonId);
	waitForAjaxCompletion();
	// panel text should NOT be visible as it reRendered by b1
	Assert.assertFalse(isPresentById(panelId), "panel_1 text should not be visible as it reRendered by b1");
	clickReset();

    }

    @Test
    public void testAjaxRenderedAttributeWithLimitToList(Template template) throws Exception {
	renderPage(template);
	// panel_1 has ajaxRendered=false and is reRender by b1 with
	// limitToList=true
	// panel_2 has ajaxRendered=true
	writeStatus("Testing ajaxRendered attribute with limitToList=true...");

	String parentId = getParentId() + FORM_ID;
	String panelId2 = parentId + PANEL2_ID + TEXT_SUFFIX;
	String buttonId = parentId + BUTTON1_ID;
	String button2Id = parentId + BUTTON2_ID;

	Assert.assertTrue(isPresentById(panelId2));
	writeStatus("Click button 1");
	// set panel_2 text visible flag to false
	clickById(buttonId);
	waitForAjaxCompletion();
	// panel_2 text should be visible as b1 has limitToList=true and
	// rerender only panel_1
	Assert.assertTrue(isPresentById(panelId2), "panel_2 text should be visible as b1 has limitToList=true and rerender only panel_1");
	writeStatus("Click button 2");
	clickById(button2Id);
	waitForAjaxCompletion();
	// panel_2 text should not be visible as it has ajaxRendered=true and b2
	// has limitToList=false
	Assert.assertFalse(isPresentById(panelId2), "panel_2 text should not be visible as it has ajaxRendered=true and b2 has limitToList=false");
	clickReset();
    }

    @Test
    public void testOnDoubleClickEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_5";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check ondoubleclick event");
	AssertTextEquals(panelResultId, "No");
	selenium.doubleClick(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnKeyDownEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_6";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onkeydown event");
	AssertTextEquals(panelResultId, "No");
	selenium.keyDown(panelId, "1");
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnKeyPressEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_7";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onkeypress event");
	AssertTextEquals(panelResultId, "No");
	selenium.keyPress(panelId, "1");
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnKeyUpEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_8";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onkeyup event");
	AssertTextEquals(panelResultId, "No");
	selenium.keyUp(panelId, "1");
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnMouseDownEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_9";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onmousedown event");
	AssertTextEquals(panelResultId, "No");
	selenium.mouseDown(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnMouseMoveEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_10";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onmousemove event");
	AssertTextEquals(panelResultId, "No");
	selenium.mouseMove(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnMouseOutEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_11";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onmouseout event");
	AssertTextEquals(panelResultId, "No");
	selenium.mouseOut(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnMouseOverEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_12";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onmouseover event");
	AssertTextEquals(panelResultId, "No");
	selenium.mouseOver(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnMouseUpEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_13";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onmouseup event");
	AssertTextEquals(panelResultId, "No");
	selenium.mouseUp(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    @Test
    public void testOnClickEvent(Template template) throws Exception {
	renderPage(template);
	String parentId = getParentId() + FORM_ID;
	String panelId = parentId + "panel_14";
	String panelResultId = panelId + RESULT_SUFFIX;
	writeStatus("Check onclick event");
	AssertTextEquals(panelResultId, "No");
	selenium.click(panelId);
	AssertTextEquals(panelResultId, "Yes");
    }

    private void clickReset() {
	String buttonId = getParentId() + FORM_ID + RESET_BUTTON_ID;
	writeStatus("Click reset button");
	clickCommandAndWait(buttonId);
    }
}
