What is this @FindBy ?
It’s an annotation on Selenium that organize the elements and using the PageFactory, these WebElements are usually initialised when a Page Object is created. It’s a best practice of Page Object Models, but more than this is a way to let your group of elements well-structured and just call when you need it.
The @FindBy annotation is used to locate one or more WebElements using a single criterion. For example:
@FindBy (id = "id_element" ) private WebElement element; |
To create the instance for these elements, you can use:
PageFactory.initElements(driver, this);
For the cases you want to search for all the given criteria, you can use @FindBys and for the ones you want to search for at least one of the given criteria, @FindAll
So, for example:
Using @FindAll:
@FindAll ({ @FindBy (name = "username" ), @FindBy (name = "password" ) }) private List<WebElement> loginfields; |
The loginfiends list should contain the element with name = username and the element that contains name = password, 2 elements. If you use @FindBys it wouldn’t bring anything, since there is no element with two names (both of the criteria).
So, this structure makes the code much easier to read. You should place the @FindBy in the beginning of your page object class.
What is the Object repository ?
It could be a properties/text file where you place all the locators for the elements and you use selenium to call each one. The property file contains a collection of key-value pairs, with the key being a logical name identifying the object and the value containing unique objects properties used to identify the object on a screen. You can use this concept of Object Repository for any language, not only Java and not only with Selenium.
It contains the key of the element and the value to find it. The corresponding value consists of two parts: the attribute type used for uniquely identifying the object on screen and the corresponding attribute value.
After this, you need to create a class to get the elements . For example:
As you can see, objects can be identified using a number of different properties, including object IDs, CSS selectors and XPath expressions.
Now you can use these in your scripts to execute any scenario. You just need to call the Map repository and get the locator key.
So, in the end you just need to update this properties file with the new locators.
The aim of both of the methods is to reduce the maintenance time when you have new locators. If you are using Selenium, I suggest you to use @FindBy since it’s a good practice and the framework provides this option, but you don’t have this for all the test frameworks in the market, for those you can have a map repository.
Cheers guys, see you next weekend 🙂
Resources:
http://www.ontestautomation.com/findby-strategies-for-selenium-explained/
http://www.ontestautomation.com/building-and-using-an-object-repository-in-selenium-webdriver/
Hey Rafaela, nice write-up and a good comparison of both strategies, It might be worth mentioning though (and this is something I didn’t think of myself either when writing those two blog posts) that neither of these approaches works when dealing with variable element locators. For instance, if you have a link without an id or name attribute and with a changing but predictable link text, you can use
driver.findElement(by.linkText(myLinkText));
where myLinkText holds the link text for that test run, day, environment, …
You won’t be able to use such a locator with either the PageFactory or an object repository.
Thanks for linking to my blog posts, that’s well appreciated.
Thank you Bas, I was not aware if this, will update the post ! What a pleasure you commenting here 🙂
Sure! I make a habit of checking out the blog posts that link to mine, there’s always more to learn!
I needed to thank you for this very good read!! I absolutely enjoyed every little bit of it.
I have got you bookmarked to look at new stuff you post…
Great post 🙂
I would recommend the other way (Map/Object repository). Using Selenium we have this functionality to associate elements inside the code, but it only works with Selenium/Appium.
If you use another tool that you can apply Page Objects only Map/Repository will works.
Have you “problems” with scripts maintenance with FindBy approach? (lke all the time open the properly class, compile and execute)
Regards!
Ah yes, totally agree ! This is not for all frameworks, unfortunately. Oh, I haven’t had the chance to work extensively with @FindBy approach, maybe for this reason I didn’t have such problems. I am curious now, will try it here and let you know Elias 🙂