/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.myfaces.test.htmlunit;

import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlHead;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <p>Abstract base class for system integration tests based on HtmlUnit.
 * These tests will expect a system property named <code>url</code> to be
 * present, which will define the URL (including the context path, but
 * without a trailing slash) of the application to be tested.</p>
 * 
 * @since 1.0.0
 */
public abstract class AbstractHtmlUnitTestCase extends TestCase
{

    // ------------------------------------------------------------ Constructors

    /**
     * <p>Construct a new instance of this test case.</p>
     *
     * @param name Name of the new test case
     */
    public AbstractHtmlUnitTestCase(String name)
    {

        super(name);

    }

    // ------------------------------------------------------ Instance Variables

    /**
     * <p>The most recently retrieved page from the server.</p>
     */
    protected HtmlPage page = null;

    /**
     * <p>The calculated URL for the installed "systest" web application.
     * This value is based on a system property named <code>url</code>,
     * which must be defined as part of the command line that executes
     * each test case.</p>
     */
    protected URL url = null;

    /**
     * <p>The web client for this test case.</p>
     */
    protected WebClient webClient = null;

    // ------------------------------------------------------ Test Setup Methods

    /**
     * <p>Set up the instance variables required for this test case.</p>
     *
     * @exception Exception if an error occurs
     */
    protected void setUp() throws Exception
    {

        // Calculate the URL for the installed "systest" web application
        String url = System.getProperty("url");
        this.url = new URL(url + '/');

        // Initialize HtmlUnit constructs for this test case
        webClient = new WebClient();

    }

    /**
     * <p>Return the set of tests included in this test suite.</p>
     */
    public static Test suite()
    {

        return (new TestSuite(AbstractHtmlUnitTestCase.class));

    }

    /**
     * <p>Tear down instance variables required by this test case.</p>
     */
    protected void tearDown() throws Exception
    {

        page = null;
        url = null;
        webClient = null;

    }

    // ------------------------------------------------------- Protected Methods

    /**
     * <p>Return the body element for the most recently retrieved page.
     * If there is no such element, return <code>null</code>.</p>
     *
     * @exception Exception if an error occurs
     */
    protected HtmlBody body() throws Exception
    {

        Iterable<HtmlElement> elements = page.getHtmlElementDescendants();
        for (HtmlElement element : elements)
        {
            if (element instanceof HtmlBody)
            {
                return ((HtmlBody) element);
            }
        }
        return (null);

    }

    /**
     * <p>Return the HTML element with the specified <code>id</code> from the
     * most recently retrieved page.  If there is no such element, return
     * <code>null</code>.</p>
     *
     * @param id Identifier of the requested element.
     *
     * @exception Exception if an error occurs
     */
    protected HtmlElement element(String id) throws Exception
    {

        try
        {
            return (page.getHtmlElementById(id));
        }
        catch (ElementNotFoundException e)
        {
            return (null);
        }

    }

    /**
     * <p>Return the form with the specified <code>id</code> from the most
     * recently retrieved page.  If there is no such form, return
     * <code>null</code>.<p>
     *
     * @param id Identifier of the requested form.
     *
     * @exception Exception if an error occurs
     */
    protected HtmlForm form(String id) throws Exception
    {

        Iterator forms = page.getForms().iterator();
        while (forms.hasNext())
        {
            HtmlForm form = (HtmlForm) forms.next();
            if (id.equals(form.getAttribute("id")))
            {
                return (form);
            }
        }
        return (null);

    }

    /**
     * <p>Return the head element for the most recently retrieved page.
     * If there is no such element, return <code>null</code>.</p>
     *
     * @exception Exception if an error occurs
     */
    protected HtmlHead head() throws Exception
    {

        Iterable<HtmlElement> elements = page.getHtmlElementDescendants();
        for (HtmlElement element : elements)
        {
            if (element instanceof HtmlHead)
            {
                return ((HtmlHead) element);
            }
        }
        return (null);

    }

    /**
     * <p>Click the specified hyperlink, and retrieve the subsequent page,
     * saving a reference so that other utility methods may be used to
     * retrieve information from it.</p>
     *
     * @param anchor Anchor component to click
     *
     * @exception IOException if an input/output error occurs
     */
    protected HtmlPage link(HtmlAnchor anchor) throws IOException
    {

        HtmlPage page = (HtmlPage) anchor.click();
        this.page = page;
        return page;

    }

    /**
     * <p>Return the currently stored page reference.</p>
     */
    protected HtmlPage page()
    {

        return this.page;

    }

    /**
     * <p>Retrieve and return the page at the specified context relative path.
     * Save a reference to this page so that other utility methods may be used
     * to retrieve information from it.</p>
     *
     * @param path Context relative path
     *
     * @exception IllegalArgumentException if the context relative path
     *  does not begin with a '/' character
     * @exception Exception if a different error occurs
     */
    protected HtmlPage page(String path) throws Exception
    {

        HtmlPage page = (HtmlPage) webClient.getPage(url(path));
        this.page = page;
        return (page);

    }

    /**
     * <p>Reset the stored page reference to the specified value.  This is
     * useful for scenarios testing resubmit of the same page (simulating the
     * user pressing the back button and then submitting again).</p>
     *
     * @param page Previously saved page to which to reset
     */
    protected void reset(HtmlPage page)
    {

        this.page = page;

    }

    /**
     * <p>Submit the current page, using the specified component, and retrieve
     * the subsequent page, saving a reference so that other utility methods
     * may be used to retrieve information from it.</p>
     *
     * @param submit Submit button component to click
     *
     * @exception IOException if an input/output error occurs
     */
    protected HtmlPage submit(HtmlSubmitInput submit) throws IOException
    {

        HtmlPage page = (HtmlPage) submit.click();
        this.page = page;
        return page;

    }

    /**
     * <p>Return the page title from the most recently retrieved page.
     * Any leading and trailing whitespace will be trimmed.</p>
     *
     * @exception Exception if an error occurs
     */
    protected String title() throws Exception
    {

        return (page.getTitleText().trim());

    }

    /**
     * <p>Calculate and return an absolute URL for the specified context
     * relative path, which must begin with a '/' character.</p>
     *
     * @param path Context relative path
     *
     * @exception IllegalArgumentException if the context relative path
     *  does not begin with a '/' character
     * @exception Exception if a different error ocurs
     */
    protected URL url(String path) throws Exception
    {

        if (path.charAt(0) != '/')
        {
            throw new IllegalArgumentException("Context path '" + path
                    + "' does not start with '/'");
        }
        return new URL(url, path.substring(1));

    }

}
