This is WONDERFUL, will give it a go as time permits this week and reply back with my findings. Thank you so much!
UPDATE: Hmm… the newest CallerB function seems to be going one layer too deep and causing an error.
For comparison, here is the driver script I’m using showing the calls being made when I call at the Parent Folder level (the original CallerB) and the new CallerB:
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testcase.TestCaseFactory as TestCaseFactory
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testdata.TestDataFactory as TestDataFactory
import com.kms.katalon.core.testobject.ObjectRepository as ObjectRepository
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import internal.GlobalVariable as GlobalVariable
import com.kms.katalon.core.annotation.SetUp
import com.kms.katalon.core.annotation.SetupTestCase
import com.kms.katalon.core.annotation.TearDown
import com.kms.katalon.core.annotation.TearDownTestCase
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.stream.Collectors
import com.kms.katalon.core.configuration.RunConfiguration
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import btt_portal.*
//Variable creation and population
Common_Functions common_functions = new Common_Functions()
String driver_user_name = user_name
String driver_site_name = site_name
int driver_object_timeout = Integer.valueOf(object_timeout)
/*
///Folder Tree Call
def pathname_array = ['01-Rgsn/02 - UI/02-Menu/03-Bus. Analy']
for (int counter; counter < pathname_array.size(); counter = counter + 1) {
common_functions.run_folder_tree_tests(pathname_array[counter],driver_user_name,driver_site_name,driver_object_timeout)
}
*
/*
///Parent Folder Call
def pathname_array = ['01-Rgsn/02 - UI/02-Menu/03-Bus. Analy/01-Slw Pgs'
]
for (int counter; counter < pathname_array.size(); counter = counter + 1) {
common_functions.run_folder_tests(pathname_array[counter],driver_user_name,driver_site_name,driver_object_timeout)
}
*/
Here’s the original CallerB function as I implemented it:
/***********************************************************************************************************************
* Function Name: run_folder_tests and listChildDirectoriesOf
*
* Function Overview: Runs all test scripts found in a given folder path (does not include subfolders)
*
* Function Input Variable(s):
* @input_folder_path - Path to the desired Test Script folder (NOTE: Do NOT include the high level "Test Suites" layer in the path)
* @input_user_name - User name to be used for the test script iteration (will override the currently set Test Script variable)
* @input_site_name - Site name to be used for the test script iteration (will override the currently set Test Script variable)
* @input_object_timeout - Object Timeout Time name to be used for the test script iteration (will override the currently set Test Script variable)
*
*******************************************************************************************************************************/
public String run_folder_tests(input_folder_path, String input_user_name, String input_site_name, int input_object_timeout = 20) {
KeywordUtil log = new KeywordUtil()
Path projectDir = Paths.get(RunConfiguration.getProjectDir())
Path scriptsDir = projectDir.resolve("Scripts")
Path myTestsFolder = scriptsDir.resolve(input_folder_path)
assert Files.exists(myTestsFolder)
List<Path> testCases = listChildDirectoriesOf(myTestsFolder).sort()
assert testCases.size() > 0
testCases.forEach({test_case ->
String current_script_path = scriptsDir.relativize(test_case).toString()
log.markWarning('current script path: ' + current_script_path)
WebUI.callTestCase(findTestCase(current_script_path), ['user_name' : input_user_name, 'site_name' : input_site_name,'object_timeout' : input_object_timeout], FailureHandling.CONTINUE_ON_FAILURE)
})
}
def List<Path> listChildDirectoriesOf(Path dir) throws IOException {
return Files.list(dir)
.filter {Files.isDirectory(it) }
.collect(Collectors.toList());
}
and the newer function:
/***********************************************************************************************************************
* Function Name: run_folder_tree_tests and listFilesRecursively
*
* Function Overview: Runs all test scripts found in a given folder path (including subfolders)
*
* Function Input Variable(s):
* @input_folder_path - Path to the desired Test Script folder (NOTE: Do NOT include the high level "Test Suites" layer in the path)
* @input_user_name - User name to be used for the test script iteration (will override the currently set Test Script variable)
* @input_site_name - Site name to be used for the test script iteration (will override the currently set Test Script variable)
* @input_object_timeout - Object Timeout Time name to be used for the test script iteration (will override the currently set Test Script variable)
*
*******************************************************************************************************************************/
public String run_folder_tree_tests(input_folder_path, String input_user_name, String input_site_name, int input_object_timeout = 20) {
KeywordUtil log = new KeywordUtil()
Path projectDir = Paths.get(RunConfiguration.getProjectDir())
Path scriptsDir = projectDir.resolve("Scripts")
Path myTestsFolder = scriptsDir.resolve(input_folder_path)
assert Files.exists(myTestsFolder)
List<Path> testCases = listFilesRecursively(myTestsFolder).sort()
assert testCases.size() > 0
testCases.forEach({test_case ->
String current_script_path = scriptsDir.relativize(test_case).toString()
log.markWarning('current script path: ' + current_script_path)
WebUI.callTestCase(findTestCase(current_script_path), ['user_name' : input_user_name, 'site_name' : input_site_name,'object_timeout' : input_object_timeout], FailureHandling.CONTINUE_ON_FAILURE)
})
}
// https://www.baeldung.com/java-list-directory-files#walking
def List<Path> listFilesRecursively(Path dir) throws IOException {
List<Path> directoryList = new ArrayList<>()
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (!Files.isDirectory(file)) {
directoryList.add(file.toAbsolutePath())
}
return FileVisitResult.CONTINUE
}
})
directoryList.sort()
return directoryList
}
Script name output from the original CallerB function:
and Error output from the Tree version of CallerB: