Test Object with xpath selector using matches() function never works

OS

Windows 7

Katalon Studio Version

5.4.2

## Katalon Studio logs:

attached, but not relevant I think

## Environment (for Web testing)

Firefox 60.0.2

## Steps to reproduce -

I made a testbed html at Discussion #7609

The page contains following markup:

    <table id="data" class="table">
        <tbody>
            <tr><td>ИВАН</td><td> ИВАНОВ ИВАН 123 </td></tr>
            <tr><td>IVAN</td><td> IVANOV IVAN 123 </td></tr>
        </tbody>
    </table>

I made 2 Test Object:

(1) ‘Page_Discussion 7609/td_Latin_alphabet - text equals’

This Test Object is assigned with Basic method, which includes a factor of text/equals/IVAN. Screenshot is attached below:

(2) Page_Discussion 7609/td_Latin_alphabet - text matches

This Test Object is assigned with Basic Method, which includes a factor of text/matches regex/IVAN. Screenshot is attached below:

I made a test case named “TC1”. The code is as follows:

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
WebUI.openBrowser('')
WebUI.setViewPortSize(703, 347)
WebUI.navigateToUrl('http://demoaut-mimic.kazurayam.com/7609_testbed.html')
WebUI.verifyElementPresent(findTestObject(    'Page_Discussion 7609/td_Latin_alphabet - text equals'),
    20, FailureHandling.CONTINUE_ON_FAILURE)
WebUI.verifyElementPresent(findTestObject(    'Page_Discussion 7609/td_Latin_alphabet - text matches'),
    3, FailureHandling.CONTINUE_ON_FAILURE)
WebUI.closeBrowser()

## Expected Behavior -

I expected that both Test Objects success to match the HTML element

        <td>IVAN</td>

## Actual Behavior -

when I ran the test case I got the following output in the log

...
[INFO]   - Finding web element with id: 'Object Repository/Page_Discussion 7609/td_Latin_alphabet - text equals' located by 'By.xpath: //td[(text() = 'IVAN' or . = 'IVAN')]' in '20' second(s)
[INFO]   - Found 1 web elements with id: 'Object Repository/Page_Discussion 7609/td_Latin_alphabet - text equals' located by 'By.xpath: //td[(text() = 'IVAN' or . = 'IVAN')]' in '20' second(s)
[PASSED] - Object 'Object Repository/Page_Discussion 7609/td_Latin_alphabet - text equals' is present
...
[INFO]   - Finding web element with id: 'Object Repository/Page_Discussion 7609/td_Latin_alphabet - text matches' located by 'By.xpath: //td[(matches(text(), 'IVAN') or matches(., 'IVAN'))]' in '3' second(s)
[FAILED] - com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: 'Object Repository/Page_Discussion 7609/td_Latin_alphabet - text matches' located by 'By.xpath: //td[(matches(text(), 'IVAN') or matches(., 'IVAN'))]' not found
...

In other words, the following org.openqa.selenium.By.xpath(String) call succeeded:

By.xpath: //td[(text() = 'IVAN' or . = 'IVAN')]

but the following By.xpath() call failed

By.xpath: //td[(matches(text(), 'IVAN') or matches(., 'IVAN'))]

I have made a demo in the GitHub:

# Cause of failure

I think By.xpath() call with expression containing matches() function would NEVER work.

The matches() function was defined in XPath 2.0.

https://www.w3.org/TR/xquery-operators/#func-matches

Most of the existing xpath engines in the world supports XPath1.0 but not XPath2.0

As the following post tells, the Selenium WebDriver’s By.xpath implements XPath1.0, but lacks XPath2.0 support including matches() function.

How are XPath1.0 and XPath2.0 different? — see jaxen - FAQ / Which version of XPath does jaxen support? Does jaxen support XPath 2? section.

I suppose all of Test Objects in Katalon Studio with Condition “matches regex” will not work properly.

# My proposal

Katalon team should consider removing the Condition “matches regex” completely.

.log

text-equals.png

text-matches.png

3 Likes

If Katalon Team can tell me how to make “matches regex” work properly, I would like to see it as I could not find any documentation about “matches regex”.

