Watchdog for UI elements

Hello, i’ll try to describe how to write asynchronous “watch dog” to check if some element appears

Situation:
our application is quite an asynchronous that means, that from time to time an Error can be shown on UI that actually does not directly belong to Test case i’m executing. However it will be good to catch such error and present it in reports.

prereq.:
I have TC that is responsible for Opening browser from this TC i will store actual driver into Global variable (type null)
I have my own reporting that allows me to store steps in way i need.

Solution:
in Test liseners i have following functions:

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

import com.kms.katalon.core.annotation.AfterTestCase
import com.kms.katalon.core.annotation.AfterTestSuite
import com.kms.katalon.core.annotation.BeforeTestCase
import com.kms.katalon.core.annotation.BeforeTestSuite
import com.kms.katalon.core.context.TestCaseContext
import com.kms.katalon.core.context.TestSuiteContext
import com.swre.report as Report

import internal.GlobalVariable as GlobalVariable


class PrepareTestDOC {

Report r = new Report()

private static TestCaseContext testCaseContext
private static TestSuiteContext testSuiteContext

private static Date start = new Date()

def runThread = true

def guard = new Thread({
	sleep(5000) // dont need to start early
	while(runThread){
		try{
// this is where i try to get driver stored by OpenBrowser TC
			def d = (WebDriver)GlobalVariable.webDriver
			
//My element that i want to watch
			WebElement e = d.findElement(By.xpath("//div[contains(@class,'noty_type_error')]//span"))
			
			if(e != null ){
				println "*** Found an ERROR bar!"
				def txt = e.text
				r.addStep("<center><b>UI Error!</b><br>${txt}</center>", false) //call to my reporting solution with information on UI error
				runThread = false
			}
		} catch (a){
			println a
		}
		println "*** from Guard ${new Date()}"
		sleep(3000)
	}
} as Runnable)

/**
 * Executes before every test case starts.
 * @param testCaseContext related information of the executed test case.
 */
@BeforeTestCase
def prepareTestCase(TestCaseContext testCaseContext) {
	GlobalVariable.testCaseContext = testCaseContext
// waking up guard
	r.setStartTest()
	println "*** Setting up guard"
	guard.start()
}

@AfterTestCase
def printStatus(TestCaseContext testCaseContext){
	r.addTestCase()
	r.setEndTest()
	r.flush()
 // thread.close() is deprecated so i use semafor to gracefully end it
	runThread = false
	println "*** Guard dissmissed"
}
}

and when error appears it looks like this in reports:

5 Likes

@Andrej_Podhajsky Thank you for this.

Great job!
I remember trying to catch ‘noty’ notification messages, but the difference was I knew when to expect them. Your solution is so much better.

Thank you guys,
thing is, that usually error messages are related to other background processes that may or may-not relay to test … therefore i needed to catch them other than standard way. also therefore test can pass even if error message was shown …
also mind the timing … in my case if error shows it will be there for quite some time i can be relaxed regarding timing … however it might be an issue in other cases

hi,

where is this lib
import com.swre.report as Report?

it’s my local library/keyword to use it one will have to make lot of changes in all TC he have, because it relays on existence of specific variable (or rather set of them) in TC.
also i don’t know if i can publish something like that since it’s in opposition of solution offered by Katalon and i don’t want to harm tool i’m using to feed my family…

1 Like

How you could get the log data?

sorry can you rephrase your question, i don’t understand what you want to know.

I mean, did you use extentreports plugin, right? If u want a create report using extentreports, u must use syntax createTest(), right? how you could get log from Katalon Studio and then created it into extentreport? just want to know how you could get log. Cuz I was explore the class log from Katalon, and I have no idea.

i’m not using any logging that is built in Katalon.
i created function that i’m calling my function:

addStep(String detail, Boolean assertion)

where as return value can be returning value of any “verify” command or return from callTestCase()
then step i want log looks like:

r.addStep("Check Data Containers button",WebUI.verifyElementVisible(findTestObject('/IRAMP-CC/CC UI/Main Page IRAMPCC/menu_DataContainers'), FailureHandling.OPTIONAL))

hope this explains a bit…