Custom Keyword Exception

Hi ,
Im new katalon studio. Trying to create custom keyword Here is my code

package package_Mycustom
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.checkpoint.Checkpoint
import com.kms.katalon.core.checkpoint.CheckpointFactory
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testcase.TestCase
import com.kms.katalon.core.testcase.TestCaseFactory
import com.kms.katalon.core.testdata.TestData
import com.kms.katalon.core.testdata.TestDataFactory
import com.kms.katalon.core.testobject.ObjectRepository
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords

import internal.GlobalVariable

import MobileBuiltInKeywords as Mobile
import WSBuiltInKeywords as WS
import WebUiBuiltInKeywords as WebUI

import org.openqa.selenium.WebElement
import org.openqa.selenium.WebDriver
import org.openqa.selenium.By

import com.kms.katalon.core.mobile.keyword.internal.MobileDriverFactory
import com.kms.katalon.core.webui.common.WebUiCommonHelper
import com.kms.katalon.core.webui.driver.DriverFactory

import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObjectProperty

import com.kms.katalon.core.mobile.helper.MobileElementCommonHelper
import com.kms.katalon.core.util.KeywordUtil

import com.kms.katalon.core.webui.exception.WebElementNotFoundException

class check_link_text {
@Keyword
def verifylinktext(TestObject object, String text){
try {

		WebElement element = WebUIAbstractKeyword.findWebElement(object);//WebUiBuiltInKeywords.findWebElement(object);
		String val =  element.getText()
		

		KeywordUtil.markPassed("Element has been found")
	} catch (WebElementNotFoundException e) {
		KeywordUtil.markFailed("Element not found")
	} catch (Exception e) {
		KeywordUtil.markFailed("Fail to click on element")
	}
}

I see an exception with Fail to click on element. Can somone guide me whats wrong im doing here

@chandan.kumar

Please provide the full log in your Console tab when this exception occurs.

@ThanhTo Thanks for replying

Custom Keyword Code

package package_mycustom
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.checkpoint.Checkpoint
import com.kms.katalon.core.checkpoint.CheckpointFactory
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testcase.TestCase
import com.kms.katalon.core.testcase.TestCaseFactory
import com.kms.katalon.core.testdata.TestData
import com.kms.katalon.core.testdata.TestDataFactory
import com.kms.katalon.core.testobject.ObjectRepository
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords

import internal.GlobalVariable

import MobileBuiltInKeywords as Mobile
import WSBuiltInKeywords as WS
import WebUiBuiltInKeywords as WebUI

import org.openqa.selenium.WebElement
import org.openqa.selenium.WebDriver
import org.openqa.selenium.By

import com.kms.katalon.core.mobile.keyword.internal.MobileDriverFactory
import com.kms.katalon.core.webui.driver.DriverFactory

import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObjectProperty

import com.kms.katalon.core.mobile.helper.MobileElementCommonHelper
import com.kms.katalon.core.util.KeywordUtil

import com.kms.katalon.core.webui.exception.WebElementNotFoundException
import com.kms.katalon.core.webui.common.WebUiCommonHelper

class check_link_text {
/**
* Refresh browser
*/
@Keyword
def refreshBrowser() {
KeywordUtil.logInfo(“Refreshing”)
WebDriver webDriver = DriverFactory.getWebDriver()
webDriver.navigate().refresh()
KeywordUtil.markPassed(“Refresh successfully”)
}

/**
 * Click element
 * @param to Katalon test object
 */
@Keyword
def clickElement(TestObject to) {
	try {
		WebElement element = WebUiBuiltInKeywords.findWebElement(to);
		KeywordUtil.logInfo("Clicking element")
		element.click()
		KeywordUtil.markPassed("Element has been clicked")
	} catch (WebElementNotFoundException e) {
		KeywordUtil.markFailed("Element not found")
	} catch (Exception e) {
		KeywordUtil.markFailed("Fail to click on element")
	}
}

/**
 * Get all rows of HTML table
 * @param table Katalon test object represent for HTML table
 * @param outerTagName outer tag name of TR tag, usually is TBODY
 * @return All rows inside HTML table
 */
@Keyword
def List<WebElement> getHtmlTableRows(TestObject table, String outerTagName) {
	WebElement mailList = WebUiBuiltInKeywords.findWebElement(table)
	List<WebElement> selectedRows = mailList.findElements(By.xpath("./" + outerTagName + "/tr"))
	return selectedRows
}


@Keyword
def verifylinktext(TestObject object, String text){
	try {

		WebElement element = WebUiBuiltInKeywords.findWebElement(object);			
		//WebUIAbstractKeyword.findWebElement(object);//WebUiBuiltInKeywords.findWebElement(object);
		String val =  element.getText()
		println (" CHK: Debug",val)

		KeywordUtil.markPassed("Element has been found")
	} catch (WebElementNotFoundException e) {
		KeywordUtil.markFailed("Element not found")
	} catch (Exception e) {
		KeywordUtil.markFailed("Fail to click on element")
	}
}

}
Issue-1: Strangely the click element generated by studio works. but the verifylinktext created by myself ,fails to identify the webelement.
Issue-2: When script failed to identify the element ,the test execution should stop. If you see the logs ,even after failed test step execution continued. I’m sure i have selected STOP_ON_FAILURE in settings. This is observed with custom keywords only.
Console LOG

2020-08-31 23:49:25.319 INFO c.k.katalon.core.main.TestCaseExecutor - --------------------
2020-08-31 23:49:25.324 INFO c.k.katalon.core.main.TestCaseExecutor - START Test Cases/Chrome/Login/CustomKeywordTest
2020-08-31 23:49:26.043 DEBUG testcase.CustomKeywordTest - 1: openBrowser("")
2020-08-31 23:49:26.486 INFO c.k.k.core.webui.driver.DriverFactory - Starting ‘Chrome’ driver
Aug 31, 2020 11:49:26 PM org.openqa.selenium.remote.DesiredCapabilities chrome
INFO: Using new ChromeOptions() is preferred to DesiredCapabilities.chrome()
2020-08-31 23:49:26.533 INFO c.k.k.core.webui.driver.DriverFactory - Action delay is set to 0 milliseconds
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 35220
Only local connections are allowed.
Aug 31, 2020 11:49:30 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
2020-08-31 23:49:30.820 INFO c.k.k.core.webui.driver.DriverFactory - sessionId = 8d9f46cd18217a6dc3af40abf0205dd7
2020-08-31 23:49:30.853 INFO c.k.k.core.webui.driver.DriverFactory - browser = Chrome 85.0.4183.83
2020-08-31 23:49:30.853 INFO c.k.k.core.webui.driver.DriverFactory - platform = Windows 10
2020-08-31 23:49:30.854 INFO c.k.k.core.webui.driver.DriverFactory - seleniumVersion = 3.141.59
2020-08-31 23:49:30.855 INFO c.k.k.core.webui.driver.DriverFactory - proxyInformation = ProxyInformation { proxyOption=NO_PROXY, proxyServerType=HTTP, username=, password=********, proxyServerAddress=, proxyServerPort=0, executionList="", isApplyToDesiredCapabilities=true }
2020-08-31 23:49:30.873 DEBUG testcase.CustomKeywordTest - 2: navigateToUrl(“https://sms.com”)
2020-08-31 23:49:34.073 DEBUG testcase.CustomKeywordTest - 3: delay(10)
2020-08-31 23:49:44.156 DEBUG testcase.CustomKeywordTest - 4: package_mycustom.check_link_text.verifylinktext(findTestObject(“Page_sms/Forgotpasswd_linkText”), “Forgot”)
2020-08-31 23:49:44.535 ERROR com.kms.katalon.core.util.KeywordUtil - :x: Fail to click on element
2020-08-31 23:49:44.537 ERROR k.k.c.m.CustomKeywordDelegatingMetaClass - :x: com.kms.katalon.core.exception.StepFailedException: Fail to click on element
2020-08-31 23:49:44.555 DEBUG testcase.CustomKeywordTest - 5: setText(findTestObject(“Object Repository/Page_sms/input_Email_mat-input-0”), “chandan.kumar@sms.com”)
2020-08-31 23:49:45.328 DEBUG testcase.CustomKeywordTest - 6: setEncryptedText(findTestObject(“Object Repository/Page_sms/input_Email_mat-input-1”), “Jh8igW29pD8Lc1unKQ1CNA==”)
2020-08-31 23:49:45.875 DEBUG testcase.CustomKeywordTest - 7: waitForElementClickable(findTestObject(“Page_sms/button_Log In”), 10)
2020-08-31 23:49:46.311 DEBUG testcase.CustomKeywordTest - 8: click(findTestObject(“Object Repository/Page_sms/button_Log In”))
2020-08-31 23:49:46.826 DEBUG testcase.CustomKeywordTest - 9: delay(10)
2020-08-31 23:49:56.832 DEBUG testcase.CustomKeywordTest - 10: verifyTextPresent(“Bangalore”, false)
2020-08-31 23:49:57.139 DEBUG testcase.CustomKeywordTest - 11: closeBrowser()
2020-08-31 23:49:58.946 ERROR c.k.katalon.core.main.TestCaseExecutor - :x: Test Cases/Chrome/Login/CustomKeywordTest FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: Fail to click on element
at com.kms.katalon.core.util.KeywordUtil.markFailed(KeywordUtil.java:19)
at com.kms.katalon.core.util.KeywordUtil$markFailed.call(Unknown Source)
at package_mycustom.check_link_text.verifylinktext(check_link_text.groovy:102)
at package_mycustom.check_link_text.invokeMethod(check_link_text.groovy)
at com.kms.katalon.core.main.CustomKeywordDelegatingMetaClass.invokeStaticMethod(CustomKeywordDelegatingMetaClass.java:50)
at CustomKeywordTest.run(CustomKeywordTest:24)
at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:339)
at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:330)
at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:309)
at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:301)
at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:235)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:114)
at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
at TempTestCase1598897961781.run(TempTestCase1598897961781.groovy:25)

