plaidshirt
plaidshirt

Reputation: 5671

Identify elements on Angular based site for WebDriver

There is an Angular based site, which doesn't use unique names/ids for elements. XPATH of elements are not permanent on page, so WebDriver based test has to be changed after each modification on site. How could I manage elements on this page without use of XPATH?

Upvotes: 2

Views: 1637

Answers (3)

MivaScott
MivaScott

Reputation: 1806

Don't rely on JUST one selector method!

You can use any of the other findElement() options such as cssSelector, name, tagName, etc. And more to the point, you don't have to use them singly. In other words, go as far as you can via one method and then switch to another. Here is a Java example of starting with XPath and finishing with css:

private final String xGrid = "//div[contains(@class,'lists-grid')]/div[contains(@class,'ui-grid')]";
private final String xGridWrapper = "/div[contains(@class,'ui-grid-contents-wrapper')]";

@FindBy(xpath = xGridScopeSubscriptions + xGridWrapper)
private List<WebElement> gridRecordList;

public void clickGridSubscriptionActionEditByRow(int row) {
    int totalColumns = gridRecordList.size();
    int actionColumn = getColumnIdByHeader("Action");

    WebElement actionCell = gridRecordList.get((totalColumns * row) + actionColumn);
    WebElement editButton = actionCell.findElement(By.cssSelector("button.subscription-edit-btn"));

    editButton.click();
}

Mind you, this is kind of a hodgepodge of different things, but I hope you get the idea.

Start with Strings to define key markers in the code. Concatenate the strings to assign a WebElement variable for starting points. Then in methods, using the starting point, do findElements() from there based on different selectors.

You can even do it all in one shot.

private WebElement deleteIcon driver.findElement(By.id("name-list")).findElement(By.cssSelector("div.grid-ui div.grid-cell")).findElement(By.xpath("./td[3]/i[contains(@class,'fa-trash')]"));

I know you said that the ID's are not stable, but I just wanted to give you an example of stringing together different methods of finding elements to reach your final goal.

Upvotes: 0

alecxe
alecxe

Reputation: 473833

First of all, follow the Page Object pattern to at least have the locators defined in one place - inside page objects. This would help to address the changing UI.

Other things to consider:

  • It's the slowest and most brittle locator strategy of all

  • Markup is very easily subject to change and therefore xpath locators require a lot of maintenance

  • xpath expressions are unreadable and very hard to debug

  • do not rely on the structure of the page or relative position of elements to each other
  • avoid repeating locators or parts of the locators - the more you repeat the more you will need to change when the design/UI changes
  • remember that elements like div or span are just containers - using them inside locators is rarely justified
  • make your locators readable and based on data - not design or layout. For instance, don't use Bootstrap layout-oriented classes like col-md-4 or col-xs-6
  • follow some of the common best practices suggested in these articles:

Upvotes: 2

W&#252;rgspa&#223;
W&#252;rgspa&#223;

Reputation: 4820

Simple question, simple answer:

If you cannot use names/ids and do not want to use xpath, you are limited to css selector, class name, tag name - and (partial) link text when dealing with links.

Maybe this article helps.

Upvotes: 0

Related Questions