Java tutorial
/******************************************************************************* * 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() { } }