-
Notifications
You must be signed in to change notification settings - Fork 3
Higher level abstractions
####Extracted Method Often in webapps there are particular concepts that are specific to the app or domain, which we want to refer to frequently. For example we may have an introduction section on a page, that is represented in html like:
<div class="section-introduction">...</div>
To locate this, we can of course use div().that( hasCssClass("section-introduction"))
but if it's needed frequently this can get repetitive and error-prone.
We can easily abstract this by creating a method :
private static MFinder<...> introductionSection() {
return div().that( hasCssClass("section-introduction"));
}
and the assertion becomes: browser.assertPresenceOf( introductionSection() );
This also means if we change what an introduction section looks like in html we just have to change it in one place.
####..with parameters
If we have lots of types of sections:
<div class="section-introduction">...</div>
<div class="section-conclusion">...</div>
we can just parameterise the method :
private static MFinder<...> section(String sectionType) {
return div().that( hasCssClass("section-"+sectionType));
}
and assertions become
browser.assertPresenceOf( section("introduction") );
browser.assertPresenceOf( section("conclusion") );
...
####..and a nice description
For the above examples, if something wasn't found, you'd still get the message in terms of divs and css class.
Expected: a(n) div that has css class "section-introduction"
but:
No element with cssClass "section-introduction" found at all
If instead, you think it makes more sense to use your domain/abstraction's terminology then it's easy to make that happen by using the Describer.describedAs method, which just wraps a Finder and gives it a new name to refer to it as:
private static MFinder<...> section(String sectionType) {
return Describer.describedAs(sectionType +" section", div().that( ...));
}
Now if your assertion fails you would get:
Expected: a(n) introduction section
but:
No element with cssClass "section-introduction" found at all
The expectation part is now in your domain's terms, although the explanation is always in low-level terms.
####More complex example This is particularly useful when you have more complex finder expressions:
public MFinder<...> menuItem(String optionText) {
return describedAs("Menu item " +optionText,
div().that(hasCssClass("menu-option"))
.that(hasSubElement( link(optionText))));
}
The above defines a "menu item" by looking for a div with css class "menu-option" which surrounds a link (<a>
tag) with the text shown.
So:
menuItem("Home")
would be a finder for the div element below:
<div class="menu-option">
<a href="...">Home</a>
...
</div>