2020-08-31 23:49:59.003 INFO c.k.katalon.core.main.TestCaseExecutor - END Test Cases/Chrome/Login/CustomKeywordTest

@chandan.kumar

This catch clause in your keyword’s implementation:

	} catch (Exception e) {
		KeywordUtil.markFailed("Fail to click on element")
	}

is swallowing the exception. In other words, it hides the exception by always printing out Fail to click on element. Try to remove that catch clause and then execute the test again to see what is the real problem.

@ThanhTo

Yeah I agree. I kept the valid exception because user can understand easily. I will share the actual exception.
But the same logic for click element worked without any exception. Also can you help me to understand why the execution continued even after failure.

/**

  • Click element
  • @param to Katalon test object
    */
    @Keyword
    def clickElement(TestObject to) {
    try {
    WebElement element = WebUiBuiltInKeywords.findWebElement(to);
    KeywordUtil.logInfo(“Clicking element”)
    element.click()
    KeywordUtil.markPassed(“Element has been clicked”)
    } catch (WebElementNotFoundException e) {
    KeywordUtil.markFailed(“Element not found”)
    } catch (Exception e) {
    KeywordUtil.markFailed(“Fail to click on element”)
    }
    }

@chandan.kumar

The execution continued even after failure because KeywordUtil.markFailed marks a Custom Keyword step as failed and continue execution. You can hover over the method to read the documentation. If you want to stop the execution upon failure inside a Custom Keyword, use KeywordUtil.markFailedAndStop instead.

