Relative Xpath from list of WebElements

20,650

Solution 1

Yes, this is definitely possible. See this:

// Find the outer element.
WebElement outer = driver.findElement(By.anything("whatever"));

// This doesn't work, it searches the whole page for the XPath expression.
WebElement inner = outer.findElement(By.xpath("//some/nasty/xpath"));

// This works! It takes the outer element as root.
WebElement inner = outer.findElement(By.xpath(".//some/nasty/xpath"));

Therefore, if I understood your need well, your XPath expression needs to look like this:

By.xpath("(.//tbody)[" + j + "]//div[text()=\"" + collector + "\"])")

EDIT (Holy cow, that's a lot of HTML and only a small amount of it is actually needed :).)

Now that I caught what you're after, I think you don't need this approach at all. Try this instead:

WebElement row = driver.findElement(By.xpath("id('CollectorQoSPerformanceMetricsgrid')//div[contains(@class,'x-grid3-row x-unselectable-single') and .//u[text()='" + collector + "']]"));

Only the XPath expression:

id('CollectorQoSPerformanceMetricsgrid')
    //div[contains(@class,'x-grid3-row x-unselectable-single')
          and .//u[text()='" + collector + "'] ]

Taken apart:

FIND ELEM WITH ID = 'CollectorQoSPerformanceMetricsgrid'
id('CollectorQoSPerformanceMetricsgrid')
    FIND ALL DIV ELEMS THAT CONTAIN 'x-grid3-row x-unselectable-single' IN @CLASS
    //div[contains(@class,'x-grid3-row x-unselectable-single')
          AND HAVE AN <U> DESCENDANT WITH TEXT EQUAL TO collector VARIABLE
          and .//u[text()='" + collector + "'] ]

This finds you only the single row you need with a single command.

If you rather want to stick with your current solution, try:

String rowsXpath = "id('CollectorQoSPerformanceMetricsgrid')//div[contains(@class, 'x-grid3-row x-unselectable-single')]";
List<WebElement> rows = driver.findElements(By.xpath(rowsXpath));
boolean foundCollector = false;
for(WebElement row : rows) {
    if(!row.findElements(By.xpath(".//u[text()='" + collector + "']")).isEmpty()) {
        foundCollector = true;
        break;
    }
}

Solution 2

Nowhere I found row (tr tag) in this xpath then how it will get rows count.

String rowsXpath = "//div[@id=\"QosDashpardPanelBottom\"]//div[@id=\"CollectorQoSPerformanceMetricsgrid\"]//div[contains(@class, \"x-grid3-row  x-unselectable-single\")]";

You need to construct xpath something like below to get row count in particular table

int rowCount=driver.findElements(By.xpath("//table[@class='x-grid3-row-table']/tbody/tr"))

Or else if you want to find all columns in that table with particular name

construct xpath like below

int columnCount=driver.findElements(By.xpath("//table[@class='x-grid3-row-table']/tbody//tr//td[@name='RequiredName']"))
Share:
20,650
so cal cheesehead
Author by

so cal cheesehead

Avid test engineer with a development background

Updated on March 01, 2020

Comments

  • so cal cheesehead
    so cal cheesehead over 4 years

    Is it possible to use a relative xpath after I've gathered a list of WebElements? If so what's the best way to do it?

    This is what I have:

    List <WebElement> rows = driver.findElements(By.xpath(rowsXpath));
    int j = 1;
    boolean foundCollector = false;
    for(WebElement e : rows) {
        String c = e.findElement(By.xpath("(//tbody)[" + j + "]//u[text()=\"" + collector + "\"])")).getText();
        if(c.equals(collector)) {
            foundCollector = true;
            break;
        }
        ++j;
    }
    

    the list rows contains individual rows with multiple columns and I'm trying to find the row which contains a particular name in a column. Within my for loop I was trying to use a relative xpath to look for an element, is this even possible? Or do I need to provide the whole xpath I used to find the rows with the additional xpath for the individual divs?

    I'm not guaranteed the order of the columns which is why I have to do it this way.

    This is the xpath I used to obtain the rows:

    String rowsXpath = "//div[@id=\"QosDashpardPanelBottom\"]//div[@id=\"CollectorQoSPerformanceMetricsgrid\"]//div[contains(@class, \"x-grid3-row  x-unselectable-single\")]";
    

    Here's the HTML:

    <body class=" ext-gecko ext-windows" onload="processLoaders();">
    <script type="text/javascript">
    <div id="topNavDiv" style="height: 90px">
    <div id="bodyContentOuter" style="width: 1280px; height: 587px;">
        <div id="bodyContentInner">
            <script src="RLT/RLT.nocache.js" language="javascript" type="text/javascript">
            <script defer="defer">
            <script language="javascript" type="text/javascript">
            <div id="rtcpMain" class=" x-component x-border-layout-ct" style="width: 1280px; height: 587px;">
                <div id="rtcpMainWest" class=" x-panel x-component x-border-panel" style="left: 5px; top: 5px; width: 225px;">
                <div id="x-auto-2" class=" x-tab-panel x-component x-border-panel" tabindex="0" hidefocus="true" style="left: 235px; top: 5px; width: 1040px;">
                    <div class="x-tab-panel-header x-unselectable" style="width: 1038px;" unselectable="on">
                    <div class="tone-rtcp-tabbed-content-panel" style="width: 1040px; height: 550px;">
                        <div id="x-auto-10" class=" x-component" style="overflow: auto; width: 1040px; height: 550px;">
                            <div id="QosDashboardPanel0" class=" x-panel x-component" style="width: 1040px;">
                                <div id="x-auto-13" class=" x-small-editor x-panel-header x-component x-hide-display" role="presentation">
                                <div id="rtcpDPBWrap" class="x-panel-bwrap" role="presentation" style="overflow: visible;">
                                    <div class="x-panel-tbar x-panel-tbar-noheader" role="presentation" style="width: 1040px;">
                                    <div id="rtcpDPBody" class="x-panel-body x-panel-body-noheader x-border-layout-ct" role="presentation" style="width: 1038px; height: 700px;">
                                        <div id="QosDashboardPanelTop" class=" x-component x-border-panel x-border-layout-ct" style="left: 0px; top: 0px; width: 1038px; height: 400px;">
                                        <div id="QosDashpardPanelBottom" class=" x-component x-border-panel x-border-layout-ct" style="left: 1px; top: 401px; width: 1036px; height: 298px;">
                                            <div id="QosDashpardPanel_pqosChartsLC" class=" x-component x-border-panel x-border-layout-ct x-hide-display" style="left: 0px; top: 0px; width: 1036px; height: 400px;">
                                            <div id="QosDashpardPanel_metricsTablesLC" class=" x-component x-border-panel x-border-layout-ct" style="left: 1px; top: 1px; width: 1034px; height: 296px;">
                                                <div id="CollectorMetrics_toneletWrapper" class=" x-panel x-component x-border-panel" style="left: 1px; top: 1px; width: 330px;">
                                                    <div id="x-auto-99" class=" x-small-editor x-panel-header x-component x-hide-display" role="presentation">
                                                    <div class="x-panel-bwrap" role="presentation">
                                                        <div class="x-panel-body x-panel-body-noheader" role="presentation" style="width: 328px; height: 292px;">
                                                            <div id="CollectorMetrics" class=" x-panel x-component" style="width: 328px;">
                                                                <div id="x-auto-109" class=" x-small-editor x-panel-header x-component x-unselectable" role="presentation" unselectable="on">
                                                                <div class="x-panel-bwrap" role="presentation">
                                                                    <div class="x-panel-body" role="presentation" style="width: 326px; height: 265px;">
                                                                        <div id="CollectorQoSPerformanceMetricsgrid" class=" x-grid-panel x-component" style="position: relative; width: 326px; height: 265px;" tabindex="0" hidefocus="true" unselectable="">
                                                                            <div class="x-grid3" role="presentation" style="width: 326px; height: 265px;">
                                                                                <div class="x-grid3-viewport" role="presentation">
                                                                                    <div class="x-grid3-header" role="presentation">
                                                                                    <div class="x-grid3-scroller" role="presentation" style="width: 326px; height: 243px;">
                                                                                        <div class="x-grid3-body" role="presentation">
                                                                                            <div id="CollectorQoSPerformanceMetricsgrid_x-auto-633" class="x-grid3-row x-unselectable-single x-grid3-row-selected x-grid3-highlightrow " style="width:510px;">
                                                                                                <table class="x-grid3-row-table" cellspacing="0" cellpadding="0" border="0" style="width:510px;" role="presentation">
                                                                                                    <tbody role="presentation">
                                                                                                        <tr role="presentation">
                                                                                                            <td id="x-auto-634" class="x-grid3-col x-grid3-cell x-grid3-td-name x-grid-cell-first " style="width:148px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-name" unselectable="on">
                                                                                                                    <u>Lync</u>
                                                                                                                </div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-635" class="x-grid3-col x-grid3-cell x-grid3-td-badCalls " style="width:53px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-badCalls" unselectable="on">36</div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-636" class="x-grid3-col x-grid3-cell x-grid3-td-totalCalls " style="width:58px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-totalCalls" unselectable="on">120</div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-637" class="x-grid3-col x-grid3-cell x-grid3-td-avgLatency " style="width:73px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-avgLatency" unselectable="on">223</div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-638" class="x-grid3-col x-grid3-cell x-grid3-td-avgLoss " style="width:53px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-avgLoss" unselectable="on">0.80</div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-639" class="x-grid3-col x-grid3-cell x-grid3-td-avgJitter " style="width:58px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-avgJitter" unselectable="on">29</div>
                                                                                                            </td>
                                                                                                            <td id="x-auto-640" class="x-grid3-col x-grid3-cell x-grid3-td-avgMOS x-grid3-cell-last " style="width:53px;" role="gridcell">
                                                                                                                <div class="x-grid3-cell-inner x-grid3-col-avgMOS" unselectable="on">3.86</div>
                                                                                                            </td>
                                                                                                        </tr>
                                                                                                    </tbody>
                                                                                                </table>
                                                                                            </div>
                                                                                            <div id="CollectorQoSPerformanceMetricsgrid_x-auto-641" class="x-grid3-row x-unselectable-single " style="width:510px;">
                                                                                                <table class="x-grid3-row-table" cellspacing="0" cellpadding="0" border="0" style="width:510px;" role="presentation">
                                                                                                    <tbody role="presentation">
                                                                                                        <tr role="presentation">
                                                                                                        <td id="x-auto-642" class="x-grid3-col x-grid3-cell x-grid3-td-name x-grid-cell-first " style="width:148px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-name" unselectable="on">
                                                                                                                <u>CUCM-Publisher</u>
                                                                                                            </div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-643" class="x-grid3-col x-grid3-cell x-grid3-td-badCalls " style="width:53px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-badCalls" unselectable="on">3</div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-644" class="x-grid3-col x-grid3-cell x-grid3-td-totalCalls " style="width:58px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-totalCalls" unselectable="on">52</div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-645" class="x-grid3-col x-grid3-cell x-grid3-td-avgLatency " style="width:73px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-avgLatency" unselectable="on">190</div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-646" class="x-grid3-col x-grid3-cell x-grid3-td-avgLoss " style="width:53px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-avgLoss" unselectable="on">0.79</div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-647" class="x-grid3-col x-grid3-cell x-grid3-td-avgJitter " style="width:58px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-avgJitter" unselectable="on">31</div>
                                                                                                        </td>
                                                                                                        <td id="x-auto-648" class="x-grid3-col x-grid3-cell x-grid3-td-avgMOS x-grid3-cell-last " style="width:53px;" role="gridcell">
                                                                                                            <div class="x-grid3-cell-inner x-grid3-col-avgMOS" unselectable="on">3.98</div>
                                                                                                        </td>
                                                                                                        </tr>
                                                                                                    </tbody>
                                                                                                </table>
                                                                                            </div>
                                                                                        </div>                                                                                                          
    
  • so cal cheesehead
    so cal cheesehead over 11 years
    I tried it but it doesn't work, I get no results. I think I'm running into a problem with accessing individual rows. The full xpath if i try "//nasty/xpath/(.//tbody)[1]" on firebug for instance I don't get anything back.
  • Petr Janeček
    Petr Janeček over 11 years
    @alexxp03 I use it on a daily basis, so the construct definitely works. You'll just have to come up with the right Xpath. If you can, post your HTML code in here, we'll work it out!
  • so cal cheesehead
    so cal cheesehead over 11 years
    I'd be glad to, this is driving me nuts. The html is quite large what's the best way to get it and post it?
  • Petr Janeček
    Petr Janeček over 11 years
    @alexxp03 Copy it into notepad, remove everything that seems to be unrelated to your case. Then simply edit it into your question. If it's still too large, use pastebin.com or something. I'll be back in half an hour. You can also start a chat room for this and post here the link, if you want.
  • so cal cheesehead
    so cal cheesehead over 11 years
    0k i posted the html although the formatting is horrible i'm not sure how helpful it's going to be.
  • so cal cheesehead
    so cal cheesehead over 11 years
    I also put in the string i use to obtain the rows which would be my root element
  • so cal cheesehead
    so cal cheesehead over 11 years
    I posted more readable Html hopefully you can still take a look. thanks!
  • so cal cheesehead
    so cal cheesehead over 11 years
    my question here was whether I could use relative paths after finding a whole. Assuming your rowCount xpath is correct, how would I access individual column values within the row reprinted by rowCount?
  • Petr Janeček
    Petr Janeček over 11 years
    @alexxp03 Sorry about the delay :(. I have just updated my answer with a solution to your problem rather an answer to your question ;).
  • Vince Bowdren
    Vince Bowdren about 9 years
    @socalcheesehead Remember you always need the leading dot in a relative xpath i.e. ./some/more/xpath/, not //some/more/xpath or `/some/more/xpath