@FindBy: Adding custom search strategy

559 views
Skip to first unread message

Vitali Kasyanenka

unread,
Nov 20, 2015, 4:36:49 AM11/20/15
to Serenity BDD Users Group
Hi everyone. I'm working on different test solutions where we use custom search strategies/locators and would like to be able to use them with the @FindBy annotation like, for example:

@FindBy(flash="flash_locator")
WebElement flashElement;

I've started digging into the serenity code trying to find a way of adding new search strategies, but found out that in order to be able to do that I'll need to use some custom element locator factory and later understood that it's impossible to do. 

Have I understood it correctly? Is it true that we cannot add new locator types without changing the existing serenity code?
Message has been deleted

Sumit Ghosh

unread,
Aug 18, 2017, 5:04:05 AM8/18/17
to Serenity BDD Users Group
Hi Vitali ,

Do you have any breakthrough in this. I am also looking for solution around it.

Thanks
Sumit

SeleniumWhat?

unread,
Aug 18, 2017, 2:40:53 PM8/18/17
to Serenity BDD Users Group
You're not allowed to manipulate the pre-defined @FindBy(<Xpath|CSS> string).  The @Findby() does not take a string argument either.  You can not pass any argument to it.  There are no other way around this.  It's a "pre-defined" path.  

But you are able to use the jquery $() method to get the element that you want when you want it.

The $() can take $(<Xpath|CSS> string)
For example:
  Let say you want to click on a dynamic element.  The element is only displayed as a result of some previous action.  But you know that path to the element.
   * In the class where you want to get the element,  you set your the path (either Xpath or CSS)  of your desired element to variable:
  String desiredElelment = "//x/y/x/<desiredElement>"; (this is an example of Xpath, you can use CSS path as well).
   * Then You get the desired element by using query $() method:
   $(desiredElelment).click();
  Just make sure that you are on the right page where the desired element is rendered.
  Need more help?  Post your code and explain what you want to do so folks can look into it.
  Good luck!
  J.N

Sumit Ghosh

unread,
Aug 23, 2017, 8:59:23 AM8/23/17
to Serenity BDD Users Group
But in selenium we can create custom locator. But I wondering the same can be achieved here or not.

Thanks
Sumit 

SeleniumWhat?

unread,
Aug 23, 2017, 10:22:51 AM8/23/17
to Serenity BDD Users Group
 
Hi Sumit,
  I'm not sure of what you meant when you said "we can create "custom locator" .  Do you mean you create a whole brand new locator module yourself?  If so, then why you try to re-invent the wheel?  One of these search strategies: XPath, CSS selector and Jquery can do anything that you want to do....so... why the need to create a new search method?
  I gather what you meant is that you try to pass a object variable to the path string?  If this is the case, then the answer is yes: (1) insert that object variable to the path string, and (2) then use $() to get the desired element.
  To made thing clearer, I recommend that you post your code and explain what you try to do,  Only then we can understand what you really meant by "custom locator".
  J.N
  

Sumit Ghosh

unread,
Aug 24, 2017, 8:54:33 AM8/24/17
to Serenity BDD Users Group
Hi J N,

Thanks for your reply.

We are planning  to introduce custom locator like

 @AutoXpath(xpath = "Line of Business, 1")
 public WebElementFacade ddl_line_of_business;

instead of 

 @FindBy(xpath = "//td[contains(., 'Line of Business')]/following-sibling::td//select")
 public WebElementFacade ddl_line_of_business;

as writing xpath takes lots of time for us.The user only have to pass the name of the object & index in case of duplicate. Behind the scene we are going to write generic xpath which will take name & index of object as parameter and return the WebElementFacade.

We are expecting this will going to reduce the effort require to identify complex xpath as well as training\KT require to identify the xpath for junior colleagues as we are facing lots of issues in writing xpath.

Please let me know how can we achieve a solution for it.  

Thanks
Sumit

John Smart

unread,
Aug 24, 2017, 9:00:58 AM8/24/17
to Sumit Ghosh, Serenity BDD Users Group
Have you considered using Screenplay? This sort of thing is trivial to do with Screenplay tests.

--
You received this message because you are subscribed to the Google Groups "Serenity BDD Users Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thucydides-users+unsubscribe@googlegroups.com.
To post to this group, send email to thucydides-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
___________________________________________________
John Smart | Wakaleo Consulting  |  +44 7398 832273
Making smart teams collaborate better
http://johnfergusonsmart.com  |  john....@wakaleo.com
___________________________________________________

We love breaking down silos and helping smart teams collaborate better! Ask about our tailored on-site workshops in Agile Product Planning, BDD Requirements Discovery,  BDD, TDD and Clean Coding, and Advanced BDD Test Automation.

Need some help with Serenity BDD? Check out our Serenity BDD training and support packages here.
___________________________________________________

SeleniumWhat?

unread,
Aug 24, 2017, 9:59:56 AM8/24/17
to Serenity BDD Users Group

Hi Sumit,
        Now I see what you meant. It confirmed my assumption that you wanted to pass a variable object string  to the XPath string.  Re-read my two previous posts on this thread again if you missed it.
        So, again, the answer is "Yes" but you need to do it a bit differently.  I need to walk you thru the process, but I'm not available until this Friday. So stay tuned. 
        I'll try my best to give you and other poster who is also new Selenium + Serenity + Cucumber the model that I built.
        You will see my post in other thread in addressing his questions.  I will address your questions as well in the thread.
        I also believe you misunderstood the use of @FindBy() functional interface because you - and I as well - are not sure how it was implemented.  But you are not alone, so don't feel bad :-).
        Rest assured that I have a solution for your question(s).
        See you on Friday !
        J.N
        PS: as John Smart just suggested, if you decide to go with Screenplay model then you don't have to worry about this, but I think what you try to do is much different from what he suggested.

SeleniumWhat?

unread,
Aug 24, 2017, 10:26:58 PM8/24/17
to Serenity BDD Users Group
Hi Sumit,
  I would separate the test case writers from the test developers.  Don't let them work on the element mapping if they don't understand how the search strategies work.  I recommend also you use the CSS selector or jQuery.  It is faster than XPath.
  
  You can get rid of  all @FindBy() annotation (functional interface) because you want to pass/change the path of the element based on a passed value.
  Based on the example you gave, I would implement something like this:

  // Set the template path with a &objectID& variable.
  String ddl_line_of_business = "//td[contains(., '&objectID&')]/following-sibling::td//select";

 // When you get a passed objectID "objectID"('Line of Business') value, replace the "&objectID&" variable with the passed value "objectID"
 // Create a method to handle the following code. 
 // The red one is a passed value to the method.  The blue one is your local variable
   this.ddl_line_of_business = ddl_line_of_business.replaceAll("&objectID&",objectID);

//Then get the desired element using jQuery $()
   WebElementFacade desired_ ddl_line_of_business = $(this.ddl_line_of_business);

// Now you can operate on the desired_ ddl_line_of_business element as a WebElementFacade element.
  
Reply all
Reply to author
Forward
0 new messages