Katalon script keeps crashing because the app logs me out unexpectedly

I’m pretty new to Katalon Studio and automation in general, and I’ve been stuck on this one issue for the past two days.

I wrote a test suite to fill out a long registration form and then verify the profile details. When I run the first few steps, everything works perfectly. But somewhere around the middle of the form, the application automatically logs me out and redirects to the login page. Because of this, my script completely crashes with a StepFailedException or WebElementNotFoundException because it’s still trying to click buttons and fill text boxes on a page that isn’t there anymore.

I don’t know how to tell Katalon, “Hey, if you suddenly see the login page, log back in before you keep going,” or at least have it check if we are still logged in before it tries to click something. Right now, it just panics and crashes. Any help would be appreciated!

What you are experiencing is a classic automation challenge related to Session Expiry or Unstable Environments.

When a web application automatically logs you out, the DOM (the underlying HTML structure) completely changes. Your script is hardcoded to look for Elements A, B, and C, but it is suddenly staring at the Login fields.

The Architectural Fix

To handle this gracefully and keep your tests scalable, we need to implement a Conditional State Check. Instead of assuming the user is always logged in, we will create a Custom Keyword that checks for a “Session Indicator” (like a sidebar, a user profile icon, or a dashboard heading). If that indicator disappears, the script will automatically handle the re-login sequence before attempting the next step.

Implementation: The Custom Keyword

We will create a Custom Keyword called checkSessionAndRecover. You can call this keyword periodically during long tests, or wrap your critical actions inside it.

Step 1: Create the Custom Keyword

In Katalon Studio, go to Keywords (in the Object Repository sidebar) → NewKeyword. Name the package com.recovery and the class SessionHandler.

Paste the following Groovy code:

Groovy

package com.recovery

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.testobject.TestObject

public class SessionHandler {

	/**
	 * Checks if the user is still logged in. If logged out, handles re-login.
	 * @param sessionElement The Test Object that proves you are logged in (e.g., Logout Button, Profile Icon)
	 * @param loginMethod A closure/block of code containing your login steps
	 */
	@Keyword
	def checkSessionAndRecover(TestObject sessionElement, Closure loginMethod) {
		// Check if the session element is present within a quick 3-second window
		// We use FailureHandling.OPTIONAL so it doesn't crash the test if missing
		boolean isTemplatePresent = WebUI.waitForElementPresent(sessionElement, 3, FailureHandling.OPTIONAL)
		
		if (!isTemplatePresent) {
			WebUI.comment("Session loss detected! Initiating recovery login sequence...")
			
			// Execute the login steps passed to this keyword
			loginMethod.call()
			
			WebUI.comment("Recovery successful. Resuming test execution.")
		} else {
			WebUI.comment("Session is valid. Proceeding with test.")
		}
	}
}

Step 2: How to use it in your Test Case (Script View)

In your actual Test Case, you can now gracefully handle the flakey logout like this:

Groovy

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

// 1. Define your "Session Indicator" (an element only visible when logged in)
def dashboardElement = findTestObject('Object Repository/MainPage/btn_Logout')

// 2. Before doing a long action, check the session. If it's gone, it runs the code inside the brackets {}
CustomKeywords.'com.recovery.SessionHandler.checkSessionAndRecover'(dashboardElement, {
	WebUI.navigateToUrl('https://your-app.com/login')
	WebUI.setText(findTestObject('Object Repository/LoginPage/input_Username'), 'your_user')
	WebUI.setText(findTestObject('Object Repository/LoginPage/input_Password'), 'your_password')
	WebUI.click(findTestObject('Object Repository/LoginPage/btn_Submit'))
})

// 3. Continue your normal test steps safely
WebUI.setText(findTestObject('Object Repository/FormPage/input_FirstName'), 'John')

Why this works beautifully:

  1. Non-Blocking Check: By using FailureHandling.OPTIONAL, Katalon won’t panic if it doesn’t find your logged-in dashboard element. It simply returns false and moves to the if block.

  2. Encapsulated Logic: The Closure loginMethod allows you to pass your entire login flow as a variable inside the keyword, keeping your recovery logic dynamic and clean.

  3. No Waste of Time: It only waits a maximum of 3 seconds to confirm your session, meaning your test execution stays fast.

Generlly it is better if you post your codebase and community provide fix relevent to that. let me know if this work

Before jumping into how to handle this situation you should first analyze why it is happening.

Ideally session timeout depends on the application and domain. In secure systems (like banking) it may be intentionally short.

But if you see, the concern to me seems to be why your test case is executing for more than session timeout? If not explicitly required, consider breaking the flow into smaller, independent test cases.

Few considerations -

  1. You should launch a fresh browser and login for each test case (this keeps your tests clean and avoids cache related issues)
  2. If entering username and password in each test case is time consuming you can consider API based login - This is a more advanced approach and can be explored as a next step.
  3. If logout can still happen unexpectedly, add a session check before critical steps (e.g., verify presence of a logout button or login page). If the session is lost, re-authenticate instead of letting the test fail immediately.

hi @vmuller

the root issue is that your script assumes the session is always valid, so when the DOM changes unexpectedly, it fails hard. You need a session check before critical actions.

