Testing maintenance

Hii, I am new to the testing world. I have started with katalon studio and its wonderful so far.
But I have a question like the way in which I am doing ui testing of my website is I am capturing Objects for every element I want to test and saving in object repository and then using them for my test.
Isn’t it hard to maintain this as there will be changes in my website daily and I can’t go and capture objects daily. I want a dynamic kind of testing. Is it possible…??

Any help would be highly appreciated …!!

Thank you.

It depends how you write the locator of TestObject.

If you ignorantly depend on the tools like Katalon Spy/Recorder to generate the Test Objects for you and if you disregard the detail of locator expressions, then the maintenance will be hard and endless like Le Mythe de Sisyphe.

But if you study the background technologies (XPath & CSS Selector), you can possibly rewrite the tool-generated locators manually to new ones which can select the HTML elements as intended and are tolerant against HTML changes.

Do you want to know more? Then you should present a sample case as the basis of discussion. Could you share an actual example:

  1. HTML source of your web page before/after change; please tell us which HTML element is of your interest
  2. A Test Object which locates the HTML element. Please show the locator expression you used before/after the HTML source change.

Thanks for the response kazurayam. Is it possible to locate objects in the way you mentioned using katalon. Like I am performing testing against my ui which looks something like the screenshot attached. Now here I have applications listed and I have a download button. I have to validate whether the download button works fine or not. Now I have already performed a testing where I am capturing the object using katalon spy and then calling a keyword which validates whether the download was successful or not.
My question is what to do when another application gets added tomorrow. My test script will not test it because I have not captured that object.

The number of rows changes frequently, and you want to verify the 1st row, 2nd, 3rd … every rows in the grid?

Most probably, yes, you can make it. But you need to have more of technical insight. The Spy tool introduce you to the testing world, helps you start working on your problem, but it does not solve your problems out of box. You need to be able to write TestObject manually.

Please show the HTML page source of your target web page, and the locator (XPath or CSS Selector) of the TestObject which were generated by the Spy tool and which you currently use.

You might want to learn how to use “Google Chrome Developer Tool” in order to view the internal of Web pages.

I copied the xpath → //*[@id=“applications_form:applications:70:j_idt242”]

I suspect that id is dynamic, meaning it will change each time the page is loaded. That means you will need to use a different locator to target the button.

You are dealing with a page/website built using Primefaces (PF - a JavaServer Faces library). To get a full and robust understanding of the task you are trying to master, you will need to learn how PF produces HTML markup.

Any one of us, including @kazurayam, could produce a locator for that button if you provide enough of the HTML - that screenshot is too short/small. But even so, you would do better if you search the web for anything that connects Selenium and Primefaces (I found a number of articles and a few on StackOverflow). This will help you start to figure out how to build better locators in the future.

Right now, based on the limited HTML you provided, I’d try using this CSS locator:


In CSS, $= means “ends with” : find the id that ends with idt242

If you need to work row by row like @kazurayam was asking, then your locator needs to be a bit more generic. Use the following as a starting point (assuming your grid is using HTML <tr> elements)

tr button[type=submit]

For a given <tr> element, that css will find ALL buttons of type submit. If there’s only one per row, you’re good to go. If there’s more than one, you might need to index the css or improve it to retrieve the correct one.

1 Like

Thank you for sharing information.

Unfortunately this piece of information does not help much.

//*[@id=“applications_form:applications:70:j_idt242”] — which node in the target web pages does this xpath corresponds? It seems that this xpath is pointing to a node which would display a text "Download" somewhere in the page. But I can not find a text "Download" displayed in the screenshot you provided. So this example does not make sense to me.


Could you describe what kind of test you want to perform?

I guess, you might want to perform one or more of the following terms, but you haven’t expressed which.

  1. you want to verify if a text "XYZ App" is displayed somewhere in the page no matter where
  2. you want to verify if a text "ABC Buggy App" is not displayed anywhere in the page no matter where
  3. you want to verify if a text "XYZ App" is displyed in the 3rd row of the grid in the page; it must be in the 3rd row, finding it in the 1st and 2nd row in not acceptable
  4. you want to verify that every row in the grid have 4 cells (Name, Infrastructure, Deployments, Created by), and those 4 cells should not be empty, should display any text of length > 0.
  5. you want to every row have 3rd cell (titled Depoyments) with clickable link. You want to test if the link is actually clickable and URL is valid.
  6. you want to find at most 10 rows in the page; finding 11 rows ore more is not acceptable.
  7. you want the rows are sorted in the ascending order of "Name"s
  8. you want to find a row with XYX App to appear only once, not repeated twice or more.

