Skip to main content

Web DSL

Architecture

The Web DSL is mainly based on annotation helpers that allow to define page objects using a declarative style.

Given the following test flow:

firefox
.openGoogleSearchPage()
.acceptCookies()
.typeIntoSearchBox("pumpitup")
.submit()

we need to define 1-page object representing the Google search landing page and 3 actions possible on that page. In traditional testing frameworks that would require writing code for all of these 3 methods plus the condition that verifies that the landing page is enough loaded to proceed. In Pumpo#5, annotations can be used to define what each method does as follows:

@Navigate("https://www.google.com")
@Wait(value = GoogleSearchPage.ACCEPT_BUTTON_XPATH, by = Lookup.XPATH)
public interface GoogleSearchPage extends WebAgentAccessor {

String ACCEPT_BUTTON_XPATH = "//button[2]";
String QUERY = "q";

@Click(value = ACCEPT_BUTTON_XPATH, by = Lookup.XPATH)
GoogleSearchPage AcceptCookies();

@SetValue(value = QUERY, by = Lookup.NAME)
GoogleSearchPage typeIntoSearchBox(String term);

@ExtendedAction
default GoogleSearchPage submit() {
getAgent().getDriver().findElement(By.name(QUERY)).submit();
return null;
}

}

The annotations @Navigate and @Wait on lines 1-2 define what the method onGoogleSearchPage will do:

  • Navigate to the specified URL
  • Wait until the specified element has been loaded enough to be visible on the browser

The annotation @Click defines what the method acceptCookies will do:

  • Click on the button for accepting cookies

etc...

Selenide support

Pumpo5 supports Selenide page objects. You can use class as alternative to interface and annotations. For the same Google search example it looks like this:

@Navigate("https://www.google.com")
@Wait(value = RohlikHomePage.ACCEPT_BUTTON_XPATH, by = Lookup.XPATH)
public class GoogleSearchPage {

private By acceptButtonXpath = By.xpath("//button[2]");
private By query = By.name("q");

public GoogleSearchPage acceptCookies() {
$(acceptButtonXpath)
.shouldBe(visible)
.click();
return this;
}

public GoogleSearchPage typeIntoSearchBox(String term) {
$(query)
.shouldBe(visible)
.setValue(term);
return this;
}

public GoogleSearchPage submit() {
$(query).submit();
return this;
}
}

Chaining annotations

Annotations can be chained, so we could for example have following method:

    @Click(value = "//button[10]", by = Lookup.XPATH)
@Click(value = "//button[11]", by = Lookup.XPATH)
SomePage clickButton10And11();

which would click on the 10th button, wait until the 11th button appears and then click on the 11th button.

Some annotations are repeatable (@Click is) while others are not. Repeatable annotations are processed always together. The order of processing various types of annotations is predefined and is as follows:

@Wait > @AssertElementPresent > @AssertElementContent > @StoreElementContent > @AssertAttributeValue > @StoreAttributeValue > @Log > @AssertUrl > @ScrollIntoView > @Click > @DoubleClick > @Select > @SetValue > @SendKeys

In case the order of execution does not fit to the needs then please have a look on the next option.

Dynamic lookup values

Almost all annotations support dynamic lookup value resolution using String.format(String pattern, Object... args). Args are taken from the method arguments. For example

    @Click(value = "//%s[%d]", by = Lookup.XPATH)
SomePage clickButtonByOrder(String TAG, int N);

which would click on the Nth element of type TAG.

In case the annotated method is by design requiring some input value (e.g. when setting the value of some input), then the last argument is ignored when performing the dynamic lookup value resolution. Even if it seems too tricky theoretically, in practice it is rather obvious:

    @SetValue(value = "//input[%d]", by = Lookup.XPATH)
SomePage setTheValueOfInputByOrder(int N, String newValue);

which would set the value newValue to the Nth input on the page.

Where annotations are not enough

In case a more complex action needs to be done, and an annotation that would fit does not exist, it is possible to code the action using plain Java as seen in the example:

    @ExtendedAction
default GoogleSearchPage submit() {
getDriver().findElement(By.name("q")).submit();
return null;
}

The annotation @ExtendedAction allows coding at low level what should happen. A more detailed description on how to use this annotation is in the annotation reference section below.

Going low-level in the test

In some cases it may be handy to not define a page object action but to code the action directly in the test. This is feasible thanks to the possibility to use the method getDrirver() directly anywhere in the test flow. So our example test could very well be written as:

