Multiple Test cases need same login, How to fix it!

I’m building out a regression suite and I have about 30 different test cases to create. Every single one of them requires the user to log in first before doing anything else.

What I’ve been doing is recording the login steps once, and then literally copy-pasting those same 5-6 rows of WebUI keywords (inputting username, password, clicking submit) into the script view of every new test case I make.

It technically works, but yesterday our dev team changed the ID of the password field on the login page. I had to manually go into 12 different test cases just to fix that one selector. I still have 18 more to go, and it’s exhausting. I tried looking at the “Call Test Case” option, but I’m a bit confused about how to pass variables or if that’s even the right industry standard way to handle this. I’m terrified of what will happen if the login page changes again.

How do professionals handle reusable steps like login in Katalon without losing their minds?

Yes, “Call Test Case” is highly recommended way to handle login procedure in Katalon. Take your time for digging into it.

In professional test automation, we strictly follow the DRY principle (Don’t Repeat Yourself). If a piece of logic—like logging in—is used more than once, it should live in exactly one place. This way, if the developers change an element ID tomorrow, you fix it in one single spot, and all 30+ tests instantly adapt.

In Katalon Studio, you have two excellent built-in ways to handle this:

  1. Call Test Case (Built-in Keyword): Perfect for standard workflow reuse.

  2. Custom Keywords (Groovy/Java): Ideal if you want a clean, programmatic function you can call seamlessly across scripts.

The Explanation: What went wrong?

By copy-pasting, you tightly coupled your test logic with your application’s UI state. The moment the UI state shifted, your tests broke globally. By abstracting the login process into a reusable component, we decouple the prerequisite (logging in) from the objective of the actual test case.

The Solution

We will create a Custom Keyword. This turns your login sequence into a reusable block of code that looks and acts just like a native Katalon command (e.g., WebUI.click).

Step 1: Create a Package and Keyword

  1. In your Katalon Object Repository/Tests Explorer, navigate to Keywords.

  2. Right-click > New > Package (Name it com.helper).

  3. Right-click your new package > New > Keyword (Name the class LoginHelper).

Step 2: The Custom Keyword Code

Paste the following code into your LoginHelper.groovy file. This function accepts a username and password as arguments, making it dynamic.

Groovy

package com.helper

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.testobject.ObjectRepository

public class LoginHelper {

    /**
     * Log into the application using specified credentials
     * @param username
     * @param password
     */
    @Keyword
    def loginToApplication(String username, String password) {
        // Opens the browser and navigates to your base URL (defined in your execution profile)
        WebUI.openBrowser('')
        WebUI.navigateToUrl('https://example.com/login')
        WebUI.maximizeWindow()

        // Interact with your existing Object Repository items
        WebUI.setText(ObjectRepository.findTestObject('Object Repository/Page_Login/input_Username'), username)
        WebUI.setEncryptedText(ObjectRepository.findTestObject('Object Repository/Page_Login/input_Password'), password)
        
        WebUI.click(ObjectRepository.findTestObject('Object Repository/Page_Login/button_Submit'))
        
        // Optional: Verify login success before proceeding
        WebUI.verifyElementPresent(ObjectRepository.findTestObject('Object Repository/Page_Dashboard/header_Welcome'), 10)
    }
}

Step 3: How to call it in your 30 Test Cases

Now, instead of copy-pasting 6 lines of code into every test, your test cases will start with just one simple, clean line.

In Script View:

Groovy

// Call your custom keyword at the start of any test case
CustomKeywords.'com.helper.LoginHelper.loginToApplication'('my_user_abc', 'my_secure_password')

// Continue with your actual test steps below...
WebUI.click(ObjectRepository.findTestObject('Object Repository/Page_Dashboard/btn_CreateReport'))

In Manual View: If you prefer Manual View, simply click Add > Custom Keyword, select loginToApplication from the dropdown, and pass your username and password into the input cells.

Why this saves your project:

  • Single Point of Maintenance: If the login URL or object IDs change, you edit them only inside LoginHelper.groovy.

  • Readability: Your actual test cases stay focused on what they are actually trying to test, rather than being cluttered with setup steps.

Note: If its require for every testcase you can explore Test Listner as well.

Best approach would be to do login Via test data.
Create the login test case and use it as the reusable artifact. Now either you can create test suite or call the login test in the test case using call test case, and change the ID and password only in the test data.

If the <id> of an object changes then you should only need to make that change in the Object Repository for that specific object and all instances of that object in your project will update. If, unfortunately, you are creating a new object because you don’t know how to change a pathway, or how to create a pathway, then I can understand what you are doing. You should spend some time learning either XPath or CSS.

As @qurzunta.kaab states, because you only have a few lines of code, I also would go with a Keyword; I use Call Test Case for lengthy pieces of code. About the Keyword, I would add some more statements than what he has given you above. I would add statements that check that your objects are clickable, and what the output of trying to setText would be since, to me, that is needed if you don’t add the clickable statement, like:

"username"
WebUI.waitForElementClickable(findTestObject('myPage/input_Username'), 10)
WebUI.verifyElementClickable(findTestObject('myPage/input_Username'))
WebUI.setText(findTestObject('myPage/input_Username'), username)
WebUI.verifyElementAttributeValue(findTestObject('myPage/input_Username'), "value", username, 10)

"password"
WebUI.verifyElementClickable(findTestObject('myPage/input_Password'))
WebUI.setEncryptedText(findTestObject('myPage/input_Password'), password)

"login"
WebUI.verifyElementClickable(findTestObject('myPage/button_Submit'))
WebUI.click(findTestObject('myPage/button_Submit'))
        
"next page"
WebUI.waitForElementClickable(findTestObject('myPage/header_Welcome'), 10)
WebUI.verifyElementPresent(findTestObject('myPage/header_Welcome'), 10)

Note: if you encrypt the password text then we can’t verify it without the encryption method; if you just setText, then I would put in a verification of the contents of the field that the text was entered similar to username.

Edit: Also you need to have the following at the top of your test case:

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

import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

I would recommend to test the login test case once and for the rest of the gest cases loging through API . It will save a lot of your time. Why call the login test case every time

If you need to change login look for Data Driven Testing, If not Keyword is good to go.

Can you please share Test Listner thing ?

Yes, this is exactly the kind of step that should not live inside every test case. I’d keep the login flow in one reusable place, either as a separate test case with “Call Test Case” or as a custom keyword if you want it cleaner in script view. Then each regression test can start with one login call and move straight to the actual scenario.

The big win is maintenance. If the password field ID changes again, you fix the object or login helper once instead of touch 30 tests. I’d also keep the username/password in profiles or variables, not hardcoded in each case.