How to combine two xpath/css into single xpath/css

I have two xpath/css as below, how to combine these two into single xpath/css and verify it.

String state1 = (//span[@id='completed'])[1]         // css  span[id='completed']:nth-of-type(1)
String state2 = (//span[@id='completed'])[2]         // css  span[id='completed']:nth-of-type(2)

'Verify that Status is "Completed" '
WebUI.verifyElementVisible(findTestObject(state1 +"and"+ state2), FailureHandling.STOP_ON_FAILURE)  // NOT WORKING

What do you mean by “combine”? I don’t understand the word.

Please describe what you want to achieve in a more natural sentence.

I have two Xpath expressions …

(//span[@id='completed'])[1]
(//span[@id='completed'])[2]

How do I write a single xpath expression that combines the two above and would return the same node-set as combining the results of running each of the expressions above individually.

For xpath | is used for union of two node sets.

(//span[@id='completed'])[1] | (//span[@id='completed'])[2]

For css , is used.

span[id='completed']:nth-of-type(1),span[id='completed']:nth-of-type(2)

One the other hand, I am looking for && condition.
If both the xpath/css is available return true.

No. This approach will not work.


You want to get a boolean value that describes if both 2 web elements are visible in a web page.

To get the result, you should start with checking the presense of each 2 web elements individually using 2 XPath expression you have. You would get 2 boolean values. Then, you can do a boolean AND operation of these 2 values.

Then here is my take.

import java.nio.file.Path
import java.nio.file.Paths

import com.kms.katalon.core.configuration.RunConfiguration
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

TestObject makeTestObjectByXPath(String xpath) {
	TestObject tObj = new TestObject()
	tObj.addProperty("xpath", ConditionType.EQUALS, xpath)
}

Path projectDir = Paths.get(RunConfiguration.getProjectDir())
Path pageHtml = projectDir.resolve("page.html")

WebUI.openBrowser(pageHtml.toFile().toURI().toURL().toExternalForm())

boolean b = (WebUI.verifyElementPresent(makeTestObjectByXPath("(//span[@id='complete'])[1]"), 5, FailureHandling.OPTIONAL) 
             &&
	         WebUI.verifyElementPresent(makeTestObjectByXPath("(//span[@id='complete'])[2]"), 5, FailureHandling.OPTIONAL)
			 )

println "b=" + b
						 			 
WebUI.delay(3)
WebUI.closeBrowser()

This code successfully compiled on my machine, printed the result false. It took over 5 seconds before obtaining the boolean value.

1 Like

@marzookrehana There’s a problem with your code or your page or your understanding of what is going on.

These xpaths describe illegal HTML:

These css selectors describe illegal HTML:

It is NOT legal to have TWO elements in ONE HTML document with the same value stored in their id attributes.

Let me say that in a much more profound way – the page is broken.

Because the page is broken, any test results you produce are meaningless.

Just let me inform you of my experiment.

I made “page.html”:

<html>
<head>
  <title></title>
</head>
<body>
  <p>
    <span id="complete">you are #1</span>
    <span id="complete">i am #2</span>
  </p>
</body>
</html>

As @Russ_Thomas pointed out, this HTML is syntactically “invalid”; as it contains 2 <span id="complete"> elements with same id value. But we all know, there could be such nasty HTMLs all over the world. Programs that consume HTMLs should be able to process them gently and silently.

My revised test case is:

import java.nio.file.Path
import java.nio.file.Paths
import com.kms.katalon.core.configuration.RunConfiguration
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

TestObject makeTestObjectByXPath(String xpath) {
	TestObject tObj = new TestObject(xpath)
	tObj.addProperty("xpath", ConditionType.EQUALS, xpath)
}

Path projectDir = Paths.get(RunConfiguration.getProjectDir())
Path pageHtml = projectDir.resolve("page.html")
WebUI.openBrowser(pageHtml.toFile().toURI().toURL().toExternalForm())
WebUI.setViewPortSize(800, 600)

boolean a = WebUI.verifyElementPresent(makeTestObjectByXPath("(//span[@id='complete'])[1] | (//span[@id='complete'])[2]"), 5, FailureHandling.OPTIONAL)
println "a=" + a

boolean b = (WebUI.verifyElementPresent(makeTestObjectByXPath("(//span[@id='complete'])[1]"), 5, FailureHandling.OPTIONAL) &&
	         WebUI.verifyElementPresent(makeTestObjectByXPath("(//span[@id='complete'])[2]"), 5, FailureHandling.OPTIONAL)
			 )
println "b=" + b

WebUI.closeBrowser()

When I ran this test case, I saw:

2022-11-22 08:56:48.941 INFO  c.k.k.core.webui.driver.DriverFactory    - sessionId = 3cc754b3986d5075dadd7de1ab352b2d
2022-11-22 08:56:48.967 INFO  c.k.k.core.webui.driver.DriverFactory    - browser = Chrome 107.0.5304.110
2022-11-22 08:56:48.968 INFO  c.k.k.core.webui.driver.DriverFactory    - platform = Mac OS X
2022-11-22 08:56:48.969 INFO  c.k.k.core.webui.driver.DriverFactory    - seleniumVersion = 3.141.59
2022-11-22 08:56:48.972 INFO  c.k.k.core.webui.driver.DriverFactory    - proxyInformation = ProxyInformation { proxyOption=NO_PROXY, proxyServerType=HTTP, username=, password=********, proxyServerAddress=, proxyServerPort=0, executionList="", isApplyToDesiredCapabilities=true }
a=true
b=true
2022-11-22 08:56:52.779 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/marzookrehana

I could confirm that @marzookrehana wrote right. XPath union operator | just works.