firefox
.openGoogleSearchPage()
.acceptCookies()
.typeIntoSearchBox("pumpitup")
.getDriver().findElement(By.name("q")).submit();

While we think in most cases it is better to define the page objects, the choice is left to the tester.

Specific report files

In case a test, running on Chrome web browser, fails, two files will be created in the current reports' folder.

The first file will contain a timestamp on it's title, followed by the suffix "_console", and the extension ".log". It will contain all the messages printed out in Chrome's console at the time the flow in the test failed.

The second file is similar, only difference being the suffix "_network" instead of "_console". This file will contain all the network requests sent and received by the Chrome web browser, since the test started up to the moment it failed.

Both files might be useful for debugging issues with your test suite, given that they contain precious information logged by Chrome Developer Tools while a test is executed by Selenium web driver.

Annotations reference

@AssertAttributeValue

This method annotation allows to check that an attribute of a given element has an expected value.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
attributeNameStringmandatoryThe name of the attribute which value is to be asserted against the provided input
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Check that the first div on the page has the name set to the provided argument

@AssertAttributeValue(value = "//div[1]", by = Lookup.XPATH, attributeName = "name")
SomePage checkThatDivHasName(String expectedName);

@AssertElementContent

This method annotation allows to check that an element content has an expected value.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Check that the first textarea on the page contains the expected string value

@AssertElementContent(value = "//textarea[1]", by = Lookup.XPATH)
SomePage checkThatTextAreaContains(String expectedContent);

@AssertElementPresent

This repeatable method annotation allows to check that an element is present on the page.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Different from other annotations, this one defaults to 0 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Note: This annotation does the same as @Wait and only differs in the default timeout setting. It may be used instead of @Wait for readability purpose.

Usage example: Check that element with id equal to logo is present on the web page

@Wait("title")
@AssertElementPresent(value = "logo", by = Lookup.ID)
SomePage checkThatLogoIsPresent();

@AssertElementAbsent

This repeatable method annotation allows to check that an element is absent on the page.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Different from other annotations, this one defaults to 0 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Check that element with id equal to logo is present on the web page

@AssertElementAbsent(value = "logo", by = Lookup.ID)
SomePage checkThatLogoIsHidden();

@Click

This repeatable method annotation allows clicking on an element or sequentially on more elements.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
tryCoordinatesbooleanoptionalWhether an attempt should be done to click at the center of the element. Defaults to true.
retriesintoptionalHow many times the agent should try to click on the element, as the action can fail e.g., if the element is not ready to be clicked on. Defaults to 1 time.
pauseintoptionalHow many seconds the agent should wait before retrying this action, in case it fails.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

In case the annotation is specified several times actions will be done in the order of specification but without any other action in-between. This annotation implicitly waits until the element specified is present (as if the annotation @Wait was used) until the specified timeout elapses.

In case the flag tryCoordinates is set and Selenium reports the element to be covered by some other element (InterceptedException) and timeout has elapsed, then a final attempt is done to click at the center of the element. The click may then be received by any other element that would overlap which in fact mimics the potential user behaviour.

Usage example: Click on the first div element on the page

@Click(value = "//div[1]", by = Lookup.XPATH)
SomePage clickWhateverIsFirst();

@DoubleClick

This method annotation allows DoubleClick on an element.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
tryCoordinatesbooleanoptionalWhether an attempt should be done to click at the center of the element. Defaults to true.
retriesintoptionalHow many times the agent should try to double click on the element, as the action can fail e.g., if the element is not ready to be clicked on. Defaults to 1 time.
pauseintoptionalHow many seconds the agent should wait before retrying this action, in case it fails.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

This annotation implicitly waits until the element specified is present (as if the annotation @Wait was used).

In case the flag tryCoordinates is set and Selenium reports the element to be covered by some other element (InterceptedException) and timeout has elapsed, then a final attempt is done to click at the center of the element. The click may then be received by any other element that would overlap which in fact mimics the potential user behaviour.

Usage example: DoubleClick on the first div element on the page

@DoubleClick(value = "//div[1]", by = Lookup.XPATH)
SomePage DoubleClickWhateverIsFirst();

@ClickAndDownload

This method annotation allows clicking on an element and downloading a file.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
retriesintoptionalHow many times the agent should try to click on the element, as the action can fail e.g., if the element is not ready to be clicked on. Defaults to 1 time.
pauseintoptionalHow many seconds the agent should wait before retrying this action, in case it fails.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

This annotation implicitly waits until the element specified is present (as if the annotation @Wait was used) until the specified timeout elapses.

In case the file is downloaded successfully a file handle is returned to the user.

Usage example: Click on the first div element on the page, downloads a PDF file, and returns a file handle to the user.

@ClickAndDownload(value = "//div[1]", by = Lookup.XPATH)
File clickToDownloadAFile();

@ClickImage

This repeatable method annotation allows clicking an area that looks like the provided image. The framework takes a screenshot of the current browser window and tries to locate the provided image (usually an icon) on it. The coordinates of the first area matching the provided template are used, and the browser clicks in the center of those coordinates. This method may be handy for example in case of pure canvas applications where the DOM is not sufficient to locate elements.

ParameterTypeMandatoryDescription
valueStringmandatoryThe path to the image that is being looked for / can be a format pattern
selectorImagemandatoryThe selector of the area to search in, can typically be a DIV element
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

While other annotations will work even if running Pumpo#5 on a public test farm or locally on the main browser not using Docker, this annotation requires the OCR module to be running somewhere. Usually this will be the test farm, but it can be deployed on another location. When using a public test farm the OCR module can still be deployed elsewhere but screenshots will transit from the public test farm to the OCR module through the test runtime.

Usage example: Click on the icon of the DELETE button in a custom app where everything is drawn on CANVAS

@ClickImage(value = "src/test/resources/icons/delete.png", selector = "mainCanvas", by = Lookup.ID)
SomePage clickOnDelete();

@ExtendedAction

This method annotation allows executing custom code while keeping relying on the library to inject necessary object as return value.

Due to the context and Java syntax patterns following conditions must be met by the custom coded method:

  • The method body must be defined in the interface: this is feasible by using the qualifier default.
  • The method return type must be the class of the page object: this is feasible by returning whatever object that satisfies to the type, e.g. null. The library will ignore the returned value and will replace it with the right object with the same interface, so the test flow can continue.

Usage example: Print the value of the argument cookieValue and set a cookie named as the argument cookieName with the same value

@ExtendedAction
default SomePage setCookie(String cookieName, String cookieValue){
System.out.println(someInput);
getDriver().manage().addCookie(new Cookie(cookieName, someInput));
return null;
}

@GetAttributeValue

This method annotation allows retrieving the value of any attribute of any element.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupmandatoryThe lookup method, e.g. XPATH. Defaults to the Application level default method.
attributeNameStringmandatoryThe name of the attribute which value is to be retrieved
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Retrieve the URL of the first link on the page

@GetAttributeValue(value = "//a[1]", by = Lookup.XPATH, attributeName = "href")
String getTheFirstHref();

@GetElementContent

This method annotation allows retrieving the content of any element.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupmandatoryThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Retrieve the content of the first list item on the page

@GetElementContent(value = "//li[1]", by = Lookup.XPATH)
String getTheFirstItem();

This page object annotation allows navigating to a specific URL. This means the result will be as if the user has entered the URL in the address field and pressed enter.

ParameterTypeMandatoryDescription
valueStringmandatoryThe url to which to navigate

The annotation will be processed only in case the page object is used in the method open(PageObject) available in the interface WebDriverAccessor and all extending interfaces as WebApplication.

In case of navigation happening as normal functionality of the application (e.g., the user clicks on a link, or a button) then the test should instead include a transition method that will switch to the new page object. Transition methods have typically empty body and only need to specify the new page object as return type.

Our recommended best practice is as follows:

  • Define translation methods with the naming convention on + PageObjectName. Example: onSecondPage where SecondPage represents the page to which the browser navigates after the previous action.
  • Leave the return type of the previous action (that actually makes the browser navigating to the new page) to the current page. The idea is that in the test, having an explicit transition method makes it much more readable: it's a kind of self-documenting pattern.

Usage example: Navigate to an initial page, click on the first link and then switch to the context of a second page object to assert that the second page was loaded by checking that there is at least one DIV element

@Navigate(value = "https://pumpitup.cz")
public interface InitialPage extends WebDriverAccessor {
@Click(value="//a[1]", by = Lookup.XPATH)
InitialPage clickOnFirstUrl();

SecondPage onSecondPage();
}

public interface SecondPage extends WebDriverAccessor {
@AssertElementPresent(value = "//[div]", by = Lookup.XPATH)
SecondPage assertThatLoaded();
}

class TestClass {
@Test
testTransition(InitialPage initialPage) {
initialPage
.clickOnFirstUrl()
.onSecondPage()
.assertThatLoaded();
}
}

@MaximizeWindow

