How do I select a (ranged) slider but the endpoints have the same name

I don’t know how to solve this problem.

I have a slider that looks like this (I removed the related counter values because it is not interesting):
double_ended_slider_control

Inspect has the following (I changed the actual name to something generic):

When I use spyweb to grab one of the endpoints, the end result is “ui-slider-handle ui-state-default ui-corner-all”, and of course, when I use WebUI.dragAndDropByOffset on the UI element object returned by spyweb, it doesn’t work properly. (No fault of spyweb, btw).

ChatGpt suggested to grab the top level object, and then to use WebUI.findWebElements as shown in the following snippet:

List<WebElement> sliderHandles = WebUI.findWebElements(findTestObject('pathto/dynamic_slider_1'), 10)
WebElement leftEnd = sliderHandles[0]
WebElement rightEnd = sliderHandles[1]

// Move left end to a specific position
WebUI.executeJavaScript("arguments[0].style.left = '50%'", Arrays.asList(leftEnd))

The above doesn’t work because it moves the slider itself and not the endpoint.

My question is: given a TestObject (of id=“DYNAMIC_slider_1”), is there a way to access the sub-objects contained in it, whereby the object returned is an array of TestObjects, and I can then use the WebUI.dragAndDropByOffset to slide the given endpoint.

Thanks in advance.

1 Like

How are we supposed to help you, if you don’t provide us with the DOM for those slider endpoints ?!
[How To] Use The Browser Developer Tools (F12 DevTools)

Just reading that tells me you know what you’re doing and you know what needs to happen.

Whether or not it’s possible is down to you to find out. Trying to figure that out here on the forum is almost impossible. As long as you’re not dealing with a custom object constructed using shadow dom, you should be able to figure it out better than us, here.

Word of advice: spyweb == "toy" – use devtools.

When you finally do get it working, please post back with the solution. Thanks.

1 Like

My apologies for not including this in my original message. I thought I had done so.

This is part of the DOM:

The remainder of the DOM is not required / not interesting.

Thanks,
Robert

Thank you for your vote of confidence in my ability. Because of your comment, I found the solution.

Abstract:

  1. Katalon does a decent job in wrapping Selenium objects (into TestObject).
  2. However, and this is no fault of Katalon, there are some things that you have to drop down into Selenium. This is one of those cases.

Problem Statement:

  1. The findTestObject relies upon / assumes (and you know what Ass-U-Me means) that every Web UI element is uniquely identified. Unfortunately, we QA Testers do not author the web page code. The ultimate solution is to beat-on-the-heads-of-Web_developers / insist that every single Web UI element has a unique name (I have no idea why this is so difficult, TBH). Short of that, we have to deal with this reality.
  2. The key problem is this:
  • the given slider (DYNAMIC_slider_1) is uniquely identified. This is not the problem.
  • contained within the given slider, there is a bunch of WebElements (this is an actual Selenium object definition). And this is where the problem lies. These WebElements are not uniquely identifiable within the slider (DYNAMIC_slider_1), and most likely it is not unique within the DOM either (bad bad bad).

Solution Statement:

  1. Selenium relies on the xpath syntax, which is highly descriptive / versatile.

Solution Details (this is not for the faint of heart, and it is long):

Step 1: grab the WebDriver, and find the WebElements associated with the slider:
WebDriver driver = DriverFactory.getWebDriver()

// Find all handle elements
List handleElements = driver.findElements(By.cssSelector(“#DYNAMIC_slider_1 .ui-slider-handle”))

NOTE: I tried using the findWebElements as described in [WebUI] Find Web Elements | Katalon Docs but that did not work because it only returned a List of one element. (IMHO, this API should be updated such that we can give to it something like the By.cssSelector syntax etc.)

Basically what the above code does is to return into a list all those WebElement(s) that matches those objects that id=DYNAMIC_slider_1, and those children contained that has the name .ui-slider-handle.

Step 2: grab the actual WebElement and then we can use Selenium APIs to manipulate / move those endpoints.

WebElement leftHandle = handleElements[0]
WebElement rightHandle = handleElements[1]

Actions actions = new Actions(driver)

actions.dragAndDropBy(leftHandle, 35, 0).build().perform()
actions.dragAndDropBy(rightHandle, 65, 0).build().perform()

NOTES:

  1. you have to include several imports
    import org.openqa.selenium.By
    import org.openqa.selenium.WebDriver
    import org.openqa.selenium.WebElement
    import com.kms.katalon.core.webui.driver.DriverFactory
    import org.openqa.selenium.interactions.Actions
    import org.openqa.selenium.WebElement
  2. I didn’t show how to do the calculation for offset (the second parameter) of dragAndDropBy. I will leave that exercise to the reader.

Enjoy!

2 Likes

Bravo.

Great. It was meant to empower you. Glad you found a solution as a result.

Pointer: the dom API equivalent is notionalRootElement.querySelectorAll("css selector")

If you wanted to, you could drop that into a blob of JS and dispense with all that Selenium WebElement marshaling. Just for your edification :wink:

2 Likes