waitFor* should behave like other methods in flow


#1

I am quite new to Katalon, but there are some issues that strikes me as odd, this one is especially one that I really struggles with.

There are some waitFor* methods that takes a timeout which I thought waits for the element to be clickable within the defined time period or otherwise should fail.

But these doesn’t fail, they just give a warning and the code continues to be executed (and fails other places).

I think that the waitFor* methods should work in the same way as other methods, when failing throw an error unless the flowControl handling states otherwise. This will make the Katalon project more consistent in its work.

This wouldn’t be that big of a problem IF the verify* counterparts had a timeout parameter (see a another discussion), but they doesn’t and this becomes a problem.

–Rune


#2

Have a look at documents

The method accepts FailureHandling object as 3rd argument:

import com.kms.katalon.core.model.FailureHandling
flowControlWebUI.waitForElementClickable(    findTestObject('Page_CuraHomepage/btn_MakeAppointment'),    20,    FailureHandling.STOP_ON_FAILURE)

You can choose either of FailureHandling.STOP_ON_FAILURE, FailureHandling.CONTINUE_ON_FAILURE and FailureHandling.OPTIONAL.

By specifying STOP_ON_FAILURE you can stop the test case on failure.


#3

You should use verify commands instead of waitFor if you want it to assert that statement. A lot of the verify commands also allow you to define a timeout. We use waitFor a lot in our if statements.


#4

The problem is that the waitFor* ignores that, even if you set’s the failureHandlig to STOP_ON_FAILURE.


#5

Yes, the Verify* commands should be the one used, but as mentioned several of these are missing the timeout value (which I reported in a seperate post).

Of course, using if statement with wait* functions could solve it but makes the tests rather clumsy, it would either be nice to have the wait functions actually wait and fail, or that all verify functions has a timeout.


#6

We can read the source code of com.kms.katalon.core.webui.keyword.builtin.WaitForElementClickableKeyword at the following URL:

Current line 80-95 is like this:

try {
    ....
    WebElement foundElement = WebUIAbstractKeyword.findWebElement(to, timeOut)
    WebDriverWait wait = new WebDriverWait(DriverFactory.getWebDriver(), timeOut)
    foundElement = wait.until(new ExpectedCondition<WebElement>() {
        @Override
        public WebElement apply(WebDriver driver) {
            if (foundElement.isEnabled()) {
                return foundElement
            } else {
                return null
            }
        }
    })
    if (foundElement != null) {                     
        logger.logPassed(MessageFormat.format(StringConstants.KW_LOG_PASSED_OBJ_X_IS_CLICKABLE, 
            to.getObjectId()))
    }
    return true
} catch (WebElementNotFoundException e) {
    logger.logWarning(e.getMessage())
    return false
} catch (TimeoutException e) {                    
    logger.logWarning(
        MessageFormat.format(
            StringConstants.KW_MSG_OBJ_IS_NOT_CLICKABLE_AFTER_X_SEC, [to.getObjectId(), timeOut] as Object[]))
    return false
}

By reading this fragment, I got to know the following

  1. the waitForElementClickable keyword waits for the target element to be present with timeout. If the timeout expires it fails.
  2. once the target is found present, then the keyward waits for it to be clickable with timeout. What if the timeout expires? — it just passes without emitting any message.

I think this behavior is arguable.

Possibly we want the last “if” statement to be amended as follows:

...
if (foundElement == null) {                     
    throw new TimeoutException()
}
return true

Other waitFor* keywords should be reviewed, of course.


#7

It seems to be reasonable to make WaitFor... honor FailureHandling settings. We will consider it in future releases.


#8

I would rather like to ask Katalon

  • waitFor… seems to be duplicating with verify… Why do you provide waitForElementPresent() as well as verifyElementPresent()?

I do not need waitForElementPresent(), I always use verifyElementPresent().


#9

I think only some of them are duplicate. Also it helps express the intention clearer, which sometimes ease the maintenance and incident investigation.


#10

Well, I can see the point having waitFor* to be used for waiting but not failing, but then I miss the possibility to verifyElement* with timeout which I reported in my other post ( Parameter timeout not consistent in verifyElement* methods ).

What I can see of solutions are:

  1. All verifyElement* get’s timeout parameter and remove the FailureHandling paremeter on waitFor (since it doesn’t work anyway)
  2. waitFor* honors FailureHandling, default can be Optional, but it should honor if we override it.

I don’t really care how this is solved (but I prefer solution no 1). Both solve my issues, but I would really like one of these fixed because how they are now are causing issues. Yes, it can be solved by using clumsy workarounds (e.g. call verifyElementPresent and then verifyElementVisible), but it would be best just to have one, less error prone…


#11

Added @Dung_Ngo to the discussion.