This method annotation allows to maximize the window. You can use it in web tests on class or method level. To be done for windows.

Usage example:

import dev.pumpo5.actions.MaximizeWindow;

@MaximizeWindow();
SomePage someMethod();

@RefreshPage

This method annotation allows to refresh the page same as F5. You can use it in web tests on class or method level.

Usage example:

import dev.pumpo5.actions.RefreshPage;

@RefreshPage();
SomePage someMethod();

@PressEnter

This method annotation allows sending the key [Enter] to the browser. This si typically used when filling forms.

Usage example: Press enter after

@PressEnter(value = "//div[1]", by = Lookup.XPATH, attributeName = "name")
SomePage someMethod(String someInput);

@ScrollIntoView

This method annotation allows to make the page or parent element to scroll until the specified view is visible.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

The annotation @Click implicitly also scrolls until the view to be clicked is visible so no need to use @ScrollIntoView in case the only purpose is to click on some element.

Usage example: Scroll to the 10th H2 title on the page, waits 5 seconds before throwing an exception in case the element is not visible

@ScrollIntoView(value = "//h[10]", by = Lookup.XPATH, timeout = 5)
SomePage scrollToTheTenthTitle();

@Select

This method annotation allows selecting an entry in an HTML SELECT form element.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find the select element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
byTextbooleanoptionalChange selection lookup by text. Defaults to false.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method except the last one that is reserved for passing the text to select.

Note: Modern applications might define their on UI elements that look like SELECT inputs but in reality are based on custom Javascript libraries that actually do not use the SELECT input type. In that case the annotation will not work.

Usage example: Select by text a day from the day dropdown

@Select(value = "//select[1]", by = Lookup.XPATH, byText = true)
SomePage selectDay(String day);

@SetValue

This method annotation allows setting a value of a form input.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find the input element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
scrollIntoViewBooleanoptionalWhether the page / parent element should be scrolled to make the input visible before actually setting the value. Default is false.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method except the last one that is reserved for passing the text to set.

Usage example: Enter the name in the input with id "name"

@SetValue(value = "name", by = Lookup.ID, scrollIntoView = true )
SomePage enterName(String name);

@SendKeys

This method annotation allows sending keys to a form input, like if you were typing from a keyboard.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find the input element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
keysStringmandatoryThe sequence of characters you want to send to the input field. In case this parameter of the annotation is not present, then the last parameter of the annotated method will be treated as the keys to send.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method except the last one if keys is not specified in which case the last argument is reserved for passing the keys to send.

Note: It's recommended that you focus on the input field first, by e.g., clicking on it. Otherwise, a warning will be logged, and the element will be implicitly clicked on before sending the keys

Note: On some configurations the function will detect the keyboard layout and map the keys to the primary char that the respective key on the keyboard would produce. This may have unexpected results. To overcome such problem we recommend to set the keyboard to US when using this annotation or to test the mapping that is effectively done on your configuration.

Usage example: Enter the name in the input with id "name"

@SendKeys(value = "name", by = Lookup.ID)
SomePage enterName(String name);

@StoreElementContent

This method annotation allows to store the visible text of an element in a store for later use, i.e., passing to another method, running complex verification logic, logging, etc.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
keyStringmandatoryThe key under the value will be stored, and to be used for value retrieval later on
globalStorebooleanoptionalWhether the value should be stored in a global store. Defaults to false.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Note: In case the HTML element is a "select", returns text(s) of selected option(s)

Usage example: Store the value of a field with id "name" in a global store using key "IMPORTANT-VALUE"

@StoreElementContent(value = "name", key = "IMPORTANT-VALUE", globalStore = true)
SomePage storeName();

@StoreAttributeValue

This method annotation allows to store the value of an element's specific HTML attribute in a store for later use, i.e., passing to another method, running complex verification logic, logging, etc.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.
keyStringmandatoryThe key under the value will be stored, and to be used for value retrieval later on
attributeNameStringmandatoryThe element's HTML attribute that should have its current value stored
globalStorebooleanoptionalWhether the value should be stored in a global store. Defaults to false.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Note: This annotation differs from @StoreElementContent in the sense that this one allows the user to select a specific HTML attribute to store its value for later use. @StoreElementContent, on the other hand, only stores the visible text from an element.

Usage example: Store the HTML attribute "value" from a field with id "name" in a global store using key "IMPORTANT-VALUE"

@StoreAttributeValue(value = "name", key = "IMPORTANT-VALUE", attributeName = "value", globalStore = true)
SomePage storeNameValue();

