Dynamic xpath for Drop down

Hi guys,

I’m very new to Katalon Web Testing and I’m trying to get the dynamically get the xpath in my application.
I’ve a drop-down list (list of locations).
My application can access different instances by changing the url. Functionality for each instance remains the same. But, the list of locations for each instance may be different. I’m trying to search for a location say, A-ABC on my first instance and record the testing it works fine when i play it. But when I run the same test case on another instance it fails to find that location, because i the second instance the Location lies in a different list index.

Eg:

  1. Xpath for 1st instance-> //*[@id=“main”]/div[1]/div[1]/div[3]/div/div/ul/li[7]/a/span[1]
  2. Xpath for 2nd instance-> //*[@id=“main”]/div[1]/div[1]/div[3]/div/div/ul/li[8]/a/span[1]

So, the li index has changed from 7 to 8 from first instance to second.
Can someone help me find a solution to run my application without having to manually change the xpath every time i switch between the instances.

1 Like

Maybe try to define a list of elements… and depends of instance operate on them.

1 Like

This might help,

l1: for (int j = 1; j < 11; j++)
 {
    String location= (' //*[@id=“main”]/div[1]/div[1]/div[3]/div/div/ul/li[' + j) + ']/a/span[1]'

    locationObj = WebUI.modifyObjectProperty(findTestObject('Object Repository/ICW_SideMenu/MenuItem/menuitem'), 'xpath', 'equals', 
       location, true);

String locationtext = WebUI.getText(locationObj);

    if (locationtext == 'Enter Your location') {
        WebUI.click(locationObj)
       

        j = 11
}
    
}
1 Like

Hi,

You should try to identify more attributes in your XPath so that it is not influenced when the instance is restarted.
I don’t know the contents of the page you are automating (that would have helped a lot) but adding more attributes to the XPath would help in your issue.
As an example in one webpage I identified the li by using id so XPath is something like //*[@id=“main”]//li[@id=‘id_of_li’]/a/span.
You can use different attributes to help identify the objects better. You can use XPath helper on Google Chrome to test your XPath (it helps me a lot).

1 Like

These are examples of what are known as “highly position-dependent xpaths”, which are a cardinal sin for XPath enthusiasts. They are what the recorder will usually return to you, because they aren’t very good at determining relative xpaths.

So you need smarter relative xpath for sure (your topic reads “Dynamic xpath…”, but in general, xpaths are static, so you really need a “smarter” xpath to locate a dynamic element). Using the index of an element is generally not a good thing, as you’ve obviously found. I second @cristian.ivanescu, we need to see your HTML to give you a good example xpath to use.

1 Like

@Mariusz @Harshavardhan_K @cristian.ivanescu @Brandon_Hein Thanks for your time and reply.

My li tag does not have an id attribute against it. Also, the list is dynamically refreshed by the js which shifts the index.

However is there a way where I can get the xpath of a test object. Say, I search a location by setText and get the xpath of the location where it occurs and then set that xpath to a variable and then modify the current xpath in the Object repository with the value of the xpath stored in the variable.

I’m not sure if this is valid. I need your opinions please. Thanks in advance.

Hi All,

I’m just thinking of all the possible solutions. Is it possible to use regex to get the xpath of a test object.

Can i define the xpath with regex in Object repository or in the script mode?.

Is there any reason why you can’t share a snippet of the HTML? I’m pretty confident we can solve your problem using xpath alone. Just need to see what you are working with…

@Brandon_Hein
Below is the html, I hope this helps…

<div class="col-xs-10" id="main" style="min-height: 500px;">
  <div class="body">
      <div class="row m-b">
           <div class="col-xs-4">
           <div class="col-xs-2">
           <div class="col-xs-6">
             <style type="text/css">
              <script type="text/javascript">
                <div class="my-grp my-select form expand">
                <button type="button" class="btn dropdown-toggle" data-toggle="dropdown" data-id="chooseMyLocation" title="A-ABC" aria-expanded="true">
                <div class="my-dropdown expand" style="max-height: 315px; overflow: hidden;">
                <div class="my-search">
                  <ul class="my-dropdown unorderedList" role="menu" style="max-height: 260px; overflow-y: auto;">
                    <li class="my-dd-header hidden" data-optgroup="1">
                    <li data-original-index="0" data-optgroup="1" class="hidden">
------>other lists in between


                    <li data-original-index="4" data-optgroup="2" class="active">
                      <a tabindex="0" class="options" style="" data-tokens="null">
                        <span class="text">A-ABC</span>
                        <span class="glyphicon-ok"></span>
                      </a>
                    </li>


------> followed by all the other list of locations ....
                </ul>
              </div>
<select id="chooseMyLocation" name="chooseMyLocation" show-tick="" class="form selectMyLocation" data-live-search="true" data-size="10" tabindex="-98" style="visibility: visible;">
------> others

Please let me know if you need any other info. Thank you. :slight_smile:

I hope you didn’t type all of that up by hand :sweat_smile: You can always just take a screenshot of the HTML and past it here. That’s usually easier.

Anyway, give this xpath a try:

//a[.//span[text()='A-ABC']]

In English, this says: “find the link element(s) which has a child span with text ‘A-ABC’”. Notice that it doesn’t care WHERE that link exists in the HTML.

1 Like

@Brandon_Hein

Oh, no i just copy pasted the code snippet and formatted it.

I’ll try the solution that you suggested. Many thanks. :slight_smile: