Index number using test object attributes

My preference is to use attributes (as opposed to xpath) for test objects in the object repository. However, is there a way to specify the second occurrence/index of a match?

For example, let’s say I want to capture the text of the second link labeled “Click” on a page…
tag equals a
text equals Click
index equals 2

I mention “index” because that’s what it’s called in UFT.

I know that I could specify [2] if I’m using xpath, but I’d rather stick to attributes if possible.

Pretty sure that’s not possible using attrs. Even CSS can’t do that if you need to match the text “Click”. If they’re near each other structurally, then you could use CSS :nth-child() or :nth-of-type().

Failing that, there’s always JavaScript… but I’m guessing you don’t want that if you’re looking for a declarative/static solution stored in OR.

1 Like

What do you mean by saying “attributes” here?

In the following screenshot, I chose “Attributes” out of 3 options of “Selected Method”, and I wrote a XPath expression in the list of “Detect objects by” of an “Attributes”.

Is it preferable for you?

Hi Kazurayam,
Not really no. Using XPaths can be a little fragile at times, whether you specify them with the Xpath or Attributes method. I would like to specify something like “click on the second occurrence of a link that is labeled as ‘Home’” for example. It would be nice if I could add three attributes, like this:
tag=a
text=“Home”
index=1 (assumes zero based, so the first occurrence would be 0, the second would be 1)

If you’ve ever used QTP/UFT before, this is an option of “Ordinal Identifier”. See attached screenshot.

Note that this isn’t too big a deal now, I can still use XPaths to do what I want, I was just surprised that Katalon didn’t also have this index option.

UFTIndex

Katalon only has Selenium.

Selenium only has XPATH, CSS and JavaScript (you know, that stuff the web is built from :wink: )

Having said that, Katalon is certainly mature enough to have its own tools that extend what’s currently on offer.

@Jass?

