0

I have started using Page factory, and now i need to provide xpath in @FindBy. It will be great if someone can provide any suggestion or reference on how to pass variable in xpath using @Findby.

Element which i want to replace with @Findby annotation

for(i=1; i <= liElements.size(); i++) {
   WebElement linkElement = driver.findElement(By.xpath("//li[" + i + "]/div//a[contains(@class, 'btn-mini')]"));
   linkElement.click(); 
}

Thanks a lot in advance for your help.

ievche
  • 1,735
  • 14
  • 22
user16165
  • 297
  • 1
  • 4
  • 9
  • From your post it is not standing out the core issue. Would you please clarify if you notice any error or sample html you are trying to find? – Rao Nov 04 '16 at 12:33
  • I want to replace my code with @FindBy annotation. I am not sure how can i achieve it. – user16165 Nov 04 '16 at 12:51
  • Can you please check the sample [here](https://github.com/SeleniumHQ/selenium/wiki/PageFactory) and see if that is helpful? – Rao Nov 04 '16 at 12:53
  • Possible duplicate of [What is the use of Annotation "@FindBy"?](http://stackoverflow.com/questions/9028757/what-is-the-use-of-annotation-findby) – Markus Nov 04 '16 at 12:55
  • Simple answer No. You cannot do it. Reason: your webelements-locator map gets initialized when you make a call to PageFactory.initElements, you would have to make repeated calls to it, besides annotation are meta data which gets fixed during class loading itself. the only way to change would be via reflections and i doubt if it will be worth at all taking reflection route. Its unnecessary pain that you will have to bear, i would recommend keep it simple as it is already – Mrunal Gosar Nov 04 '16 at 13:11
  • Oh that's bad. But then is it a good practise to use @Findby annotation for all other page elements and use driver.findElement only for one element? – user16165 Nov 04 '16 at 13:29
  • I would avoid the use of PageFactory unless you have very static pages. PageFactory scrapes the entire page when the page is loaded. If anything changes on the page or you have a dynamically loading page, you are going to have to rescrape the page every time it changes anyway. Switch to scraping only when needed and I think things get a lot easier. – JeffC Nov 04 '16 at 13:53

1 Answers1

2

Regarding your question around parametrised FindBy - this is not possible as annotations are constant values. Take a look here - Can the annotation variables be determined at runtime?

In this particular case you can find a list of the elements in FindBy:

@FindBy(xpath = "//li/div//a[contains(@class, 'btn-mini')]")
private List<WebElement> links;

Then you can iterate through them like this:

for(WebElement link : links) {
    link.click(); 
}

So you will click links found by that xPath one by one.

Community
  • 1
  • 1
ievche
  • 1,735
  • 14
  • 22
  • Amazing, thanks a lot. I was exactly looking for this :-) I will use this code and let u know the result . – user16165 Nov 04 '16 at 14:41
  • Looks `@FindBy(xpath = "//li/div//a[contains(@class, 'btn-mini')]")` needs to be changed to `@FindBy(xpath = "//li/div/a[contains(@class, 'btn-mini')]")`? Please recheck. – Rao Nov 04 '16 at 15:39
  • @Rao, this only depends on html structure, which is behind the scene. However 1st option is more generic. But on the other hand it can find elements that topic-starter do not need. – ievche Nov 04 '16 at 15:42