Forum Discussion

Don's avatar
Don
Contributor
8 years ago

WebApp: Clicking on a button in a grid cell

Hello Community.

 

I'm having an issue that I can't figure out and hopefully someone can help me. I have a grid on a web application that has several rows and columns. I know the sample pic below shows the same name but for the purpose of this thread lets say the names are SaveIncomplete1, SaveIncomplete2, etc. 

 

I want to click on the edit button for say SaveIncomplete1 but I'm unable to do so. I've tried using Xpath Descendant, and Sibling but it always errors out. Any suggestions are greatly appreciated.

 

Regards

 

  • Can you post the code of what you've actually tried?  

     

    Here's what we're doing. These two functions combined can take any table and, given the particular set of parameters, click on the child link within the found cell within the table.

    function findRow(tableObject, stringSearch, searchColumn, maxRows = 0) {
        var cellFound = Utils.CreateStubObject();
        var upperLimit;
        if (maxRows == 0) {
            upperLimit = tableObject.RowCount;
        } 
        else {
            upperLimit = maxRows;
        } 
        if ((searchColumn == 999) || (searchColumn == undefined)) {
            cellFound = tableObject.FindChild('innerText', aqConvert.VarToStr(stringSearch) + '*', 0, true);
        }
        else {
            for (var i = 1; i < upperLimit; i ++) {
                if (aqString.Trim(tableObject.Cell(i, searchColumn).innerText) == aqString.Trim(aqConvert.VarToStr(stringSearch)) ) {
                    cellFound = tableObject.Cell(i, searchColumn);
                    break;
                } 
            
            } 
        }
        if (cellFound.Exists) {
            return cellFound.RowIndex;
        }
        else {
            return -1;
        }
    }
    
    function clickTableColumn(stringToFind, objectTableInput, colIndexToClick, searchColumn = 999) {
    
        var rowFound;
        if (objectTableInput.Exists) {
            rowFound = findRow(objectTableInput, stringToFind, searchColumn);
            objectTableInput.Cell(rowFound, colIndexToClick).Child(0).scrollIntoView(true);
            objectTableInput.Cell(rowFound, colIndexToClick).Child(0).Click();    
            }
        else { 
            throw Error('Unable to find the table '+ objectTableInput.MappedName) ;
        }               
    }




  • Don's avatar
    Don
    Contributor

    Here's my solution after trying different ones. You can use the following-sibling but you have to dig into the code to get the proper xpath. The Xpath tool i use in firefox does not provide this. 

     

     

    This is the line of code that I used which calls the object in test complete

    var editLink = Sys.Browser("*").Page("*").FindChildByXPath("//td[contains(text(),'"+num+"')]/following-sibling::td[@aria-describedby='ApprovalPreDelivery_Approve']//span[@class='afexLink']//img[@class='edit']");  

     

    The first xpath is the main parent and you must use the following-sibling property to call on the child nodes. I tried removing the following-sibling and replace it with a // but that fails my test case. 

     

    I'm sure a similar solution is somewhere here in the community but I am posting my solution in the hope that it helps out other community members. If you need help understanding it. Please feel free to send me a PM. I will try to answer as soon as I can.

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    Can you post the code of what you've actually tried?  

     

    Here's what we're doing. These two functions combined can take any table and, given the particular set of parameters, click on the child link within the found cell within the table.

    function findRow(tableObject, stringSearch, searchColumn, maxRows = 0) {
        var cellFound = Utils.CreateStubObject();
        var upperLimit;
        if (maxRows == 0) {
            upperLimit = tableObject.RowCount;
        } 
        else {
            upperLimit = maxRows;
        } 
        if ((searchColumn == 999) || (searchColumn == undefined)) {
            cellFound = tableObject.FindChild('innerText', aqConvert.VarToStr(stringSearch) + '*', 0, true);
        }
        else {
            for (var i = 1; i < upperLimit; i ++) {
                if (aqString.Trim(tableObject.Cell(i, searchColumn).innerText) == aqString.Trim(aqConvert.VarToStr(stringSearch)) ) {
                    cellFound = tableObject.Cell(i, searchColumn);
                    break;
                } 
            
            } 
        }
        if (cellFound.Exists) {
            return cellFound.RowIndex;
        }
        else {
            return -1;
        }
    }
    
    function clickTableColumn(stringToFind, objectTableInput, colIndexToClick, searchColumn = 999) {
    
        var rowFound;
        if (objectTableInput.Exists) {
            rowFound = findRow(objectTableInput, stringToFind, searchColumn);
            objectTableInput.Cell(rowFound, colIndexToClick).Child(0).scrollIntoView(true);
            objectTableInput.Cell(rowFound, colIndexToClick).Child(0).Click();    
            }
        else { 
            throw Error('Unable to find the table '+ objectTableInput.MappedName) ;
        }               
    }




    • Don's avatar
      Don
      Contributor

      Thanks for the quick reply.

       

      I usually just do something like this

       var editLink = Sys.Browser("*").Page("*").FindChildByXpath("//td[@id='SaveIncomplete']/descendant::img[@role='editLink']");

       

      I have also used following-sibling instead of descendant. Usually that works for other methods but this one is giving me some problems.

      • tristaanogre's avatar
        tristaanogre
        Esteemed Contributor

        While FindChildByXpath works well in many situations, one problem I have with it is that it is scanning the whole page to find the particular Xpath.  I'm not particular fond of that aspect of things hence why I use the more targeted FindChild that allows you to find the specific children of a specific parent object... in this case, the edit link in cell in the row that contains the target text.  I'm not familiar enough with FindChildByXpath to comment on why that code isn't working for you. Sorry.  Our code that I posted before works well for any table that we want to click in a control in a column.