-
Notifications
You must be signed in to change notification settings - Fork 0
Element Locating
If Vani instantiates a PageObject
or FragmentObject
class, it will create a proxy for all fields annotated by locator annotation. So it's possible to instantiate the class although desired html elements are still unavailable.
If you don't want to get only a single matching element, the type of annotated field must be List
. In that case, the generic type of the List
is important, because this will be used for resolving target element type. For example
@FindBy(className= "componentBox")
private List<WebElement> components;
//or for using fragments
@FindBy(css = "${content.css.componentBox}")
private List<ComponentFragment> components;
In the above example, the list instance is also a proxy. So any call on the instance, will trigger the locating.
Selenium provides a feature called Cache Lookup. This means, that only the first access triggers the locating. After that, the same html object will be always used.
To enable this feature. you have to annotate the corresponding field with @CacheLookup
.
The handling of this feature by Vani differs little bit from Selenium. Vani will always cache all matching element except single WebElement
or JQueryElement
due to performance reasons. If the page is changed, you must call the invalidate
method on PageObject
or only on single fragment
when not the complete page was changed.
Selenium brings some annotations for declaring specific locating strategy of elements. These are following:
- FindBys - allows you to declare multiple selectors at once with AND conjunction (all selectors must be fulfilled)
@FindBys({@FindBy(id = "foo"),
@FindBy(className = "bar")})
-
FindAll - similar to
FindBys
but it uses OR as conjunction (at least one selector must be fulfilled)
@FindAll({@FindBy(how = How.ID, using = "foo"),
@FindBy(className = "bar")})
-
FindBy - allows various selectors like
id
,name
,className
,cssSelector
,tagName
,xpath
orlinkText
@FindBy(id = "foobar")
Vani supports all of them and provide you the power of springs's placeholder mechanism. For example:
@FindBy(id = "${content.id.login.username}")
Additionally, Vani gives you the possibility to use jQuery's selectors. So you are more flexible and they are more powerful than Selenium's one. For example:
@FindByJQuery("${content.jq.searchInput}")
private JQueryElement inputSearch;
In the above example, we use the JQueryElement
class as type for our field. It's also possible to use the normal WebElement
class, because JQueryElement
is only a subclass of it, which provides some jQuery function counterparts.
The regex selector can also be used in the @FindByJQuery
annotation.
For more information about using jQuery, please see jQuery Integration or for complete documentation about all jQuery selectors.
If you want multiple matching elements, you should not use a list, because the JQueryElementLocator
holds a reference on a jQuery object (which has itself an array of matching html elements).
If you want to implement an own locating strategy, you have to do following steps:
- Create your Locator-annotation (like
@FindByJQuery
) - Create your
By
implementation (likeByJQuery
) - Create an implementation of
LocatorBuilder
(This class is responsible for creating an instance of yourBy
implementation by converting your Locator-annotation. For example seeJQueryLocatorBuilder
implementation).
That's all. You don't have to instantiate the locator builder. This will be done by Vani