Set execution settings in script

I’m trying to update the report[screenCaptureOption] setting via script so that I can sometimes allow screenshots and sometimes not (i.e., I don’t want pages with sensitive to take screenshots, but others are fine).

I’m trying to update with RunConfiguration.setExecutionSetting, but I’m getting a null pointer exception. I’ve checked the RunConfiguration documentation but it didn’t clear anything up.

Any help folks can give is appreciated!

My execution properties look like this (the one I want to change is in bold):
[autoApplyNeighborXpaths:false, ignorePageLoadTimeoutException:false, timeCapsuleEnabled:false, executionProfile:default, excludeKeywords:[verifyElementPresent, verifyElementNotPresent], xpathsPriority:[[left:xpath:attributes, right:true], [left:xpath:idRelative, right:true], [left:dom:name, right:true], [left:xpath:link, right:true], [left:xpath:neighbor, right:true], [left:xpath:href, right:true], [left:xpath:img, right:true], [left:xpath:position, right:true], [left:xpath:customAttributes, right:true]], timeout:30.0, actionDelay:0.0, methodsPriorityOrder:[[left:XPATH, right:true], [left:CSS, right:true], [left:BASIC, right:true], [left:IMAGE, right:true]], proxy:{“proxyOption”:“USE_SYSTEM”,“proxyServerType”:“HTTP”,“username”:“”,“password”:“”,“proxyServerAddress”:“127.0.0.1”,“proxyServerPort”:0,“exceptionList”:“”,“applyToDesiredCapabilities”:true}, defaultFailureHandling:STOP_ON_FAILURE, terminateDriverAfterTestCase:false, defaultPageLoadTimeout:30.0, report:[videoRecorderOption:[enable:false, useBrowserRecorder:true, videoFormat:AVI, videoQuality:LOW, recordAllTestCases:false, allowedRecordIfFailed:true, allowedRecordIfPassed:false], screenCaptureOption:true, reportFolder:/var/folders/rk/6ltbhf7j4gl59_84khbd1hrh0000gn/T/Katalon/Test Cases/UnitTests/KeywordUTs/UTKW001_GetTestCaseID/20240802_141716], enablePageLoadTimeout:false, terminateDriverAfterTestSuite:true, useActionDelayInSecond:SECONDS, testDataInfo:[:], selfHealingEnabled:false]

My script (currently in a listener) is:

import com.kms.katalon.core.annotation.BeforeTestCase
import com.kms.katalon.core.annotation.BeforeTestSuite
import com.kms.katalon.core.configuration.RunConfiguration
import com.kms.katalon.core.context.TestCaseContext
import com.kms.katalon.core.context.TestSuiteContext
import com.kms.katalon.core.util.KeywordUtil

import internal.GlobalVariable

class TurnOffScreenCapture {
	/**
	 * Executes before every test case starts.
	 * @param testCaseContext related information of the executed test case.
	 */
	@BeforeTestCase
	def sampleBeforeTestCase(TestCaseContext testCaseContext) {
		if (!GlobalVariable.screenShotsDisabled) {
			// Don't run if this has already been run by the test suite
			turnOffScreenShots()
		}
	}

	/**
	 * Executes before every test suite starts.
	 * @param testSuiteContext: related information of the executed test suite.
	 */
	@BeforeTestSuite
	def sampleBeforeTestSuite(TestSuiteContext testSuiteContext) {
		turnOffScreenShots() 
	}
	
	private void turnOffScreenShots() {
		try {
			// Get the current execution properties
			Map<String, Object> executionProperties = RunConfiguration.getExecutionGeneralProperties()
			
			if (executionProperties == null) {
				KeywordUtil.markWarning("Execution properties are null")
			} else {
				KeywordUtil.logInfo("Execution properties: " + executionProperties.toString())
				
				// Check if 'report' key exists and is a Map
				if (executionProperties.containsKey('report') && executionProperties['report'] instanceof Map) {
					executionProperties['report']['screenCaptureOption'] = false // or true to enable
					KeywordUtil.logInfo(executionProperties['report']['screenCaptureOption'].toString())
				} else {
					KeywordUtil.markWarning("Report settings not found or not a Map in execution properties")
				}
				
				// Log the final state of executionProperties before setting it
				KeywordUtil.logInfo("Final execution properties before setting: " + executionProperties.toString())
				
				// Apply the updated execution settings
				RunConfiguration.setExecutionSetting(executionProperties) // throws NullPointerException
				
				// Set this variable to true to indicate other test cases in the suite don't need to run it
				GlobalVariable.screenShotsDisabled = true
			}
		} catch (Exception e) {
			KeywordUtil.markError("Error while updating execution settings: " + e.message)
			e.printStackTrace()
		}
	}
}
1 Like

Hi there,

Thank you very much for your topic. Please note that it may take a little while before a member of our community or from Katalon team responds to you.

Thanks!

I did copy&paste your Test Listener code and got the following error.

2024-08-04 06:47:34.047 INFO  com.kms.katalon.core.util.KeywordUtil    - Final execution properties before setting: [autoApplyNeighborXpaths:false, ignorePageLoadTimeoutException:false, timeCapsuleEnabled:false, executionProfile:default, excludeKeywords:[verifyElementPresent, verifyElementNotPresent], xpathsPriority:[[left:xpath:attributes, right:true], [left:xpath:idRelative, right:true], [left:dom:name, right:true], [left:xpath:link, right:true], [left:xpath:neighbor, right:true], [left:xpath:href, right:true], [left:xpath:img, right:true], [left:xpath:position, right:true], [left:xpath:customAttributes, right:true]], timeout:30.0, actionDelay:0.0, methodsPriorityOrder:[[left:XPATH, right:true], [left:BASIC, right:true], [left:CSS, right:true], [left:IMAGE, right:true]], proxy:{"proxyOption":"NO_PROXY","proxyServerType":"HTTP","username":"","password":"","proxyServerAddress":"","proxyServerPort":0,"exceptionList":"","applyToDesiredCapabilities":true}, defaultFailureHandling:STOP_ON_FAILURE, terminateDriverAfterTestCase:false, defaultPageLoadTimeout:30.0, report:[videoRecorderOption:[enable:false, useBrowserRecorder:true, videoFormat:AVI, videoQuality:LOW, recordAllTestCases:false, allowedRecordIfFailed:true, allowedRecordIfPassed:false], screenCaptureOption:false, reportFolder:/Users/kazuakiurayama/katalon-workspace/test/Reports/20240804_064726/TS0/20240804_064726], enablePageLoadTimeout:false, terminateDriverAfterTestSuite:true, useActionDelayInSecond:SECONDS, testDataInfo:[:], selfHealingEnabled:false]
2024-08-04 06:47:34.123 ERROR c.k.k.core.context.internal.TestHooker   - ❌ java.lang.NullPointerException: Cannot invoke "java.util.Map.get(Object)" because the return value of "com.kms.katalon.core.configuration.RunConfiguration.getExecutionProperties()" is null
	at com.kms.katalon.core.configuration.RunConfiguration.getDriverExecutionProperties(RunConfiguration.java:296)
	at com.kms.katalon.core.configuration.RunConfiguration.getDriverPreferencesProperties(RunConfiguration.java:332)
	at com.kms.katalon.core.configuration.RunConfiguration.getDriverPreferencesProperties(RunConfiguration.java:328)
	at com.kms.katalon.core.util.TestCloudPropertyUtil.hideTestCloudSensitiveName(TestCloudPropertyUtil.java:111)
	at com.kms.katalon.core.logging.KeywordLogger.logStartKeyword(KeywordLogger.java:194)
	at com.kms.katalon.core.logging.KeywordLogger.startKeyword(KeywordLogger.java:223)
	at com.kms.katalon.core.ast.TestStepUtil.logStartKeyword(TestStepUtil.java:35)
	at TurnOffScreenCapture.turnOffScreenShots(TL.groovy:62)
	at TurnOffScreenCapture.sampleBeforeTestSuite(TL.groovy:32)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at com.kms.katalon.core.context.internal.TestHooker.invokeMethod(TestHooker.java:111)
	at com.kms.katalon.core.context.internal.TestHooker.lambda$3(TestHooker.java:95)
	at com.kms.katalon.core.context.internal.TestHooker.invokeContextMethods(TestHooker.java:94)
	at com.kms.katalon.core.context.internal.TestListenerCollector.lambda$3(TestListenerCollector.java:88)
	at com.kms.katalon.core.context.internal.TestListenerCollector.handleListenerEvent(TestListenerCollector.java:85)
	at com.kms.katalon.core.context.internal.ExecutionEventManager.publicEvent(ExecutionEventManager.java:36)
	at com.kms.katalon.core.main.TestSuiteExecutor.execute(TestSuiteExecutor.java:104)
	at com.kms.katalon.core.main.TestCaseMain.startTestSuite(TestCaseMain.java:187)
	at TempTestSuite1722721646508.run(TempTestSuite1722721646508.groovy:36)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Caught: java.lang.IllegalArgumentException: No enum constant com.kms.katalon.core.model.RunningMode.null
java.lang.IllegalArgumentException: No enum constant com.kms.katalon.core.model.RunningMode.null
	at com.kms.katalon.core.model.RunningMode.valueOf(RunningMode.java:1)
	at com.kms.katalon.core.configuration.RunConfiguration.getRunningMode(RunConfiguration.java:647)
	at com.kms.katalon.core.main.TestSuiteExecutor.accessTestSuiteMainPhase(TestSuiteExecutor.java:142)
	at com.kms.katalon.core.main.TestSuiteExecutor.execute(TestSuiteExecutor.java:106)
	at com.kms.katalon.core.main.TestCaseMain.startTestSuite(TestCaseMain.java:187)
	at TempTestSuite1722721646508.run(TempTestSuite1722721646508.groovy:36)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

The folloing message is interesting

java.lang.IllegalArgumentException: No enum constant com.kms.katalon.core.model.RunningMode.null
	at com.kms.katalon.core.model.RunningMode.valueOf(RunningMode.java:1)
...
	at com.kms.katalon.core.main.TestSuiteExecutor.accessTestSuiteMainPhase(TestSuiteExecutor.java:142)
...

What is com.ks.katalon.core.mode.RunningMode ? I could retrieve the source code:

package com.kms.katalon.core.model;

public enum RunningMode {
    GUI("gui"),
    CONSOLE("console");
    
    private final String mode;
    
    private RunningMode(String mode) {
        this.mode = mode;
    }

    public String getMode() {
        return mode;
    }
}

I suppose that "GUI" means the Katalon Studio’ GUI, "console" means the Katalon Runtime Engine.

The exception was thrown at

at com.kms.katalon.core.main.TestSuiteExecutor.accessTestSuiteMainPhase(TestSuiteExecutor.java:142

So I check the source code of TestSuiteExecutor.java:142. I got puzzled. The TestSuiteExecutor.java:142 seems to have nothing to do with RunConfiguration.setExecutionSetting(...). There could be a mere bug in TestSuiteExecutor.java:142. And @abby.watt encounted with it just accidentally.

Anyway, as everybody know, Katalon Studio does not officially support modifying the report.takeScreenshotOption=true/false in the /settings/internal/com.kms.katalon.execution.properties dynamically during a test run by user scripts. Anything curious could happen.

@abby.watt won’t be satisfied with the “Screenshots on failure” feature of Katalon Studio as long as he/she can not hide the sensitives in the screenshots taken.

I think that @abby.watt 's point is valid. The feature would be useless if it can not hide/remove the sensitives in the screenshots.

1 Like

WebUI.takeFullPageScreenshot keyword accepts an option ignoredElements

  • Name: ignoredElements
    • Description: List of Test Objects you want to hide when taking a screenshot.
    • Parameter Type: List
    • Mandatory: Optional

An HTML element specified to be ignored will be painted with a grey rectangle in a screenshot, effectively the element will be hidden. With it, you should be able to hide the sensitive part on the screenshot.

@abby.watt

Does the feature “ignoredElements” help you?

As Kaz said, maybe something like this:


import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.configuration.RunConfiguration as RunConfiguration

// Define the list of elements to be ignored
List ignoredElements = [findTestObject('UI/logo'), findTestObject('UI/banner')]

// Take a full-page screenshot and save it to a specified path, ignoring certain elements
WebUI.takeFullPageScreenshot(RunConfiguration.getReportFolder() + '/full_view_no_elements.png', ignoredElements)

  • The screenshot is saved in the
  • report folder with the name full_view_no_elements.png.

I appreciate your not assuming my pronouns; they are she/her/hers.

Thank you for all of the information in your responses. You are correct that I’m not able to use “Screenshots on failure” if I can’t hide sensitives.

I appreciate the suggestion. Due to the nature of our product I want to assume that every element should be ignored unless I specify that it’s safe to screen shot (I want to opt in instead of opting out).

I’ll think about the feasibility of writing a method that adds all of the test objects in the repo to the ignore list, and removes them if I manually specify that they’re ok. I’m worried that that might be unwieldy to maintain and that the performance would be bad, but maybe that’s a way to go.

@abby.watt

You can take screenshots in Katalon Studio by the feature “Take Screent when execution failed”.

Let me ask you a question. Who do you expect to see the PNG pictures that were taken when your test failed?

Do you expect only you to see the screenshots? Or are you going to distribute the screenshots more widely? To your collegues, to your managers, or even to customers?

I think that the feature “Take Screenshots when execution failed” is designed with an implicit assumption that the pictures will be shared only by a small/closed/private development team. The feature is intended to let your team notified of the failure and let them fix it as soon as possible. Therefore Katalon did not plan hiding the sensitives in the pictures. In my humble opinion, this design is acceptable.

If you are going to share the screenshots to a wider range of audience, and therefore you must be careful about the sensitives in the pictures, I think you should manully take the screenshots while you carefully black out the sensitives.

Sharing within my company isn’t the main issue: the issue is that it would be a breach of data privacy for these screenshots to get uploaded to Katalon TestOps if they were to contain actual customer data (which is where they are uploaded when they are taken).

This point looks significant but argueable.

Some would take everything serious but others wouldn’t mind.

Perhaps, if you are serious, you would not be able to use “Take Screenshots on failure” backed by TestOps.

In our case it isn’t arguable. The customer didn’t agree for their sensitive information to get shared with Katalon, and we don’t have a BAA with Katalon.

I agree: the easiest solution is to not use Take Screenshots on Failure.

Ah, I understand your situation. I believe that your situation is typical, not exceptional.

@Elly_Tran

Will Katalon consider establishing a scheme of Business Associate Agreement with your Enterprise users?

1 Like

@abby.watt

If you are going to take screenshots using the keywords like takeFullPageScreenshot and want the images to be attached in the Basic report, you need to be careful where (into which folder) you save the .png files. See the following post: