Naveen
Katalon Apprentice
04/05/2017

How to handle dynamic xpath ?

Hi Team,
I am facing difficulties in handling dynamic xpath. I have a table, the contents of table changes depending on the previous steps.

Ex : 
//[@id="aaaa.CountryRolePhasesView.readyByDate_editor.0"]
//
[@id="aaaa.CountryRolePhasesView.readyByDate_editor.1"]
//*[@id="aaaa.CountryRolePhasesView.readyByDate_editor.2"]

In above example, number changes. How can we handle this ? can we pass a variable to test objects to achieve this ? If yes, please provide the procedure for the same.

Also, how to get the number of elements matching a xpath, like "findelements" in selenium. Eg : List<WebElement> tableList = driver.findElements(By.xpath()));

Please let me know if any other information is required.
Appreciate your help!

Thanks.

Upvote
Quote

Comments

  • Vinh Nguyen
    Katalon Expert
    04/05/2017
    Hi there,

    Suppose you have a variable called 'changedValue' and you want to pass it into 'xpath' of existing test object 'cell'Table' (the dynamic element ):
    changedValue = 0
    TestObject to = findTestObject('cellTable')

    'Change xpath property to new value'
    to.findProperty('xpath').setValue('//*[@id=\u201Daaaa.CountryRolePhasesView.readyByDate_editor\u2033].' + changedValue)
    You can refer to other functions of TestObject class in this page. After the test object's value has been changed, you can then use it freely in other step, e.g: WebUI.click(to)

    2. To get the number of elements matching a xpath, like “findelements” in selenium. Eg : List<WebElement> tableList = driver.findElements(By.xpath()));

    => You should utilize DriverFactory class and its functions

    Example code:
    WebUI.openBrowser('http://demoaut.katalon.com)

    WebDriver driver = DriverFactory.getWebDriver()
    List&lt;WebElement&gt;tableList = driver.findElements(By.xpath()));

    WebUI.closeBrowser()
    We have a similar concern regarding to dynamic element, which you can find here
    Upvote
    Quote
  • Naveen
    Katalon Apprentice
    04/07/2017
    Hi Nguyen,
    Appreciate your help here. I have tried above and still facing issue. Kindly find below as the code i have tried.

    1. Code
    WebDriver driver = DriverFactory.getWebDriver()
    List tablelist1 = driver.findElements(By.xpath('//*contains(@id,"aaaa.CountryRolePhasesView.CountryRoleAndPhase_Table:\")]'))

    Result : Test Cases/TC01_ProjectCreation FAILED because (of) Variable 'By' is not defined for test case.

    2. Code
    TestObject to = findTestObject('Unilever/Page_CreateProject/TextField/input_aaaa.CountryRolePhasesVi')
    to.findProperty('xpath').setValue('id(\"aaaa.CountryRolePhasesView.tacCode_editor4.' + RowId + '\")')
    WebUI.click(to)

    Original xpath, as in captured by Katalon : id("aaaa.CountryRolePhasesView.tacCode_editor4.0")

    Results : Success

    3. Is it possible to use existing parameters of test objects and modify the same. Let say in above case, xpath is id("aaaa.CountryRolePhasesView.tacCode_editor4.0"), now i wanted to change this to -
    id("aaaa.CountryRolePhasesView.tacCode_editor4.+rowid+"). So i can have single custom function, which can be used for different fields of the table, instead of hard coding the partial xpath.

    Kindly Help and appreciate your support :)-
    Upvote
    Quote
  • Jason Roberts
    Katalon Apprentice
    09/22/2017

    Hi,

    I have a similar issue in attempting to locate a dynamic xpath id. Here is an example:

    //*[@7dfb13b9eab5"]/div[2]/div[5]/table/tbody/tr/td

    where the above id is dynamic. The element is a calculated numeric value.

    Any ideas?

    Thanks,

    Jason Roberts

    Upvote
    Quote
  • Paul Johnson
    Katalon Apprentice
    11/13/2017

    Naveen By should be by ( not capitlised) Jason, the way i got round this was to look in the script view and define the variable, and then referecne the variable in the xpath statement. the define line appears in the manual view as a binary value. Hope this helps

    Upvote
    Quote
  • Dave Evers
    Katalon Apprentice
    04/11/2018
    edited April 11

    Naveen By should be by ( not capitlised) Jason, the way i got round this was to look in the script view and define the variable, and then referecne the variable in the xpath statement. the define line appears in the manual view as a binary value. Hope this helps

    Hi Paul or Vinh,
       Could you please include an example of how you were able to change a test object's xpath value & then use WebUI.click(to)? I've tried the code as suggested by Vinh, but I am not having any luck with changing the objects xpath values.

    My code:
    changedValue = 100
    TestObject to = findTestObject('Dynamic.Objs/Page_AdvisorWeb Login/img_login')
    to.findProperty('xpath').setValue("//*[@id = 'login']" + changedValue)
    WebUI.click(to)
    xpath result:


    Thanks,
    Dave
    Upvote
    Quote
  • Mate Mrse
    Katalon Ambassador
    04/12/2018
    You could try this:
    changedValue = 100
    TestObject to = WebUI.modifyObjectProperty(findTestObject('Dynamic.Objs/Page_AdvisorWeb Login/img_login'), 'xpath', 'equals', '//*[@id = 'login']"+changedValue', true)
    WebUI.click(to)
    Upvote
    Quote
  • Marek Melocik
    Katalon Ambassador
    04/12/2018
    Hi Dave,

    How is your TestObject defined? It is case sensitive, so if your property name is XPATH and you use lower-case version xpath in the test code, it won't work.

    Also, you may use XPATH selector type instead of Basic properties:


    In this case, the code must be slightly different. See a simple example:

    TestObject to = findTestObject("Misc/test")

    // get Map with <SelectorMethod, String> pair
    Map allSelectors = to.getSelectorCollection()

    // println original value of XPATH selector
    println allSelectors.get(SelectorMethod.XPATH)

    // update the value
    to.setSelectorValue(SelectorMethod.XPATH, "//some/other/path")

    // println new value of XPATH selector
    allSelectors = to.getSelectorCollection()
    println allSelectors.get(SelectorMethod.XPATH)

    // console output

    04-12-2018 09:17:25 AM - [START] - Start action : Statement - println(allSelectors.get(XPATH))
    //some/path
    04-12-2018 09:17:25 AM - [END] - End action : Statement - println(allSelectors.get(XPATH))
    04-12-2018 09:17:25 AM - [START] - Start action : Statement - to.setSelectorValue(XPATH, "//some/other/path")
    04-12-2018 09:17:25 AM - [END] - End action : Statement - to.setSelectorValue(XPATH, "//some/other/path")
    04-12-2018 09:17:25 AM - [START] - Start action : Statement - allSelectors = to.getSelectorCollection()
    04-12-2018 09:17:25 AM - [END] - End action : Statement - allSelectors = to.getSelectorCollection()
    04-12-2018 09:17:25 AM - [START] - Start action : Statement - println(allSelectors.get(XPATH))
    //some/other/path
    04-12-2018 09:17:25 AM - [END] - End action : Statement - println(allSelectors.get(XPATH))




    Upvote
    Quote
  • Marek Melocik
    Katalon Ambassador
    04/12/2018
    edited April 12
    delete please
    Upvote
    Quote
  • Dave Evers
    Katalon Apprentice
    04/12/2018
    Hi Marek,
    Thanks for your suggestions ;-)
    I am using the XPath selector type = //*[@id="login"]

    But I am not able to click on the 'login_btn' can you see where I am going wrong?

    TestObject login_btn = findTestObject("Chk.Xpath/Page_AdvisorWeb Login/img_login")
    login_btn.setSelectorValue(SelectorMethod.XPATH, '//*[@id="login001"]')
    Map allSelectors = login_btn.getSelectorCollection()
    println ('NewXpath: ' + allSelectors.get(SelectorMethod.XPATH))
    //My result= NewXpath: //*[@id="login001"]
    WebUI.click(login_btn)
    Results:
    04-12-2018 10:51:45 AM - [START]  - Start action : click
    04-12-2018 10:51:45 AM - [INFO]   - Checking object
    04-12-2018 10:51:45 AM - [INFO]   - Checking timeout
    04-12-2018 10:51:45 AM - [INFO] - Finding web element with id: 
    'Object Repository/Chk.Xpath/Page_AdvisorWeb Login/img_login' located by 'By.xpath: //*[@id="login001"]' in '30' second(s)
    04-12-2018 10:52:17 AM - [FAILED] - Unable to click on object 'Object Repository/Chk.Xpath/Page_AdvisorWeb Login/img_login' 
    (Root cause: com.kms.katalon.core.webui.exception.WebElementNotFoundException: 
    Web element with id: 'Object Repository/Chk.Xpath/Page_AdvisorWeb Login/img_login' 
    located by 'By.xpath: //*[@id="login001"]' not found)


    Upvote
    Quote
  • Marek Melocik
    Katalon Ambassador
    04/13/2018
    Hi Dave,

    looks like you entered incorrect XPath as there's WebElementNotFoundException - Katalon is unable to find specified object on a page.

    Make sure you are using correct path - doublecheck if you are on the correct page when you call WebUI.click() and/or open Dev console in browser and check if button ID you use is correct.
    Upvote
    Quote
  • anja.brand
    Katalon Apprentice
    04/13/2018

    Hi,

    I also want some help on this topic. I am just starting using Katalon.
    The objects on the webpage are build dynamically from scratch. 

    Using basic objects properties it can’t perform the click action:

    It's not able to find the object. The message:
    Test Cases/PIM/Menu catalogus FAILED because (of) Unable to click on object 'Object Repository/PIM/2.Menu_onderdelen/Menu_Catalogus' (Root cause: org.openqa.selenium.WebDriverException: unknown error: Element <div data-uid="1" class="item">...</div> is not clickable at point (214, 12). Other element would receive the click: <div class="src-loading-overlay"></div>

    So I tried xpath
    Using Spy Web I can find the right xpath e.g. //*[@menu"]/div[1]
    I checked that with the verify and highlight option in the method xpath.
    No scrolling is needed.

    httpsforumkataloncomuploadseditorz2nwwsc88doq6hpng

    <div class="src-ui-menubar" id="main-menu" style="left: 176px; top: 1px; width: 1157px; height: 24px;">
    <div class="item" data-uid="1"><span>Catalogus</span></div>
    <div class="item" data-uid="2"><span>Item</span></div>
    <div class="item" data-uid="3"><span>Gefilterde&nbsp;items</span></div>
    <div class="item" data-uid="4"><span>DAM</span></div>
    <div class="item" data-uid="5"><span>Beeld</span></div>
    <div class="item" data-uid="6"><span>Extra</span></div>
    <div class="item" data-uid="7"><span>Help</span></div>
    <div class="clear"></div></div>

    This testcase is also not able to perform the click action on the Testobject.
    The message:

    Test Cases/PIM/Menu catalogus - Click FAILED because (of) Unable to click on object 'Object Repository/PIM/2.Menu_onderdelen/Menu_Catalogus' (Root cause: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: 'Object Repository/PIM/2.Menu_onderdelen/Menu_Catalogus' located by 'By.xpath: ' not found)

     

    Scriptmode:

    WebUI.openBrowser('')
    WebUI.maximizeWindow()
    WebUI.navigateToUrl('vms01-t/')
    WebUI.waitForPageLoad(GlobalVariable.TimeOut)
    WebUI.sendKeys(findTestObject('PIM/1.Page_Login - SRC-PIM Regressie/username'), 'AnjaENG')
    WebUI.sendKeys(findTestObject('PIM/1.Page_Login - SRC-PIM Regressie/password'), '???????!')
    WebUI.click(findTestObject('PIM/1.Page_Login - SRC-PIM Regressie/btn_login'))
    WebUI.waitForElementVisible(findTestObject('PIM/2.Menu_onderdelen/SRC_Logo'), 0)
    WebUI.click(findTestObject('PIM/2.Menu_onderdelen/Page_SRC-PIM Regressie (1)/span_Catalogus'))

    I tried to work with the Dynamic object but I am struggling with the scriptmode. With the examples mentioned it is not clear what to do.

    Can somebody please tell me what the script has to be?


    Upvote
    Quote
Sign In or Register to comment.