com.qmetry.qaf.automation.ui.AbstractTestPage.java Source code

Java tutorial

Introduction

Here is the source code for com.qmetry.qaf.automation.ui.AbstractTestPage.java

Source

/*******************************************************************************
 * QMetry Automation Framework provides a powerful and versatile platform to author 
 * Automated Test Cases in Behavior Driven, Keyword Driven or Code Driven approach
 *                
 * Copyright 2016 Infostretch Corporation
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
 *
 * This program 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 General Public License for more details.
 *
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
 *
 * You should have received a copy of the GNU General Public License along with this program in the name of LICENSE.txt in the root folder of the distribution. If not, see https://opensource.org/licenses/gpl-3.0.html
 *
 * See the NOTICE.TXT file in root folder of this source files distribution 
 * for additional information regarding copyright ownership and licenses
 * of other open source software / files used by QMetry Automation Framework.
 *
 * For any inquiry or need additional information, please contact support-qaf@infostretch.com
 *******************************************************************************/

package com.qmetry.qaf.automation.ui;

import java.lang.reflect.ParameterizedType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.qmetry.qaf.automation.core.ConfigurationManager;
import com.qmetry.qaf.automation.ui.api.PageLocator;
import com.qmetry.qaf.automation.ui.api.TestPage;
import com.qmetry.qaf.automation.ui.api.UiTestBase;
import com.qmetry.qaf.automation.ui.selenium.WaitService.JsToolkit;
import com.qmetry.qaf.automation.ui.webdriver.ElementFactory;
import com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebDriver;
import com.qmetry.qaf.automation.util.PropertyUtil;

/**
 * High level page class for different UI driver implementation.
 * <p>
 * This class provides you a way to define static or dynamic page hierarchy. In
 * the case of page hierarchy, you just need to call launch page method of the
 * object. it takes care of not only launching that page but also the entire
 * page hierarchy to reach that specific page. Furthermore it also checks that
 * is page already active in browser? If so then it will continue from there,
 * results in reduced execution time. It also allows you to set one of the
 * {@link #setLaunchStrategy(com.qmetry.qaf.automation.ui.api.TestPage.LaunchStrategy)
 * launch strategy} so that you can specify launch behavior before launching the
 * page. The default launch strategy is {@link LaunchStrategy#onlyIfRequired
 * launch only if required}.
 * <p>
 * When functionality changes only the specific test page file needs to be
 * updated: if there is any change in page/ui of web/native AUT you need to
 * update just in particular page rather than each and every test case, thus
 * result in less maintenance.
 * <p>
 * By implementation of test page concept in a best efficient way, you can
 * manipulate page navigation same as on actual web application under test. Once
 * page get created page object's functionalities can be used in any test case,
 * makes code more reusable.
 * 
 * @author Chirag Jayswal
 * @param <P>
 *            parent page in hierarchy
 * @param <D>
 *            Driver implementation - e.g. selenium or webdriver
 */
public abstract class AbstractTestPage<P extends TestPage<D>, D> implements TestPage<D> {
    protected P parent;
    protected UiTestBase<D> testbase;
    protected D driver;
    protected PropertyUtil pageProps;
    protected PageLocator pageLocator;
    protected Object[] launchArguments;

    protected final Log logger;
    protected LaunchStrategy launchStrategy = LaunchStrategy.onlyIfRequired;

    public AbstractTestPage(UiTestBase<D> testBase) {
        this.testbase = testBase;

        logger = LogFactoryImpl.getLog(this.getClass());
        driver = testbase.getDriver();

        this.pageProps = ConfigurationManager.getBundle();
        initWebElements();
    }

    public AbstractTestPage(UiTestBase<D> testBase, P parent2) {
        this(testBase);
        this.parent = parent2;
    }

    @Override
    public UiTestBase<D> getTestBase() {
        return testbase;
    }

    @Override
    public PageLocator getPageLocator() {
        return this.pageLocator;
    }

    @Override
    public void setLaunchStrategy(LaunchStrategy strategy) {
        launchStrategy = strategy;
    }

    @Override
    public void launchPage(PageLocator locator, Object... args) {

        this.pageLocator = locator;
        this.launchArguments = args;
        boolean reqToLaunch = false;

        parent = getParent();
        try {
            reqToLaunch = !launchStrategy.equals(LaunchStrategy.onlyIfRequired)
                    || !this.isPageActive(locator, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (reqToLaunch) {
            logger.debug("Launching page: " + this.getClass().getCanonicalName());
            if (parent != null) {
                if (launchStrategy.equals(LaunchStrategy.alwaysRelaunchFromRoot)) {
                    parent.setLaunchStrategy(launchStrategy);
                } else {
                    parent.setLaunchStrategy(LaunchStrategy.onlyIfRequired);
                }
                parent.launchPage(locator != null ? locator.getParentLocator() : null, args);
            }
            beforeLaunch(args);
            openPage(locator, args);
            waitForPageToLoad();
            afterLaunch();
        }
    }

    public void waitForPageToLoad() {

    }

    @Override
    public boolean isPageActive(PageLocator loc, Object... args) {
        return false;
    }

    /**
     * this method can be override to provide tasks to be done immediate after
     * page launch. It will ensure that page is launched. It is
     */
    protected void afterLaunch() {
    }

    /**
     * you can override this method to fech any information/data from parent
     * page before launching the page. FW will ensure that when this method get
     * executed parent page is open.
     * <p>
     * <b>Note:</b> If launch method found this page is not opened and going to
     * open the page then only this method will get executed.
     * 
     * @param args
     *            passed in {@link #launchPage(PageLocator, Object...)}
     */
    protected void beforeLaunch(Object... args) {
    }

    @SuppressWarnings("unchecked")
    protected void initParent() {
        try {
            Class<P> class1 = (Class<P>) ((ParameterizedType) this.getClass().getGenericSuperclass())
                    .getActualTypeArguments()[0];
            if (!class1.isInterface()) {
                parent = class1.newInstance();
            }
        } catch (Exception e) {
            logger.warn("Unable to init parent class" + e.getMessage());
        }

    }

    /**
     * Do not provide steps to load this page in this method, Instead provide
     * steps in method of parent and call that method over here.<br>
     * In case of multiple parent or referrer page, provide code to get parent
     * by casting. For instance:
     * 
     * <pre>
     * <code>
     * if(parent instanceof UploadStatus ){
     * UploadStatus parent = (UploadStatus) getParent();
     * parent.methodToLoadThisPage(args_if_any);
     * }
     * </code>
     * </pre>
     * 
     * @param locator
     * @param args
     */
    abstract protected void openPage(PageLocator locator, Object... args);

    @Override
    public final P getParent() {
        if (this.parent == null) {
            initParent();
        }
        return this.parent;
    }

    private void initWebElements() {
        ElementFactory elementFactory = new ElementFactory();
        elementFactory.initFields(this);
    }

    public void assertActive() {
        String msg = String.format("Expected %s is active.", this.getClass().getSimpleName());
        AbstractTestCase.assertTrue(isPageActive(pageLocator, launchArguments), msg, msg);
    }

    @Deprecated
    public void waitForImageToLoad(final String imgLoc) {

    }

    /**
     * for any kit
     */
    public void waitForAjaxToComplete() {
    }

}