Skip to main content

Check web element state with isElement and assertElement keywords

Last updated: October 2026
Scope

The keywords and behavior on this page apply to Katalon Studio 11.2.0 and later, for WebUI tests only.

Katalon Studio 11.2.0 adds two families of WebUI keywords for checking the state of a web element:

  • isElement* keywords return true or false. Use them to decide what your test does next.
  • assertElement* keywords fail the step when the element is not in the expected state. Use them for checkpoints.

Each keyword does one job, so your test scripts say exactly what you mean: "tell me" or "make sure."

Choose the right keyword​

Start with one question: if the element is not in the expected state, has the test failed?

If the answer is...UseReturnsWhen the condition is not met
Yes, the test has failedassertElement*No value to useThe step fails, based on the failure handling you set
No, the test just takes a different pathisElement*true or falseReturns false. The step still passes

You can keep using the verify* and waitFor* keywords in existing tests. They are still supported. For new tests, we recommend isElement* and assertElement* because they behave the same way every time, whatever failure handling you set.

note

isElement* and assertElement* keywords do not use self-healing, classic or AI. If a step needs self-healing to recover from a broken locator, keep using the verify* or waitFor* keyword for that step. See Self-healing.

See Move from verify and waitFor keywords.

Available keywords​

State checkedisElement*assertElement*
Present: the element exists in the DOMisElementPresent
isElementNotPresent
assertElementPresent
assertElementNotPresent
Visible: the element is present and displayedisElementVisible
isElementNotVisible
assertElementVisible
assertElementNotVisible
Clickable: the element is enabled, visible, stable, and not covered by another elementisElementClickable
isElementNotClickable
assertElementClickable
assertElementNotClickable
Checked: a checkbox or radio button is selectedisElementChecked
isElementNotChecked
assertElementChecked
assertElementNotChecked
Has attribute: the attribute exists and its value is not nullisElementHasAttribute
isElementNotHasAttribute
assertElementHasAttribute
assertElementNotHasAttribute
Attribute value: the attribute value matches exactly (case-sensitive)isElementAttributeValueassertElementAttributeValue
Text: the element text matches exactlyisElementTextassertElementText
In viewport: the element is visible in the part of the page shown on screenisElementInViewport
isElementNotInViewport
Not available. See Assert that an element is in the viewport.

How these keywords work​

Parameters​

Every keyword takes the same core parameters:

ParameterTypeRequiredDescription
toTestObjectYesThe web element to check.
timeOutintYesThe maximum time to wait, in seconds. A negative value uses the default WebUI element timeout in Project > Settings > Execution > WebUI.
flowControlFailureHandlingNoWhat happens on failure: STOP_ON_FAILURE, CONTINUE_ON_FAILURE, or OPTIONAL. Uses the project default if you leave it out.

Some keywords need an expected value as well:

  • *HasAttribute and *NotHasAttribute take attributeName.
  • *AttributeValue takes attributeName and attributeValue.
  • *Text takes expectedText.

Waiting and timeouts​

The keywords check the condition repeatedly until it is met or the timeout runs out:

  • If the condition is met, the keyword returns right away.
  • If the condition is never met, the keyword waits for the full timeout, then returns false (isElement*) or fails the step (assertElement*).

This means an isElement* keyword that returns false always takes the full timeout. Keep timeouts short when a false result is common. See Keep isElement timeouts short.

Negative states need the element to exist​

Not* keywords, such as assertElementNotVisible or isElementNotClickable, first find the element, then check that it is not in the given state. A missing element does not count as "not visible" or "not clickable." In that case:

  • isElementNot* returns false.
  • assertElementNot* fails.

To check that an element is gone from the page, use isElementNotPresent or assertElementNotPresent.

Failure handling​

  • assertElement*: failure handling decides what happens when the condition is not met. STOP_ON_FAILURE stops the test, CONTINUE_ON_FAILURE marks the step as failed and continues, and OPTIONAL logs a warning and continues.
  • isElement*: a condition that is not met returns false and the step passes. Failure handling applies only to unexpected errors, such as an invalid locator or a closed browser. If the test continues after such an error, the keyword returns false.

Self-healing​

isElement* and assertElement* keywords do not use self-healing, classic or AI. If the locator of a test object is broken, the keyword does not try other locators:

  • isElement* returns false.
  • assertElement* fails the step.

This is by design. A state check that silently heals to a different element can pass when it should fail, so these keywords report exactly what the locator finds.

verify* and waitFor* keywords work differently. They are excluded from classic self-healing by default, but you can remove them from the exclusion list in Project Settings > Self-Healing. If your tests rely on self-healing for these checks, keep using verify* and waitFor* for those steps.

An upcoming release will update the verify* and waitFor* keywords so that they behave more consistently, while keeping self-healing support. This update may change how some existing tests behave. We will share details in the release notes.

Text matching​

isElementText and assertElementText compare the element text exactly. For Flutter web elements (tag names that start with flt-), an exact match on the aria-label attribute also counts.

Example use cases​

Add a checkpoint​

Fail the test if the order confirmation does not appear, or the total is wrong:

WebUI.click(findTestObject('Checkout/btn_PlaceOrder'))

WebUI.assertElementVisible(findTestObject('Checkout/lbl_OrderConfirmed'), 10)
WebUI.assertElementText(findTestObject('Checkout/lbl_Total'), '$42.00', 10)

Handle an optional element​

Close a cookie banner only if it shows up:

if (WebUI.isElementVisible(findTestObject('Home/btn_AcceptCookies'), 3)) {
WebUI.click(findTestObject('Home/btn_AcceptCookies'))
}

Wait for a loading indicator to go away​

Pick the keyword based on how your app hides the indicator:

// The spinner is removed from the page
WebUI.assertElementNotPresent(findTestObject('Common/spinner'), 30)

// The spinner stays in the page but is hidden (for example, display: none)
WebUI.assertElementNotVisible(findTestObject('Common/spinner'), 30)

If you are not sure which one applies, use assertElementNotPresent. assertElementNotVisible fails when the element no longer exists.

Check that a button stays disabled​

Confirm that Submit cannot be clicked until the form is valid:

WebUI.assertElementNotClickable(findTestObject('Signup/btn_Submit'), 5)

WebUI.setText(findTestObject('Signup/txt_Email'), 'tester@example.com')
WebUI.setText(findTestObject('Signup/txt_Password'), 'Str0ngPass!')

WebUI.assertElementClickable(findTestObject('Signup/btn_Submit'), 5)

Check an attribute​

// The tab is marked as active
WebUI.assertElementAttributeValue(findTestObject('Nav/tab_Reports'), 'aria-selected', 'true', 5)

// The field is no longer read-only
WebUI.assertElementNotHasAttribute(findTestObject('Profile/txt_Name'), 'readonly', 5)

Check a checkbox​

WebUI.click(findTestObject('Signup/chk_AcceptTerms'))
WebUI.assertElementChecked(findTestObject('Signup/chk_AcceptTerms'), 5)

Report a failure and keep going​

Use CONTINUE_ON_FAILURE to check several things in one run:

WebUI.assertElementVisible(findTestObject('Dashboard/widget_Revenue'), 10, FailureHandling.CONTINUE_ON_FAILURE)
WebUI.assertElementVisible(findTestObject('Dashboard/widget_Users'), 10, FailureHandling.CONTINUE_ON_FAILURE)

Assert that an element is in the viewport​

There is no assertElementInViewport keyword. Use isElementInViewport with a Groovy assert:

WebUI.scrollToElement(findTestObject('Footer/lnk_Contact'), 5)
assert WebUI.isElementInViewport(findTestObject('Footer/lnk_Contact'), 5)

Best practices​

Use assertElement for checkpoints, not verify plus custom logic​

You no longer need to wrap a verify* keyword in an if statement and call KeywordUtil.markFailed(). An assertElement* keyword fails the step for you and logs a clear message.

Use isElement for branching, not verify with OPTIONAL​

verifyElementVisible(to, 5, FailureHandling.OPTIONAL) returns a boolean but also logs a warning when the result is false. isElementVisible(to, 5) returns the same boolean, and the report still shows a passed step. That keeps reports clean when a false result is expected.

Keep isElement timeouts short​

A false result always takes the full timeout. For optional elements, such as pop-ups, banners, or A/B test variants, 2 to 5 seconds is usually enough. Long timeouts on isElement* checks are a common cause of slow test runs.

Use the Not keyword to wait for a change​

Negating a positive check does not wait for the element to change:

// Returns false right away while the dialog is still open. Does not wait.
!WebUI.isElementVisible(findTestObject('Dialog/modal'), 10)

// Waits up to 10 seconds for the dialog to disappear.
WebUI.isElementNotPresent(findTestObject('Dialog/modal'), 10)

Check the state you actually need​

The states build on each other: Present < Visible < Clickable. Check the lowest state that proves your point:

  • Use Present to confirm an element exists in the DOM, such as a hidden input.
  • Use Visible to confirm the user can see it.
  • Use Clickable to confirm the user can interact with it right now.
  • Use In viewport for scroll-dependent UI, such as sticky headers or lazy-loaded content.

A stronger check than you need adds wait time and can make a test flaky.

Do not add a check before every action​

Action keywords such as click and setText already wait for the element to be ready when Use Enhanced Waiting & Checking is turned on in Project > Settings > Execution > WebUI. Add a clickable check only when the state itself is what you want to test. See Wait and Enhanced Waiting & Checking keyword logic.

Match text exactly, or use verifyMatch for patterns​

isElementText and assertElementText need an exact match. For a partial or regular expression match, get the text first:

String status = WebUI.getText(findTestObject('Order/lbl_Status'))
WebUI.verifyMatch(status, 'Shipped.*', true)

Record assertions with Web Recorder Plus​

You can add assertElement* steps while recording with Web Recorder Plus:

  1. Start Web Recorder Plus and open your application.

  2. Right-click the element you want to check, then select Katalon Recorder Plus.

  3. Select Assert Element State, then choose a state: Present, Not Present, Visible, Not Visible, Clickable, or Not Clickable.

    To check the text of the element, select Assert Element Text instead.

Web Recorder Plus context menu with Assert Element State options

Katalon Studio adds the matching assertElement* step to your test case, for example assertElementVisible or assertElementText.

The recorder menu covers the states above. To check other states, such as checked or attribute values, edit the recorded step or add the keyword in the script.

Move from verify and waitFor keywords​

The verify* and waitFor* keywords are still supported. There is no need to rewrite working tests. Use the new keywords in new tests, and switch to them when you edit existing ones.

Before you switch a step, check whether it relies on self-healing. The new keywords do not use self-healing, so a step that passes today only because a broken locator was healed fails after you switch. Fix the locator first, or keep the verify* or waitFor* keyword for that step. See Self-healing.

If your script does this...Use this instead
verifyElementPresent(to, t) as a checkpointassertElementPresent(to, t)
verifyElementVisible(to, t, FailureHandling.OPTIONAL) inside an ifisElementVisible(to, t)
verifyElementClickable(to, t, FailureHandling.OPTIONAL) inside an ifisElementClickable(to, t)
if (!WebUI.verifyElementPresent(...)) { KeywordUtil.markFailed(...) }assertElementPresent(to, t)
waitForElementNotPresent(to, t) to wait for something to disappearassertElementNotPresent(to, t)
waitForElementNotVisible(to, t) for an element that is hidden, not removedassertElementNotVisible(to, t)
waitForElementVisible(to, t) right before clickOften not needed, because click already waits
verifyElementText(to, expected)assertElementText(to, expected, t)
note

The isElement* and assertElement* keywords take a timeout. verifyElementText does not. When you switch, choose a timeout that matches how long the text normally takes to update.

Known issues​

  • Smart Locator and image locator (Katalon Studio 11.2.0 to 11.5.0): when a test object uses Smart Locator or image locator as its default locator, assertElementPresent can fail on an element that verifyElementPresent finds, for example an element under an overlay. This is fixed in Katalon Studio 11.6.0. We recommend upgrading to 11.6.0 or later. If you can't upgrade yet, set a different default locator, such as XPath or CSS, for that test object.

Troubleshooting​

assertElementNotVisible fails even though the element is gone. The element was removed from the page, so there is nothing to evaluate. Use assertElementNotPresent instead. See Negative states need the element to exist.

My test got slower after switching to isElement*. Check the timeouts on isElement* checks that often return false. Each false result waits for the full timeout.

assertElementText fails, but the text looks right. The match is exact, including spaces and letter case. Check for leading or trailing spaces, line breaks, or hidden characters. For flexible matching, use getText with verifyMatch.

assertElementNotClickable passes on an element covered by an overlay. That is expected. An element covered by another element is not clickable, because it is not on top.

A step passed with verify* or waitFor*, but fails after switching to assertElement*. The old keyword probably found the element through self-healing. The new keywords do not use self-healing. Check the self-healing log for that test object and update its locator, or keep the old keyword for that step. See Self-healing.

An isElement* keyword fails the step instead of returning false. The keyword hit an unexpected error, such as an invalid locator or a closed browser, not an unmet condition. Check the test object locator. To keep the test running, pass FailureHandling.OPTIONAL or FailureHandling.CONTINUE_ON_FAILURE; the keyword then returns false.

Was this page helpful?