Additionally, my guess is that the object doesn’t have any text, which would explain why calling getText() on it throws an exception. Try to verify the xpath for that element using Chrome Dev Tool to see if the element actually contains any text.

@ThanhTo

Thanks for clarifying on test step execution even after failure . Im trying read the text of the an object .i.e basically a link (forgot password). I have used Xpath to find the element and read the text for that object.
To my surprise without changing any anything (even the object ). Keyword started working with same piece of code. Just added print statements. You can see the prints in the console log

 @Keyword
def clickElement(TestObject to) {
	try {
		WebElement element = WebUiBuiltInKeywords.findWebElement(to);			
		String text =  element.getText()			
		System.out.println(" Get text Click Element Keyword: Debug---------------" + text)			
		KeywordUtil.logInfo("Clicking element")
		element.click()
		KeywordUtil.markPassed("Element has been clicked")
	} catch (WebElementNotFoundException e) {
		KeywordUtil.markFailed("Element not found")
	} catch (Exception e) {
		//KeywordUtil.markFailed("Fail to click on element")
		System.out.println(" Reason for exception: Debug---------------" + e)
	}
}



   @Keyword
def verifylinktext(TestObject object, String text){
	try {

		WebElement element = WebUiBuiltInKeywords.findWebElement(object);

		//WebUIAbstractKeyword.findWebElement(object);//WebUiBuiltInKeywords.findWebElement(object);
		
		String val =  element.getText()
		System.out.println(" Get text in verifylinktext keyword: Debug---------------" + val)
		
		//String val =  element.getAttribute("innerHTML")
		//System.out.println(" inner html link text function: Debug" + val)
		KeywordUtil.markPassed("Element has been found")
		
	} catch (WebElementNotFoundException e) {
		KeywordUtil.markFailed("Element not found")
	} catch (Exception e) {
	System.out.println(" Reason for exception: Debug---------------" + e)
	
		//KeywordUtil.markFailed("Fail to click on element")
	}

2020-09-01 13:53:06.619 INFO c.k.katalon.core.main.TestCaseExecutor - --------------------
2020-09-01 13:53:06.627 INFO c.k.katalon.core.main.TestCaseExecutor - START Test Cases/Chrome/Login/CustomKeywordTest
2020-09-01 13:53:07.284 DEBUG testcase.CustomKeywordTest - 1: openBrowser("")
2020-09-01 13:53:07.706 INFO c.k.k.core.webui.driver.DriverFactory - Starting ‘Chrome’ driver
Sep 01, 2020 1:53:07 PM org.openqa.selenium.remote.DesiredCapabilities chrome
INFO: Using new ChromeOptions() is preferred to DesiredCapabilities.chrome()
2020-09-01 13:53:07.767 INFO c.k.k.core.webui.driver.DriverFactory - Action delay is set to 0 milliseconds
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 13693
Only local connections are allowed.
Sep 01, 2020 1:53:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
2020-09-01 13:53:12.599 INFO c.k.k.core.webui.driver.DriverFactory - sessionId = 2a96eb75a4a84b43f6c06db0682ec984
2020-09-01 13:53:12.661 INFO c.k.k.core.webui.driver.DriverFactory - browser = Chrome 85.0.4183.83
2020-09-01 13:53:12.662 INFO c.k.k.core.webui.driver.DriverFactory - platform = Windows 10
2020-09-01 13:53:12.662 INFO c.k.k.core.webui.driver.DriverFactory - seleniumVersion = 3.141.59
2020-09-01 13:53:12.668 INFO c.k.k.core.webui.driver.DriverFactory - proxyInformation = ProxyInformation { proxyOption=NO_PROXY, proxyServerType=HTTP, username=, password=********, proxyServerAddress=, proxyServerPort=0, executionList="", isApplyToDesiredCapabilities=true }
2020-09-01 13:53:12.682 DEBUG testcase.CustomKeywordTest - 2: navigateToUrl(“https://sms.com”)
2020-09-01 13:53:16.115 DEBUG testcase.CustomKeywordTest - 3: delay(10)
2020-09-01 13:53:26.188 DEBUG testcase.CustomKeywordTest - 4: package_mycustom.check_link_text.clickElement(findTestObject(“Page_sms/Forgotpasswd_linkText”))
Get text Click Element Keyword: Debug---------------Forgot your password?
2020-09-01 13:53:26.612 INFO com.kms.katalon.core.util.KeywordUtil - Clicking element
2020-09-01 13:53:26.752 DEBUG com.kms.katalon.core.util.KeywordUtil - ✓ Element has been clicked
2020-09-01 13:53:26.754 DEBUG testcase.CustomKeywordTest - 5: refresh()
2020-09-01 13:53:28.153 DEBUG testcase.CustomKeywordTest - 6: package_mycustom.check_link_text.verifylinktext(findTestObject(“Page_sms/Forgotpasswd_linkText”), “Forgot”)
Get text in verifylinktext keyword: Debug---------------Forgot your password?
2020-09-01 13:53:28.654 DEBUG com.kms.katalon.core.util.KeywordUtil - ✓ Element has been found
2020-09-01 13:53:28.654 DEBUG testcase.CustomKeywordTest - 7: delay(5)
2020-09-01 13:53:33.659 DEBUG testcase.CustomKeywordTest - 8: closeBrowser()
2020-09-01 13:53:35.900 INFO c.k.katalon.core.main.TestCaseExecutor - END Test Cases/Chrome/Login/CustomKeywordTest

@chandan.kumar

I think the difference is that in the preceding click. It failed when you didn’t use Click customkeyword.

When it passes:

I suspect that the preceding click triggers a side-effect that makes the Forget Your Password link clickable, and originally when you load the page it wasn’t clickable.

@ThanhTo
Not sure how it can work after that click.
Just tried again removing the click keyword and use only link text keyword. Now the test is passing,

2020-09-01 14:52:14.582 INFO c.k.katalon.core.main.TestCaseExecutor - --------------------
2020-09-01 14:52:14.588 INFO c.k.katalon.core.main.TestCaseExecutor - START Test Cases/Chrome/Login/CustomKeywordTest
2020-09-01 14:52:15.341 DEBUG testcase.CustomKeywordTest - 1: openBrowser("")
2020-09-01 14:52:15.813 INFO c.k.k.core.webui.driver.DriverFactory - Starting ‘Chrome’ driver
Sep 01, 2020 2:52:15 PM org.openqa.selenium.remote.DesiredCapabilities chrome
INFO: Using new ChromeOptions() is preferred to DesiredCapabilities.chrome()
2020-09-01 14:52:15.887 INFO c.k.k.core.webui.driver.DriverFactory - Action delay is set to 0 milliseconds
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 17603
Only local connections are allowed.
Sep 01, 2020 2:52:22 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
2020-09-01 14:52:22.453 INFO c.k.k.core.webui.driver.DriverFactory - sessionId = 559b473c3f729539bb5e4604f573bb6a
2020-09-01 14:52:22.491 INFO c.k.k.core.webui.driver.DriverFactory - browser = Chrome 85.0.4183.83
2020-09-01 14:52:22.493 INFO c.k.k.core.webui.driver.DriverFactory - platform = Windows 10
2020-09-01 14:52:22.494 INFO c.k.k.core.webui.driver.DriverFactory - seleniumVersion = 3.141.59
2020-09-01 14:52:22.495 INFO c.k.k.core.webui.driver.DriverFactory - proxyInformation = ProxyInformation { proxyOption=NO_PROXY, proxyServerType=HTTP, username=, password=********, proxyServerAddress=, proxyServerPort=0, executionList="", isApplyToDesiredCapabilities=true }
2020-09-01 14:52:22.510 DEBUG testcase.CustomKeywordTest - 2: navigateToUrl(“https://sms.com”)
2020-09-01 14:52:26.515 DEBUG testcase.CustomKeywordTest - 3: delay(5)
2020-09-01 14:52:31.563 DEBUG testcase.CustomKeywordTest - 4: package_mycustom.check_link_text.verifylinktext(findTestObject(“Page_sms/Forgotpasswd_linkText”), “Forgot”)
Get text in verifylinktext keyword: Debug---------------Forgot your password?
2020-09-01 14:52:31.984 DEBUG com.kms.katalon.core.util.KeywordUtil - ✓ Element has been found
2020-09-01 14:52:31.985 DEBUG testcase.CustomKeywordTest - 5: delay(5)
2020-09-01 14:52:36.992 DEBUG testcase.CustomKeywordTest - 6: closeBrowser()
2020-09-01 14:52:39.019 INFO c.k.katalon.core.main.TestCaseExecutor - END Test Cases/Chrome/Login/CustomKeywordTest