2 Likes

OS:win10
Katalon Studio:5.6.0
**matches regex **doesn’t work either.

It seems also that the condition “ends with” doens’t work either, so Katalon team should consider removing the Condition “ends with” completely also.

Also, “equals” and “starts with” seem to have some troubles : they often react the same way…

Ah, yes, “ends with” was added in XPath 2.0 as well.

1 Like

Any update on this issue please

Updates? Do you expect matches() to work in future? Do don’t think it will happen.

1 Like

Don’t know why this bug is not fixed. But anyway, matches() seems like a very common use case.

OK, let’s wait for @Katalon team to respond to us.

1 Like

Any update on this @Katalon_team ? This is indeed a very common use case, especially when I have to test 3rd-party integrations, and have no control over the code. Regex is a needed fallback.

I think Katalon Studio would never be able to support XPath matches() function. I explained the reason above.

1 Like

You can live without the matches() function in XPath2.0. It is possible to implement “grep” with string pattern over a text content of a HTML element with XPath1.0 expression. The following comment shows how to:

1 Like

Hi @kazurayam,

I understand your point on removing options in Katalon… But I am a bit disapointed as Xpath is a powerful way to handle HTML documents and, to speed-up test creation and execution.
Hence, I would rather pledge for an update to Xpath2.0 and a little clean up of the attributes detection interface. There is really interesting functions in the v.2.0.

WebUI.verifyElementPresent(findTestObject(    'Page_Discussion 7609/td_Latin_alphabet - text matches'),
    3, FailureHandling.CONTINUE_ON_FAILURE)

where the Test Object has a XPath defined as

//td(matches(text(), 'IVAN'))

When I run the test case, Katalon Studio calls org.openqa.selenium.WebDriver.findElement(By.ByXpath). The string //td(matches(text(),'IVAN')) is transferred from Katalon Studio to browser (for example, Chrome). Chrome browser interprets the string //td(matches(text(),'IVAN')) as XPath, and evaluate it against the DOM of a Web page.

The thing is, it is browsers (Chrome, Firefox, etc) who evaluates the string //td(matches(text(),'IVAN')) as an XPath expression. Katalon Studio does not know if the string is an expression conformant to XPath1.0 or XPath2.0. All Katalon Studio does is saving the string and transferring it to browsers. It depends on Browser’s capability if it supports XPath 2.0 or not. According to https://stackoverflow.com/questions/25455351/does-chrome-use-xpath-2-0 , Chrome uses libxml which supports XPath 1.0 but not XPath 2.0.

If you want to use XPath 2.0 expression in Katalon Studio, then you need to convince the Browser vendors (Google, Mozzila, Microsoft, Apple) to hear your wishes. I believe that Katalon Team has very little they can do for changing Chrome and Firefox.

And I guess, Browser vendors will not be interested in XPath2.0 support; they are serious about CSS and JavaScrit, but not about XPath features any longer.

1 Like

In KSE 7.2.1, the “matches regex”, “not matches regex”, and “ends with” conditions provided for selecting objects by attributes do not work. If this is dependent on browser support, and none of the browsers Katalon uses support XPath 2.0, why are the options still present in Katalon?

1 Like

@ThanhTo

I would propose this to Katalon Team again.

Yes I agree that it is misleading that these do not work. Either they should be removed or fixed. I am running into this issue with mobile… with this is a selector: //*[ends-with(@resource-id, ‘child_start_button’)]
@ThanhTo @duyluong

This has to be a bug, when i select this for regex selection by resource-id for mobile android, i see the following in the logs:

e[35m[HTTP]e[39m e[90m{“using”:“-android uiautomator”,“value”:“new UiSelector().resourceId("child_start_button")”}e[39m
Katalon should be calling resourceIdMatches: UiSelector  |  Android Developers

I need this to work too, I need to match the current month / year and many other cases on a text of a testObject, and regex seems to be the closest to what I need that would not involve a lot of workarounds… Ideally I would like to match the current month or year on a text of testObject(s) but that involves coding and reorganizing a lot of repository objects and consequent adjustments. We need the simplest solution for our needs.