Simple way to find and interact with elements

Hi, I am fairly new to Katalon/Selenium, having worked mostly with Cypress in the past. In cypress finding elements is pretty straight forward and I am trying to use Katalon in a similar way but I often find that an element cannot be found.

For this element for instance (an email verification button after a new user has been created), the xpath constantly changes due to a random user ID being added to the href:

href="http://localhost:3500/email-verification/a63a2b24-b785-4b18-b104-83283670b920?email=test%40aurem.ae"

In cypress I could easily click the button with following code:

cy.findAllByRole("link", { name: /Verify email/i })
        .eq(0)
        .should("be.visible");

cy.findAllByRole("link", { name: /Verify email/i }).click();

How can I achieve something similar with Katalon?

1 Like

Hi there,

Thank you very much for your topic. Please note that it may take a little while before a member of our community or from Katalon team responds to you.

Thanks!

I don’t understand your Cypress bit of “{name: ‘Verify email/i’ }” but otherwise, I might do something like:

import org.openqa.selenium.WebDriver as WebDriver
import org.openqa.selenium.WebElement as WebElement
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

WebDriver driver = DriverFactory.getWebDriver();

WebElement element = driver.findElement(By.xpath("//button[contains(@href,'/email-verification/') and contains(@href, 'email=test')]"));
assertTrue (element.isDisplayed())
WebUI.verifyMatch(element.isDisplayed().toString(), "true", false)
element.click()

Edit: if there is a <name> attribute somewhere in your HTML that you did not show, then you might be able to use that to find a unique pathway to your element.

Basically with Cypress (and a plugin called test library) I can easily fetch elements by their role and name, so things like:

    cy.findByRole("button", { name: /Sign Up/i }).click();
    cy.findByRole("heading", { name: /Create an account/i }).should(
      "have.text",
      "Create an account",
    );

and when a unique ID is present just like:

    cy.get('[data-e2e-id="signUp__input__email"]').clear().type(adminEmail);
    cy.get('[data-e2e-id="signUp__input__password"]')
      .clear()
      .type(adminPassword);
    cy.get('[data-e2e-id="signUp__button__submit"]').click();

I think searching by xpath using contains I should be able to fetch unique elements.

I’m just wondering, do i always have to call WebElement element = driver.findElement? I suppose this is only needed if you do not use the Object Repository.

1 Like

If you use the Object Repository, then you will be dealing with Test Objects and you can just drag-and-drop from the OR into your Test Case, such as below.
WebUI.click(findTestObject('myPage/button_EmailVerification'))

In my post above, as you surmised, I created a WebElement.

Edit: you can also make a Test Object without using the Object Repository by either using the below Keyword or its contents inline of your code:

import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.testobject.ConditionType

	/**
	 * Utility to create an instance of TestObject with XPath
	 * @param xpath
	 * @return TestObject
	 */
	public static TestObject makeTO(String xpath) {
		TestObject to = new TestObject(xpath)
		to.addProperty("xpath", ConditionType.EQUALS, xpath)

		return to
	}

you can rename the method to whatever you want, but the idea is to use the contents of the method or as a Keyword to create a Test Object. So, if you want to use the Keyword and perform your task, it could look like:

myItem = com.Tools.makeTO("//button[contains(@href,'/email-verification/') and contains(@href, 'email=test')]")
WebUI.verifyElementVisible(myItem)
WebUI.click(myItem)
1 Like

Hi @ronald1, :wave:

Just checking in to see if you were able to find the solution in this thread or not based on Grylion54’s comments.

If yes, then don’t forget to mark helpful replies as a solution :white_check_mark: so that others who may be asking similar questions / running into similar problems can find the solution as well!

Thanks for making for forum better,
Albert