@Switch

This method annotation allows to select the flow of actions to take on a page during a test, depending on what elements are present or absent

The method return type must be an integer, based on which the tester will decide on the next steps in the test.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupmandatoryThe lookup method, e.g. XPATH. Defaults to the Application level default method
timeoutintoptionalTimeout in seconds waiting for the element to be visible, in case state is VISIBLE. Defaults to 30 seconds.
stateStateoptionalThe state we expect the element to be, after the timeout. Defaults to VISIBLE
returnOptionintmandatoryThe integer value to be returned, in case the condition for this option is the first one to be met

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

Usage example: Check for two elements that might be present in the page, and for one element that might be absent. The first condition to be met will have the value specified in its returnOption returned for the tester. Based on this, the tester can choose the next flow of actions.

Please, make sure that all the values specified for returnOption are different.

@Switch(value = "element_1", by = Lookup.XPATH, timeout = 10, returnOption = 1, state = State.VISIBLE)
@Switch(value = "element_2", by = Lookup.XPATH, timeout = 15, returnOption = 2, state = State.VISIBLE)
@Switch(value = "element_3", by = Lookup.XPATH, timeout = 5, returnOption = 3, state = State.ABSENT)
int checkForTwoVisibleElementsAndOneAbsentElement();

@SwitchToIframe

This method annotation allows to switch the page context to an iFrame element inside the page.

The user can then execute other actions inside the iframe, like searching for elements, clicks, double clicks, etc.

If the value attribute is left empty, the testing flow will go back to the default content, exiting all iFrames in the process.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find the iFrame / can be a format pattern. If empty, the action will go back to the default content.
byLookupmandatoryThe lookup method, e.g. XPATH. Defaults to the Application level default method
timeoutintoptionalTimeout in seconds waiting for the iFrame to be visible. Defaults to 30 seconds.

Usage example: Switch to an iFrame by XPATH and click on a button inside the iFrame. The locator for the button is relative to the iFrame context.


@SwitchToIframe(value = "/html/body/iframe", by = XPATH, timeout = 10)
@Click(value = "/html/body/button", by = XPATH)
SomePage switchToIframeAndClickButton();

Usage example: Switch back to the default content, and exit all iFrames.

@SwitchToIframe(value = "")
SomePage switchBackToDefaultContent();

@Wait

This repeatable annotation allows waiting until an element is present. It can be used both for methods and pages.

ParameterTypeMandatoryDescription
valueStringmandatoryThe value to lookup to find an element / can be a format pattern
byLookupoptionalThe lookup method, e.g. XPATH. Defaults to the Application level default method.
timeoutintoptionalTimeout in seconds waiting for the element to be visible. Defaults to 30 seconds.

value formatting: the parameter value can be a pattern. It will be formatted using String.format(pattern,object... args) where pattern will be the value and args will be the arguments of the annotated method.

If used on a page object, the wait mechanism will be applied before returning the instance of the page object. If used on a method, the method itself will be enhanced with the wait mechanism.

Note: All annotations using selectors like @Click, @ScrollIntoView have an implicit wait mechanism built in already and there is no need to use the @Wait annotation. The @Wait annotations use case is mainly to wait on some other elements that will not be directly interacted with but signal that something has been loaded.

Usage example: Wait until the page SomePage is loaded recognised as when the first div is present

@Wait(value = "//div[1]", by = Lookup.XPATH)
SomePage{
method1();
...
};

@AssertUrl

This method and page object annotation allows to assert the actual url with expected url. You can use it in web tests on method level and on page object.

ParameterTypeMandatoryDescription
valueStringoptionalThe value of expected url that will be asserted to actual url received from the web-browser.

The annotation can be used anywhere in the test. You can use it with the method when value of argument will be asserted or on the page object where the parameter value will contain the expected value of url. It will get the current url from the web-browser and assert it with the expected value.

Usage example:


import dev.pumpo5.actions.AssertUrl;

@Navigate(value = "https://pumpitup.cz")
public interface SomePage extends WebApplication {
@AssertUrl()
SomePage checkUrl(String url);

@Click(value = "somewhere_id")
SomePage clickLink();

SecondPage onSecondPage();
}

@AssertUrl(value = "https://pumpitup.cz/secondpage")
public interface SecondPage extends WebApplication {
}

class TestClass {
@Test
void testAssertUrl(Firefox1 webApplication) {
webApplication.open(SomePage.class)
.checkUrl("https://pumpitup.cz")
.clickLink()
.onSecondPage();
}
}