Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding WebElements, best practices

In our current automation (using Selenium/WebDriver/Java), we use @FindBy very extensively. For example:

@FindBy(css="a[name='bcrumb']")    protected List<WebElement> breadCrumbLinks;
@FindBy(id="skuError")         protected WebElement skuError;  
@FindBy(className="reducedPrice")  protected List<WebElement> reducedPrice;
@FindBy(partialLinkText="Injinji RUN 2.0")  protected WebElement playButton;
@FindBy(linkText="annual member refund")    protected WebElement annualMemberRefund;
@FindBy(xpath="//li[@itemprop='price']")    protected WebElement productPrice;

By definition, @FindBy can locate a selector using the following: using, id, name, className, css, tagName, linkText, partialLinkText and xpath.

Recently, our front-end devs proposed that we implement an new attribute class that begins with 'test='. I think this is a great idea since we could find WebElements by just looking for that blurb of text, rather than the values that @FindBy inherently uses. My question is, would it be better to extend the existing functionality of @FindBy OR, create a new way of searching for the WebElements we use in our tests?

like image 546
Brian Avatar asked Jul 03 '13 17:07

Brian


3 Answers

First off, there are no "best practices," just ones that work well in your particular context. Sorry, that's an old gripe of mine...

I wouldn't spend the effort for custom attributes unless you can't work with an existing approach. I prefer using existing locators (find logic) where possible.

Whenever possible, use ID attributes. If the page is valid HTML, then IDs are unique on the page. They're extraordinarily fast for resolution in every browser, and the UI can change dramatically but your script will still locate the element.

Sometimes IDs aren't the right choice. Dynamically generated IDs are almost always the wrong choice when you're working with something like a grid control. You rely on an id that is likely tied to the specific row position and then you're screwed if your row changes.

In some of these cases your devs can help you out by appending or prepending constant values to a dynamically generated ID value. ASP.NET Webforms does crazy stuff with dynamically generated values, so I've used a suffix to my advantage several times.

Link text, name attribute values, and CSS selectors (JQuery style) are great second choices when you can't get a stable, reliable ID, or one's just not available.

XPath is my last choice in nearly all situations. It's slow, can be extremely brittle, and is hard to deal with when it's a complex XPath. That said, if you need to move up and down the page DOM for your locators, then it's the only choice.

Using one of the existing FindBy methods means you'll be using a well-understood, well-supported locator strategy. That's a big bonus when you're trying to figure out an old test, or when onboarding someone new to your team.

That's my $0.02.

like image 62
Jim Holmes Avatar answered Nov 17 '22 11:11

Jim Holmes


I think this will help Selenium Locators Best Practices

Tastiest Locators: ID Name Class Link Text or Partial Text

Yummy Locators Index XPath Child Elements CSS Properties Edible Locators JS Events DOM Elements KeyStrokes Coordinates

like image 37
Stormy Avatar answered Nov 17 '22 11:11

Stormy


If I understood you correctly you can continue using @FindBy annotation with css selectors such as css = "[test='...']".

like image 1
user2525437 Avatar answered Nov 17 '22 11:11

user2525437