How to find unique selectors for elements on pages with ExtJS for use with Selenium?

I use Selenium with Firefox Webdriver to work with elements on the page with unique CSS IDs (each time the page loads), but the IDs change every time, so I can not use them to find the element. This is because the page is a web application built using ExtJS.

I am trying to use Firebug to get item information.

I need to find a unique xPath or selector so that I can select each element separately with Selenium.

When I use Firebug to copy xPath, I get this value:

//*[@id="ext-gen1302"] 

However, the next time the page loads, it looks like this:

 //*[@id="ext-gen1595"] 

On this page, each element has this identifier format, so the CSS identifier cannot be used to find the element.

I want to get xPath in terms of its position in the DOM, but Firebug will return the xPath identifier, since it is unique to this page instance.

 /html/body/div[4]/div[3]/div[4]/div/div/div/span[2]/span 

How can I get Firebug (or another tool that will work at the same speed) to give me a unique selector that can be used to search for an element with Selenium even after changing the ext-gen identifier?

+4
source share
3 answers

Another victim of ExtJS UI Automation testing, here are my tips specifically for ExtJS testing. (However, this will not answer the question described in your title)

Tip 1: Never use unreadable XPath, for example /div[4]/div[3]/div[4]/div/div/div/span[2]/span . One tiny replacement of the source code can lead to a change in the structure of the DOM. This will result in huge maintenance costs.

Tip 2: Use meaningful auto-generated partial identifiers and class names.

For example, this ExtJS grid example: By.cssSelector(".x-grid-view .x-grid-table") will be convenient. If there are many grids, try indexing them or finding an identifiable ancestor, such as By.cssSelector("#something-meaningful .x-grid-view .x-grid-table") .

Tip 3: Create meaningful class names in your source code. ExtJS provides cls and tdCls for custom class names, so you can add cls:'testing-btn-cancel' to your source code and get it By.cssSelector(".testing-btn-cancel") .

Tip3 is the best and last. If you don’t have access to the source code, talk to your manager, Selenium UI automation should really be a developer’s task for those who can change the source code, and not a user-like tester.

+4
source

I would recommend using CSS in this case by doing By.cssSelector("span[id^='ext-gen'])

The above statement means "select a span element with id that starts with ext-gen". (If you need to be more specific, you can answer, and I'll see if I can help you).

Alternatively, if you want to use XPath, look at this answer: Xpath to select the html id, including a random number

+1
source

Although in some cases, as mentioned above, is undesirable, you can parse the elements and generate xpath identifiers.

 import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class XPATHDriverWrapper { Map xpathIDToWebElementMap = new LinkedHashMap(); Map webElementToXPATHIDMap = new LinkedHashMap(); public XPATHDriverWrapper(WebDriver driver){ WebElement htmlElement = driver.findElement(By.xpath("/html")); iterateThroughChildren(htmlElement, "/html"); } private void iterateThroughChildren(WebElement parentElement, String parentXPATH) { Map siblingCountMap = new LinkedHashMap(); List childrenElements = parentElement.findElements(By.xpath(parentXPATH+"/*")); for(int i=0;i<childrenElements.size(); i++) { WebElement childElement = childrenElements.get(i); String childTag = childElement.getTagName(); String childXPATH = constructXPATH(parentXPATH, siblingCountMap, childTag); xpathIDToWebElementMap.put(childXPATH, childElement); webElementToXPATHIDMap.put(childElement, childXPATH); iterateThroughChildren(childElement, childXPATH); // System.out.println("childXPATH:"+childXPATH); } } public WebElement findWebElementFromXPATHID(String xpathID) { return xpathIDToWebElementMap.get(xpathID); } public String findXPATHIDFromWebElement(WebElement webElement) { return webElementToXPATHIDMap.get(webElement); } private String constructXPATH(String parentXPATH, Map siblingCountMap, String childTag) { Integer count = siblingCountMap.get(childTag); if(count == null) { count = 1; } else { count = count + 1; } siblingCountMap.put(childTag, count); String childXPATH = parentXPATH + "/" + childTag + "[" + count + "]"; return childXPATH; } } 

Another shell for creating identifiers from a document is available at: http://scottizu.wordpress.com/2014/05/12/generating-unique-ids-for-webelements-via-xpath/

+1
source

Source: https://habr.com/ru/post/1495004/


All Articles