All Downloads are FREE. Search and download functionalities are using the official Maven repository.

geb.Page.groovy Maven / Gradle / Ivy

Go to download

Geb (pronounced "jeb") is a browser automation solution. It brings together the power of WebDriver, the elegance of jQuery content selection, the robustness of Page Object modelling and the expressiveness of the Groovy language.

There is a newer version: 7.0
Show newest version
/* Copyright 2009 the original author or authors.
 *
 * Licensed 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 geb

import geb.content.*
import geb.download.DefaultDownloadSupport
import geb.download.DownloadSupport
import geb.download.UninitializedDownloadSupport
import geb.error.GebException
import geb.error.PageInstanceNotInitializedException
import geb.error.UndefinedAtCheckerException
import geb.error.UnexpectedPageException
import geb.frame.DefaultFrameSupport
import geb.frame.FrameSupport
import geb.frame.UninitializedFrameSupport
import geb.interaction.DefaultInteractionsSupport
import geb.interaction.InteractionsSupport
import geb.interaction.UninitializedInteractionSupport
import geb.js.AlertAndConfirmSupport
import geb.js.DefaultAlertAndConfirmSupport
import geb.js.JavascriptInterface
import geb.js.UninitializedAlertAndConfirmSupport
import geb.navigator.Navigator
import geb.textmatching.TextMatchingSupport
import geb.waiting.DefaultWaitingSupport
import geb.waiting.UninitializedWaitingSupport
import geb.waiting.Wait
import geb.waiting.WaitingSupport
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.WebElement

/**
 * The Page type is the basis of the Page Object pattern in Geb.
 * 

* This implementation is a generic model of every page. Subclasses add methods and * content definitions that model specific pages. *

* This class (or subclasses) should not be instantiated directly. *

* The following classes are also mixed in to this class: *

    *
  • {@link geb.content.PageContentSupport} *
  • {@link geb.download.DownloadSupport} *
  • {@link geb.waiting.WaitingSupport} *
  • {@link geb.textmatching.TextMatchingSupport} *
  • {@link geb.js.AlertAndConfirmSupport} *
*

* See the chapter in the Geb manual on pages for more information on writing subclasses. */ class Page implements Navigable, PageContentContainer, Initializable, WaitingSupport { /** * The "at checker" for this page. *

* Subclasses should define a closure here that verifies that the browser is at this page. *

* This implementation does not have an at checker (i.e. this property is {@code null}) */ static at = null /** * Defines the url for this page to be used when navigating directly to this page. *

* Subclasses can specify either an absolute url, or one relative to the browser's base url. *

* This implementation returns an empty string. * * @see #to(java.util.Map, java.lang.Object) */ static url = "" /** * The wait time configuration for 'at' checking specific to this page. *

* Subclasses can specify atCheckWaiting value, value specified in page takes priority over the global atCheckWaiting setting. *

* Possible values for the atCheckWaiting option are consistent with the ones for wait option of content definitions. *

* This implementation does not have any value for atCheckWaiting (i.e. this property is {@code null}). */ static atCheckWaiting = null private Browser browser @Delegate private PageContentSupport pageContentSupport = new UninitializedPageContentSupport(this) @Delegate private DownloadSupport downloadSupport = new UninitializedDownloadSupport(this) private WaitingSupport waitingSupport = new UninitializedWaitingSupport(this) @Delegate private FrameSupport frameSupport = new UninitializedFrameSupport(this) @Delegate private InteractionsSupport interactionsSupport = new UninitializedInteractionSupport(this) @Delegate @SuppressWarnings("UnusedPrivateField") private final TextMatchingSupport textMatchingSupport = new TextMatchingSupport() @Delegate private AlertAndConfirmSupport alertAndConfirmSupport = new UninitializedAlertAndConfirmSupport(this) //manually delegating here because @Delegate doesn't work with cross compilation http://jira.codehaus.org/browse/GROOVY-6865 private Navigable navigableSupport = new UninitializedNavigableSupport(this) /** * Initialises this page instance, connecting it to the browser. *

* This method is called internally, and should not be called by users of Geb. */ @SuppressWarnings('SpaceBeforeOpeningBrace') Page init(Browser browser) { this.browser = browser def contentTemplates = PageContentTemplateBuilder.build(browser, this, browser.navigatorFactory, 'content', this.class, Page) pageContentSupport = new DefaultPageContentSupport(this, contentTemplates, browser.navigatorFactory) navigableSupport = new NavigableSupport(browser.navigatorFactory) downloadSupport = new DefaultDownloadSupport(browser) waitingSupport = new DefaultWaitingSupport(browser.config) frameSupport = new DefaultFrameSupport(browser) interactionsSupport = new DefaultInteractionsSupport(browser) alertAndConfirmSupport = new DefaultAlertAndConfirmSupport({ this.getJs() }, browser.config) this } /** * The browser that the page is connected to. */ Browser getBrowser() { browser } private Browser getInitializedBrowser() { if (browser == null) { throw uninitializedException() } browser } /** * The driver of the browser that the page is connected to. */ WebDriver getDriver() { getInitializedBrowser().driver } /** * Returns the name of this class. * * @see Class#getName() */ String toString() { this.class.name } /** * Checks if the browser is not at an unexpected page and then executes this page's "at checker". * * @return whether the at checker succeeded or not. * @see #verifyAtSafely(boolean) * @throws AssertionError if this page's "at checker" doesn't pass (with implicit assertions enabled) * @throws UnexpectedPageException when at an unexpected page */ boolean verifyAt() { getInitializedBrowser().checkIfAtAnUnexpectedPage(getClass()) verifyThisPageAtOnly(true) } /** * Executes this page's "at checker", suppressing any AssertionError that is thrown * and returning false. * * @return whether the at checker succeeded or not. * @see #verifyAt() */ boolean verifyAtSafely(boolean honourGlobalAtCheckWaiting = true) { getAtVerificationResult(honourGlobalAtCheckWaiting) } /** * Executes this page's "at checker" and captures the result wrapping up any AssertionError that might have been thrown. * * @return at verification result with any AssertionError that might have been thrown wrapped up * @see AtVerificationResult */ AtVerificationResult getAtVerificationResult(boolean honourGlobalAtCheckWaiting = true) { Throwable caughtException = null boolean atResult = false try { atResult = verifyThisPageAtOnly(honourGlobalAtCheckWaiting) } catch (AssertionError e) { caughtException = e } new AtVerificationResult(atResult, caughtException) } /** * Executes this page's "at checker". * * @return whether the at checker succeeded or not. * @throws AssertionError if this page's "at checker" doesn't pass (with implicit assertions enabled) */ private boolean verifyThisPageAtOnly(boolean honourGlobalAtCheckWaiting) { Closure verifier = getClass().at?.clone() if (verifier) { verifier.delegate = this verifier.resolveStrategy = Closure.DELEGATE_FIRST def atCheckWaiting = getEffectiveAtCheckWaiting(honourGlobalAtCheckWaiting) if (atCheckWaiting) { atCheckWaiting.waitFor(verifier) } else { verifier() } } else { throw new UndefinedAtCheckerException(this.class.name) } } /** * Sends the browser to this page's url. * * @param params request parameters to be appended to the url * @param args "things" that can be used to generate an extra path to append to this page's url * @see #convertToPath(java.lang.Object) * @see #getPageUrl(java.lang.String) */ void to(Map params, Object[] args) { def path = convertToPath(*args) if (path == null) { path = "" } getInitializedBrowser().go(params, getPageUrl(path)) getInitializedBrowser().page(this) } /** * Returns the constant part of the url to this page. *

* This implementation returns the static url property of the class. */ String getPageUrl() { this.class.url } /** * Returns the url to this page, with path appended to it. * * @see #getPageUrl() */ String getPageUrl(String path) { def pageUrl = getPageUrl() path ? (pageUrl ? pageUrl + path : path) : pageUrl } /** * Converts the arguments to a path to be appended to this page's url. *

* This is called by the {@link #to(java.util.Map, java.lang.Object)} method and can be used for accessing variants of the page. *

* This implementation returns the string value of each argument, separated by "/" */ // tag::convert_to_path[] String convertToPath(Object[] args) { args ? '/' + args*.toString().join('/') : "" } // end::convert_to_path[] /** * Returns the title of the current browser window. * * @see org.openqa.selenium.WebDriver#getTitle() */ String getTitle() { getInitializedBrowser().driver.title } /** * Provides access to the browser object's JavaScript interface. * * @see geb.Browser#getJs() */ JavascriptInterface getJs() { getInitializedBrowser().js } /** * Lifecycle method called when the page is connected to the browser. *

* This implementation does nothing. * * @param previousPage The page that was active before this one */ @SuppressWarnings(["UnusedMethodParameter", "EmptyMethod"]) void onLoad(Page previousPage) { } /** * Lifecycle method called when this page is being replaced as the browser's page instance. *

* This implementation does nothing. * * @param nextPage The page that will be active after this one */ @SuppressWarnings(["UnusedMethodParameter", "EmptyMethod"]) void onUnload(Page nextPage) { } private Wait getGlobalAtCheckWaiting(boolean honourGlobalAtCheckWaiting) { honourGlobalAtCheckWaiting ? getInitializedBrowser().config.atCheckWaiting : null } private Wait getEffectiveAtCheckWaiting(boolean honourGlobalAtCheckWaiting) { getClass().atCheckWaiting != null ? pageLevelAtCheckWaiting : getGlobalAtCheckWaiting(honourGlobalAtCheckWaiting) } protected Wait getPageLevelAtCheckWaiting() { def atCheckWaitingValue = getClass().atCheckWaiting getInitializedBrowser().config.getWaitForParam(atCheckWaitingValue) } Navigator find() { navigableSupport.find() } Navigator $() { navigableSupport.$() } Navigator find(int index) { navigableSupport.find(index) } Navigator find(Range range) { navigableSupport.find(range) } Navigator $(int index) { navigableSupport.$(index) } Navigator $(Range range) { navigableSupport.$(range) } Navigator find(String selector) { navigableSupport.find(selector) } Navigator $(String selector) { navigableSupport.$(selector) } Navigator find(String selector, int index) { navigableSupport.find(selector, index) } Navigator find(String selector, Range range) { navigableSupport.find(selector, range) } Navigator $(String selector, int index) { navigableSupport.$(selector, index) } Navigator $(String selector, Range range) { navigableSupport.$(selector, range) } Navigator find(Map attributes) { navigableSupport.find(attributes) } Navigator $(Map attributes) { navigableSupport.$(attributes) } Navigator find(Map attributes, int index) { navigableSupport.find(attributes, index) } Navigator find(Map attributes, Range range) { navigableSupport.find(attributes, range) } Navigator $(Map attributes, int index) { navigableSupport.$(attributes, index) } Navigator $(Map attributes, Range range) { navigableSupport.$(attributes, range) } Navigator find(Map attributes, String selector) { navigableSupport.find(attributes, selector) } Navigator $(Map attributes, String selector) { navigableSupport.$(attributes, selector) } Navigator find(Map attributes, String selector, int index) { navigableSupport.$(attributes, selector, index) } Navigator find(Map attributes, String selector, Range range) { navigableSupport.find(attributes, selector, range) } Navigator $(Map attributes, String selector, int index) { navigableSupport.$(attributes, selector, index) } Navigator $(Map attributes, String selector, Range range) { navigableSupport.$(attributes, selector, range) } Navigator $(Map attributes, By bySelector) { navigableSupport.find(attributes, bySelector) } Navigator find(Map attributes, By bySelector) { navigableSupport.find(attributes, bySelector) } Navigator $(Map attributes, By bySelector, int index) { navigableSupport.find(attributes, bySelector, index) } Navigator find(Map attributes, By bySelector, int index) { navigableSupport.find(attributes, bySelector, index) } Navigator $(Map attributes, By bySelector, Range range) { navigableSupport.find(attributes, bySelector, range) } Navigator find(Map attributes, By bySelector, Range range) { navigableSupport.find(attributes, bySelector, range) } Navigator $(By bySelector) { navigableSupport.find(bySelector) } Navigator find(By bySelector) { navigableSupport.find(bySelector) } Navigator $(By bySelector, int index) { navigableSupport.find(bySelector, index) } Navigator find(By bySelector, int index) { navigableSupport.find(bySelector, index) } Navigator $(By bySelector, Range range) { navigableSupport.find(bySelector, range) } Navigator find(By bySelector, Range range) { navigableSupport.find(bySelector, range) } Navigator $(Navigator[] navigators) { navigableSupport.$(navigators) } Navigator $(WebElement[] elements) { navigableSupport.$(elements) } @Override T module(Class moduleClass) { navigableSupport.module(moduleClass) } @Override T module(T module) { navigableSupport.module(module) } @Override def T waitFor(Map params = [:], String waitPreset, Closure block) { waitingSupport.waitFor(params, waitPreset, block) } @Override def T waitFor(Map params = [:], Closure block) { waitingSupport.waitFor(params, block) } @Override def T waitFor(Map params = [:], Double timeout, Closure block) { waitingSupport.waitFor(params, timeout, block) } @Override def T waitFor(Map params = [:], Double timeout, Double interval, Closure block) { waitingSupport.waitFor(params, timeout, interval, block) } GebException uninitializedException() { def message = "Instance of page ${getClass()} has not been initialized. Please pass it to Browser.to(), Browser.via(), Browser.page() or Browser.at() before using it." new PageInstanceNotInitializedException(message) } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy