Check web element state with isElement and assertElement keywords
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 returntrueorfalse. 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... | Use | Returns | When the condition is not met |
|---|---|---|---|
| Yes, the test has failed | assertElement* | No value to use | The step fails, based on the failure handling you set |
| No, the test just takes a different path | isElement* | true or false | Returns 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.
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​
How these keywords work​
Parameters​
Every keyword takes the same core parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
to | TestObject | Yes | The web element to check. |
timeOut | int | Yes | The maximum time to wait, in seconds. A negative value uses the default WebUI element timeout in Project > Settings > Execution > WebUI. |
flowControl | FailureHandling | No | What 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:
*HasAttributeand*NotHasAttributetakeattributeName.*AttributeValuetakesattributeNameandattributeValue.*TexttakesexpectedText.
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*returnsfalse.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_FAILUREstops the test,CONTINUE_ON_FAILUREmarks the step as failed and continues, andOPTIONALlogs a warning and continues.isElement*: a condition that is not met returnsfalseand 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 returnsfalse.
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*returnsfalse.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:
-
Start Web Recorder Plus and open your application.
-
Right-click the element you want to check, then select Katalon Recorder Plus.
-
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.
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 checkpoint | assertElementPresent(to, t) |
verifyElementVisible(to, t, FailureHandling.OPTIONAL) inside an if | isElementVisible(to, t) |
verifyElementClickable(to, t, FailureHandling.OPTIONAL) inside an if | isElementClickable(to, t) |
if (!WebUI.verifyElementPresent(...)) { KeywordUtil.markFailed(...) } | assertElementPresent(to, t) |
waitForElementNotPresent(to, t) to wait for something to disappear | assertElementNotPresent(to, t) |
waitForElementNotVisible(to, t) for an element that is hidden, not removed | assertElementNotVisible(to, t) |
waitForElementVisible(to, t) right before click | Often not needed, because click already waits |
verifyElementText(to, expected) | assertElementText(to, expected, t) |
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,
assertElementPresentcan fail on an element thatverifyElementPresentfinds, 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.