How to perform mobile actions on an app within a separate thread

I am trying to catch unexpected events in the background of a mobile app and decided to create a separate thread that would wait for that event to occur using the Mobile.waitForElementPresent keyword. I would start the application in the main thread, and then create a new thread right after that would wait for the events to occur. Whenever I run the program, I get this error.

Exception in thread "Thread-14" com.kms.katalon.core.exception.StepFailedException: No driver found
at com.kms.katalon.core.mobile.helper.MobileScreenCaptor.getAnyAppiumDriver(MobileScreenCaptor.java:82)
at com.kms.katalon.core.mobile.helper.MobileScreenCaptor.take(MobileScreenCaptor.java:49)
at com.kms.katalon.core.helper.screenshot.ScreenCaptor.takeScreenshotAndGetAttributes(ScreenCaptor.java:37)
at com.kms.katalon.core.mobile.keyword.internal.MobileKeywordMain.stepFailed(MobileKeywordMain.groovy:40)
at com.kms.katalon.core.mobile.keyword.internal.MobileKeywordMain.runKeyword(MobileKeywordMain.groovy:23)
at com.kms.katalon.core.mobile.keyword.builtin.WaitForElementPresentKeyword.waitForElementPresent(WaitForElementPresentKeyword.groovy:80)
at com.kms.katalon.core.mobile.keyword.builtin.WaitForElementPresentKeyword.execute(WaitForElementPresentKeyword.groovy:64)
at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:73)
at com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords.waitForElementPresent(MobileBuiltInKeywords.groovy:1553)
at com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords$waitForElementPresent$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at patient.ErrorHandling$ThreadDeploy_Error.run(ErrorHandling.groovy:29)

Is there any way I can use Mobile keywords on the application I already started, within the newly created separate thread?

Here is the run method for the thread I am creating.

	public void run() {
		try {
			println("[THREAD INFO] Thread " + this.threadName + " successfully deployed. Date: " + Util.getCurrentDateAsString())
			KeywordUtil.logInfo("[THREAD INFO] Thread " + this.threadName + " successfully deployed. Date: " + Util.getCurrentDateAsString())
                            // Wait for error element
			Mobile.waitForElementPresent(findTestObject('Object Repository/Mobile/Error_Elements/android.widget.Error_PopUp_Text'), Constants.INFINITY)
			KeywordUtil.markError("[THREAD WARN] Error notification recieved. Date: " + Util.getCurrentDateAsString())
			
		} catch (InterruptedException e) {
			System.out.println( this.threadName + "-- Thread interrupted!!!");
		}
	}

I do not think that the Thread you newly created can get access to the Appium Driver instance created by your Test Case thread. The driver is only accessible for the current thread of the Test Case script itself. The driver is not accessible for other Threads.

How do I know it? I will tell you.

You can read the source code of MobileScreenCapter.getAnyAppiumDriver at

You can start with it, and read further to find

there you will find:

    private static final ThreadLocal<Integer> localStorageAppiumServer = new ThreadLocal<Integer>() {
        ....
    };

It’s an instance of java.lang.ThreadLocal. ThreadLocal object will be accessible only by a specific thread

IMHO, I find no benefit in creating separate Threads in Test Cases in Katalon Studio.

@kazurayam Thanks for the response, I thought that would be the case. Would there be any other way to run multiple Mobile keywords at the same time? E.g. Waiting for an element to show using Mobile.waitForElementPresent in the background of a test case while that test case continues on as normal. I basically need to check if an unexpected element appears while I am running a normal test case.

Are you concerned that Mobile.waitForElementPreset runs very slow?

Yes, there are many post about the slowness of Mobile keywords. For example,

The speed of keyword largely depends on how the locator expression in TestObject is written. In many cases you can find some alternative expressions that run much faster. How to write faster locators? — That is a question to be studied case-by-case. There is no silver bullet.

Sorry, I am not experienced with Mobile testing. If you want to find out a way to make your Mobile tests run faster, you should ask Mobile testing experts (@Chris_Trevarthen and others) for advices.

Do you mean by this “sharing an instance of driver by multiple threads”? As I wrote, it is NOT possible, as the KS stores the driver instance is ThreadLocal.

Alternative approach could be creating 2 instances of of drivers at the same time. I have ever demonstrated a test case for WebUI. See

I proved that I can open a single URL in 2 browser windows simultaneously and do 2 sets of assertions on each windows. This approach would help you organising codes packed per target web pages; a bit easier to read.

Please note this example does assertions sequentially, one by one. It does not perform parallel things at all. So this approach does not make processing faster.

Sorry, I do not know if it is possible for Mobile as well.

It seems you want Mobile.asyncWaitForElementPresent which works asynchronously. You want to register a Groovy Closure as a callback, and timeout. As you know, all of KS built-in keywords are synchronous. There is no async type of keyword. That is something completely new. I have no idea if its feasible in KS or not.

I suppose that Image comparison is an alternative approach to check if anything UNEXPECTED happened. You want to take screenshots twice: before “normal test case” and after “normal test case”. And then create “diff” between the 2 images, with which you would find unexpected things if any.