OK, you can express this in XPath: (//a[text()="Home"])[2]

In XPath, the index of node-set starts with 1, not 0.

Yes, you are right. Katalon Studio generates several instances of XPath expressions as candidates. Many of them are fragile for HTML design changes.

However XPath is a language that can express a node in a document by many variations of expressions. You would be intelligent enough to think and write more robust XPath expressions manually just as you are capable in QTP/UFT.

Thanks Russ, I think the problem here is that I’m not doing a good job of explaining what I am looking for. I’ve used the XPATH solution, but what I’m after is a way to do this through Katalon’s UI with Attributes. For example, if I choose the Attributes method over the XPath method, I can click the “Add” button and select “tag” and type in the value “a”, and type a property of “id” and type a value, I can type property of “href” and type a corresponding value, etc, but… to my knowledge there’s no way to specify a value of “index” (or some other equivalent keyword) and specify a value of 0, 1, 2 or whatever. The only way I can do this is to manually edit the XPath. Does that make any more sense?

1 Like

Hi Kazurayam. Please see the response I just type to Russ here, I don’t think I’m doing a good job of explaining exactly what I mean. It appears that the only way to do this is by manually editing the Xpath (appending “[2]” for example), whereas what I would like is to use the Attributes method, select a value of “index” (or some other similar keyword) and typing a property of 0, 1, 2 or whatever. In other words, making it more UI driven than manually editing an Xpath. Does that make any sense?

The best way to describe your problem is to share the HTML source code of your target Web page. Without the HTML source, you can not describe problems in automated testing of Web UI clear enough.

c/c @sara.leslie

I created a demo project at GitHub to explain my idea. I hope my HTML is similar to @gengland’s target.

clone out this project, and you want to open and run the “Test Cases/TC1”. In browser, you will see this:

See the HTML source: genglands_selecting_HTML_tag_with_position_index/target.html at master · kazurayam/genglands_selecting_HTML_tag_with_position_index · GitHub

Problem to solve

I want to click the 2nd <a> tag with the content text Click, which links to the movie “007”.

Solution

Test Case in action

See how the sample project works

Test Cases/TC1 source

See the source: genglands_selecting_HTML_tag_with_position_index/Script1645484417089.groovy at master · kazurayam/genglands_selecting_HTML_tag_with_position_index · GitHub

Core of the solution

I wrote a XPath to select the 2nd anchor tag : (//a[text()='Click'])[2]

Description

In the XPath expression, find a pair of ( and ) before [2].

In the XPath v1.0 Specification of W3C, 3.3 Node-sets, the Predicate prepended with a pair of ( and ) is described as “FilterExpr”

Conclusion

@gengland

I suppose that you just did not know how to use the pair of ( and ) to construct a FilterExpr in XPath. If you use it appropriately && manually, you should be able solve your problem using XPath completely.

Katalon Studio is ignorant of the FilterExpr either. But you shouldn’t blame them. The FilterExpr is a Lightsaber lightsaber of XPath Jedis who can manually write every possible expressions in XPath syntax. Enough training is required. KS is not a Jedi.

Perhaps your favourite QTP/UFT works the same as FilterExpr of XPath implicitly.

By the way …

@Russ_Thomas

How would you solve this using CSS Selector?

You can’t match content with CSS.

Thank you for the reply

Thanks kazurayam, I really appreciate you taking the time over this, but this is not what I’m asking, I’m having trouble communicating my thoughts. What I’m asking for (if it doesn’t already exist) is a slight tweak in the UI for specifying the instance number. Your website example correctly illustrates what I’m trying to test against, but I’m trying to avoid having to add (for example) “[2]” to the end of an xpath manually, and do it through Katalon’s UI attributes “helper” that constructs the xpath.
If I click on the Add button of the Object’s Properties pane, I have a dropdown list of class, css, id, name, title and xpath. It would be nice to have an additional option for the instance number, so if you set it to “2” it would append “[2]” to the xpath. Does that make more sense? See screenshot attached.

OK. This is a Frequently Asked Question in this forum.

Katalon offers a solution to this problem with title “Parameterized Test Object”. See

I have updated my demo project on GitHub. It has a Test Object anchor_Click_to_each_movie with a locator like this

(//a[text()='Click'])[${i}]

Please note this locator has a “place holder” ${i} which should be interpolated by the index values like 1, 2, 3.

How this “place holder” is interpolated with the index values?

Please find Test Cases/TC3

This Test Case has lines as follows, where the placeholder ${i} is interpolated by the index values.

for (int i = 1; i <= numberOfAnchors; i++) {
    TestObject anchor = findTestObject("anchor_Click_to_each_movie", ["i":i])
    ...

Please find a mythical literal : ["i": i]. With this, a placeholder ${i} is supplied with an integer value to be interpolated with.

I would like to remind you that my previous “Test Case/TC2”, which does not use “Object Repository” at all, already used the concept of “Parameterized Test Object”.

Please find the code

for (int i = 1; i <= numberOfAnchors; i++) {
	TestObject anchor = byXPath("(//a[text()='Click'])[${i}]")
        ...

in Test Cases/TC2

This line is doing just the same string interpolation as new Test Cases/TC3.

1 Like

Thanks again kazurayam. On the one hand, this still isn’t quite what I was looking for, and I really don’t know how else to try and explain myself. I think Russ nailed it from the start by saying that what I am after isn’t possible using attributes. I was hoping to find a way for some of our team members that are new to automation and unfamiliar with xpath to identify objects purely from making selections from the attributes view. It’s not a big deal though, this doesn’t come up very often and I can advise they use XPaths and append the instance number to it.
On the other hand, I had never considered the ability to parameterize test objects in the way you described, and this is awesome, so thanks!! This will come in most handy when I need to traverse web tables and the like.

Do you still want to stick to what you call “attributes” (excluding xpath)? Do you still want to avoid XPath?

Then I believe that you would not find a favourable solution. It is up to you if you continue looking for or abandon.

Thanks Kazurayam, I think you’re right, this isn’t something that is currently built into KSE. I appreciate your help and advice, as always!