the cleanest fix is a custom keyword that checks for a logged-in indicator element and re-authenticates if it’s missing. Use waitForElementPresent with FailureHandling.OPTIONAL so a missing element doesn’t throw an exception.

@Keyword
def ensureLoggedIn(TestObject sessionIndicator, Closure relogin) {
    if (!WebUI.waitForElementPresent(sessionIndicator, 3, FailureHandling.OPTIONAL)) {
        WebUI.comment("Session expired, re-logging in")
        relogin.call()
    }
}

call it before the steps that tend to fail:

CustomKeywords.'com.my.SessionHandler.ensureLoggedIn'(findTestObject('Dashboard/btn_Profile'), {
    WebUI.navigateToUrl('https://myapp.com/login')
    WebUI.setText(findTestObject('Login/input_User'), 'admin')
    WebUI.setText(findTestObject('Login/input_Pass'), 'password')
    WebUI.click(findTestObject('Login/btn_Submit'))
})

also investigate why the logout happens. If it is a short session timeout on your test environment, see if you can get it increased. Recovering mid-test is fine, but avoiding the logout in the first place is better

Try to upgrade to the latest stable build if not done already

This is usually a session-expiry problem: the app redirects to login mid-flow, and the script keeps trying to act on the old page state.

What to do

Add a quick checkpoint before critical steps:

  • Verify a logged-in-only element exists, such as a profile icon or logout button.
  • If it’s missing, run the login steps again.
  • Then continue the form from the point where the session recovered.

Simple pattern

if (!WebUI.verifyElementPresent(findTestObject('MainPage/btn_Logout'), 3, FailureHandling.OPTIONAL)) {
    WebUI.navigateToUrl('https://your-app.com/login')
    WebUI.setText(findTestObject('LoginPage/input_Username'), 'your_user')
    WebUI.setText(findTestObject('LoginPage/input_Password'), 'your_password')
    WebUI.click(findTestObject('LoginPage/btn_Submit'))
}

Better structure

Wrap the login recovery into a reusable custom keyword so you can call it during long flows. Use a stable “session indicator” that only appears when the user is authenticated, not something that can exist on both pages.

Extra stability

  • Reduce idle time in the middle of long forms.
  • Break the flow into smaller steps with session checks between them.
  • Save test data before the risky section so recovery doesn’t force a full restart.

If this keeps happening, the app may need a longer session timeout in test environments or a test account configured not to expire so aggressively

@vmuller The issue you posted sounds like a session/authentication issue rather than a Katalon issue. When the application redirects to the login page, your script continues looking for elements from the previous page, which leads to StepFailedException or WebElementNotFoundException.

Add a session validation check before critical actions. For example, verify whether a login page element is present (or check if the URL contains /login). If it is, call your Login test case again and then continue execution.

Before performing critical actions, verify that the session is still active.

Try like the below exampl

boolean loginPageVisible = WebUI.verifyElementPresent(
    findTestObject('LoginPage/txt_Username'),
    2,
    FailureHandling.OPTIONAL
)

if(loginPageVisible) {
    WebUI.comment('Session expired. Logging in again.')

    WebUI.callTestCase(
        findTestCase('Common/Login'),
        [:],
        FailureHandling.STOP_ON_FAILURE
    )
}

Then continue with the test execution.
Please us know more about the \issue.
Note: I want to know which version of katalon u are using, if 11.0.1 please update it with the latest version

Curious question to all, how often should he call this to check if the session is valid or logged out?

After every step?

After every 2 steps?

Or when exactly in the script?

This sounds literally very unusual. It sounds that your application has an obvious bug. It is too buggy that you can not automate your tests at all. Then, you need to fix the bug in your app first before you start automating your grand test suite.

@vmuller

Have you tested your app manually with your hands without Katalon? In that case, does the app automatically log you out and redirect you to the login page? If it does, it is too buggy. If it doesn’t, what’s the difference? You should find out the reason why. I don’t see what’s happening in your app at all. Nobody, other than you yourself, can see how your app works.

Please study your application under the test for yourself in more detail and tell us how it works. Once you could describe the behavior of the application with more concrete detail, the guys would be able to advise you better.

I am also just curious if you are scrolling down your page via code, using WebUI.scrollToElement(element, timeout) or WebUI.scrollToPosition(x, y), or do let Katalon do it with click events. If you let Katalon do it, perhaps try to use code do it, like:

WebUI.scrollToPosition(100, 0) // top of the page

WebUI.scrollToElement(findTestObject(‘myPage/input_Status’), 10)

(position the page maybe 1 inch or 2 cm above your objects)

Also, maybe you can try to use WebUI.sendKeys() instead of WebUI.setText()to see if this assists in keeping your page active.

Edit: maybe you might be encountering a situation that you have an error in one of your Katalon statements, such as having one too many parameters, that is causing a “fatal” error and closing your browser. Review your test script to see if your script collapses at the same spot repeatedly.

Depends on his app behaviours, If the flow is not consistent then need to look for actions that are dependent on login in that case need to see session or call session handler for all other steps, one can bypass checking state at everytime.