… many more possibilities

Here I do NOT require you to list all terms you want to perform (the Specification) and disclose it to us. I just want you to share with us at least ONE testing scenario you actually want to perform using the tool. If you tell us 1 practical scenario of testing, then we would understand your problem more clearly and we would be able to start discussing how to implement it. Your problem might be perfectly obvious to you, but is not to others unless you tell it.

If you want to implement this test, then you would want to create a TestObject with the following locator in XPath.

//*[contains(text(), 'XYZ App')]

The Spy/Recorder tool will never generate this sort of (highly abstract and expressive) locator. You can come up with it and create it only manually.

Hey actually if you see in the action column of the screenshort there is a download button. So I wanted to click that no matter where is it in the ui because my ui will be updated daily.

xpath looks something like this : -

In your position as the Test Engineer there is nothing wrong with you asking the developers to accommodate your task by making key elements (like buttons etc) more identifiable for testing purposes. For example, you could ask that they incorporate data-* attributes which, along with the regular attributes might help you find key elements much easier.

If the buttons are moving as much as you say (honestly, I am not convinced they are) then you should speak up.

1 Like

In the new screenshot you provided, I found that your web page has <td> tags.

<td role="gridcell">...</td>

This implies that the HTML has at least 1 <TABLE> element which has one or more <tr> element. The <tr> element represents rows of a grid. The overall structure of the page would be as follows.

...<!-- more markup here -->
<table id="TBL1">
    <td><!-- Type/Tool --></td>
    <td><!-- Config --></td>
    <td><!-- Resource --></td>
    <td><!-- Date --></td>
    <td><!-- Status --></td>
    <td><!-- Summary --></td>
    <td><!-- Actions-->
        <button><!--  --></button>
        <button><!-- Download --></button>
        <button><!--  --></button>
        <button><!--  --></button>
        <button><!--  --></button>
<!-- more rows here -->
...<!-- more markups here -->

Now let me assume that the table has id="TBL1" that uniquely identifies that table among all.

The Download button in the 1st row can be expressed by a xpath:

The Download button in the 2nd row can be expressed by a xpath:

The Download button in the 3rd row can be expressed by a xpath:

and so on. No matter how many rows you have in the page, you can identify a single Download button by those XPath expressions in a uniform format.

Let me assume you have 10 rows in a grid and you want to verify if a Download button is there for each rows.

Then, do you need to create 10 TestObjects to select them?

No, you need only 1 parameterised TestObject. The TestObject would have following locator:


Please note a placeholder ${ROWINDEX} is introduced here. The formal specification of XPath by W3C does NOT include such placeholder syntax. So, the above line is not a valid XPath expression; it is a XPath-like notation specific to TestObject in Katalon Studio.

And in the test case script, you will interpolate the placeholder with actual value (1, 2, 3, …) by the following code:

for (int rowIndex = 1; rowIndex <= 10; rowIndex++) {
    TestObject tObj = findTestObject("yourTestObjectId", ['ROWINDEX': rowIndex])
    WebUI.verifyElementPresent(tObj, 8)

See the following page for detail explanation about parameterizing Web Test Objects

The above code assumed that the number of rows is static and known to be 10. That assumption is un-realistic. You would want to inspect the <table> and find out how many rows are there. Of course, you can detect the number of rows dynamically by code. However this issue would bring you too far. I would not talk about it now.

Thanks @kazurayam, sorry for the late reply as I was unwell. The problem currently I am facing is the id is dynamic. It keeps changing in few days.
Like say the xpath is —> //button[@id=‘applications_form:applications:0:j_idt242’]/span
Now this id 242 keeps changing. It is also there in css selector option. It is difficult for me to test as these id is automatically generated by primeface, Is there any way I can test this dynamic thing.

You can ignore the changing part: 242. Try changing the XPath expression to :

//button[starts-with(@id, 'applications_form:applications:0:j_idt')]/span

If you have multiple button elements with id attribute which starts with applications_form:applications:0:j_idt and you want to select the 2nd button, then you can write:

//button[starts-with(@id, 'applications_form:applications:0:j_idt')][2]/span

Just in case that the part in between applications: and :j_idt (e.g, 0) is also changing, then you can ignore that as well by writing as follows:

//button[starts-with(@id, 'applications_form:applications:') and contains(@id, ':j_idt')][1]/span