Check if directory contains file a filename

Hi

Am currently have a logic issue base on finding a filename that contains a specific string. An overview regarding the process. I have a test case which creates an excel file and stores couple of values. When the TC is created it has the following filename example “Getvideo_Pending_xxxx_xxxx.xlsx” (the xxxx_xxxx is dynamic string). When the TC finish it will change the filename to “Getvideo_Final_xxxx_xxxx.xlsx”. This TC is assign to a Test Suite where the Test Suite is assigned into Test Suite Collection with Parallel execution. So keep in mind that there will be more than one “Getvideo_Pending_xxxx_xxxx.xlsx” until become final and to become final the time is not the same.
I want to create a test suite where it will include a single TC where will search if at least one “Getvideo_Pending_xxxx_xxxx.xlsx” created and then I need a logic that all the filenames change to “Getvideo_Final_xxxx_xxxx.xlsx”

I have the below logic but returns that only Final files found where there still Pending Strings

//Retrieve specific temporary files
def list = []
def dir = new File(RunConfiguration.getProjectDir() + “/Data Files/Temporary/”)
files_found = false

while(files_found == false){
list = []
dir.eachFileRecurse (FileType.FILES) { file →
list << file
}
ArrayList filterFiles = new ArrayList()
for (int i=0;i<list.size();i++){
list[i]=list[i].toString()
list[i]=list[i].split(‘Temporary’)[list[i].split(‘Temporary’).size()-1].substring(1)
if (list[i].contains(“GetVideo”) == true){
filterFiles[i]=list[i]
filterFiles.removeAll([null])
}
if (filterFiles.contains(“GetVideo_Pending”) == false && filterFiles.contains(“GetVideo_Final”) == false){
files_found = true
println(‘File pending not found’)
WebUI.delay(5)
}
}
}
println(‘Final files found - Out of while loop’)
WebUI.delay(5)

// get parent folder:
def dir = new File(RunConfiguration.getProjectDir() + "/Data Files/Temporary/")    

// first requirement, will continuously check folder until at least 1 file name with substring of "Pending" exists:
def pending = false
do {
    def files = dir.list()
    for(File file : files) {
        if(file.getName().contains("Pending")) {
            pending = true
            break
        }
    }
} while(!pending)

// second requirement, will continuously check folder until all file names have substring of "Final"
def final = false
do {
    def files = dir.list()
    for(File file : files) {
        if(!file.getName().contains("Final")) {
            final = false
            break
        }
        else {
            final = true
        }
    }
} while(!final)

Note that there is a risk of an infinite loop here, if:
1.) A file with “Pending” in its name never appears.
2.) A file without “Final” in its name remains forever.

I believe that org.apache.tools.ant.DirectoryScanner, which was developed over 20 years ago, is the best old friend for a Java/Groovy programmer who wants to scan a fileset and select files/directories by the pattern matching over names.

import com.kms.katalon.core.configuration.RunConfiguration
import org.apache.tools.ant.DirectoryScanner

/**
 * Ant DirectoryScanner 
 * (http://docs.groovy-lang.org/docs/ant/api/org/apache/tools/ant/DirectoryScanner.html)
 * is your best friend
 */

File dir = new File(RunConfiguration.getProjectDir() + "/tmp/")

def ds = new DirectoryScanner()
ds.setBasedir(dir)
ds.setCaseSensitive(true)

// scan the directory for files of which name contains "Pending"
String[] includes1 = ["*Pending*"] as String[]
ds.setIncludes(includes1);
ds.scan()
String[] files1 = ds.getIncludedFiles()
println("number of Pending files: ${files1.length}")
files1.each { f ->
	println(f)
}

// scan the directory for files of which name contains "Final"
String[] includes2 = ["*Final*"] as String[]
ds.setIncludes(includes2);
ds.scan()
String[] files2 = ds.getIncludedFiles()
println("number of Final files: ${files2.length}")
files2.each { f ->
	println(f)
}

When I ran this, I got:

number of Pending files: 1
...
barPendingBar.xlsx
...
number of Final files: 1
...
fooFinalfoo.xlsx

You need to download a file ant-1.9.6.jar from the Maven Central Repository and save it into the Drivers directory of your project. You should stop/restart KS.


Groovy language support Ant
https://groovy-lang.org/scripting-ant.html
and you should be able to do the same directory scanning.

But I haven’t learned the AntBuilder yet. I would prefer calling the DirectoryScanner class directly in Katalon Test Case.

1 Like

I would agree, there are some libraries that are better suited for this type of work, like Apache’s FileUtils. It could also be accomplished with streams, but I figured the most understandable answer to the topic would be brute-force java/groovy, and no external libraries :thinking:

OK, I will try to be brutal as well.

I copied and pasted the Brandon’s code. But unfortunately it did not run due to the following reasons.

  • Groovy Language v2.4.x does not support do { ... } while (...) syntax
  • dir.list() does not return List<File>. It returns String[] instead
  • The code failed into an infinite loop too easily

So I modified it and got this:

import com.kms.katalon.core.configuration.RunConfiguration

// get parent folder:
def dir = new File(RunConfiguration.getProjectDir() + "/tmp/")

// first requirement, will continuously check folder until at least 1 file name with substring of "Pending" exists:
def foundPending = false
def files = dir.list()
for (String fileStr in files) {
	File file = new File(fileStr)
	if (file.getName().contains("Pending")) {
		println fileStr
		foundPending = true
	}
}
if (foundPending) {
	println "at least 1 file name with substring Pending found"
} else {
	println "no file name with substring Pending found"
}

// second requirement, will continuously check folder until all file names have substring of "Final"
def foundNonFinal = false
def files2 = dir.list()
for (String fileStr : files2) {
	File file = new File(fileStr)
	if (!file.getName().contains("Final")) {
		println fileStr
		foundNonFinal = true
	}
}
if (foundNonFinal) {
	println "at least 1 file name without substring Final found"
} else {
	println "all file names have string Final"
}

This code ran OK, but I found it unsatisfactory. Why? ---- I found this brute-force Test Case script (with for loop or each loop) is too slow.

If I have many files under the target directory, the above Test Case script emits too verbose Step Execution logs, and hence runs slowly. For example, when I have 20 files in the target directory, the test case emitted 170 lines of logs, and it took nearly 10 seconds to flush the messages into the Log Viewer GUI.

I personally would never accept slowness. I know a few approaches to make it faster. After some thoughts about them, I would be in favor of the Ant’s DirectoryScanner class. The test case with Ant’s DirectoryScanner runs far faster; in 2 seconds.

Thanks a lot. Your code and the library helped me a lot. I added couple of logics to proceed to the next steps and works fine.

Thanks again