com.kazurayam.ks.globalvariable.ExecutionProfilesLoader.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ExecutionProfilesLoader Show documentation
Show all versions of ExecutionProfilesLoader Show documentation
A Katalon Studio plugin that enables loading Execution Profiles in test scripts
package com.kazurayam.ks.globalvariable
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.annotation.Keyword
import com.kms.katalon.core.configuration.RunConfiguration
import groovy.util.slurpersupport.GPathResult
/**
* Enables Test Case scripts to load Execution Profile(s) dynamically.
* ExecutionProfilesLoader modifies the GlobalVariable object using Groovy's Meta-programming technique.
* It can add new entries into the GlobalVariables, update the value of GlobalVariables, clear the added entries.
*
* @author kazurayam
*/
public final class ExecutionProfilesLoader {
private static final GlobalVariableAnnex XGV = GlobalVariableAnnex.newInstance()
private Path profilesDir
private XmlSlurper xmlSlurper
public Boolean onlyOnce = false
public Boolean alreadyDone = false
private static Path resolveProfilesDir() {
Path p
if (RunConfiguration != null
&& RunConfiguration.getProjectDir() != null
&& RunConfiguration.getProjectDir() != 'null') {
p = Paths.get(RunConfiguration.getProjectDir()).resolve("Profiles")
} else {
p = Paths.get(".").resolve("Profiles")
}
return p
}
ExecutionProfilesLoader() {
this(resolveProfilesDir())
}
ExecutionProfilesLoader(Path profilesDir) {
this.profilesDir = profilesDir
this.xmlSlurper = new XmlSlurper()
// important!
this.clear()
}
/**
* load an Execution Profile to add GlobalVariables dynamically and make them available to Test Case script
*
* @param profileName
* @return
*/
@Keyword
int loadProfile(String profileName) {
return this.loadProfiles( [profileName])
}
@Keyword
int loadProfiles(String... profileNames) {
List args = profileNames as List
return this.loadProfiles(args)
}
/**
* load Execution Profiles to add GlobalVariables dynamically and make them available to Test Case script
*
* @param profileNames
* @return
*/
@Keyword
int loadProfiles(List profileNames) {
if (this.onlyOnce && this.alreadyDone) {
throw new IllegalStateException("the property onlyOnce is set true, and loadProfiles method has already done once")
}
List profilePaths = profileNames.stream()
.map({ prof -> profilesDir.resolve(prof + '.glbl') })
.collect(Collectors.toList())
int count = 0
profilePaths.each { profile ->
Map loadedGlobalVariables = digestProfile(profile)
loadedGlobalVariables.entrySet().each({ entry ->
String name = entry.key.toString()
Object value = evaluateGroovyLiteral(entry.value.toString())
XGV.addGVEntity(name, value)
count += 1
})
}
alreadyDone = true
return count // returns how many GlobalVariables have been added
}
/* the clear() method is not implemented.
* we can add method to a Metaclass, but can not remove the added method
* see https://stackoverflow.com/questions/2745615/remove-single-metaclass-method
*/
// the clear() method does not work as expected.
// Why?
// We can add methods into Metaclass, but can not remove the added methods.
void clear() {
XGV.clear()
}
/**
*
* @param profile
*
* <?xml version="1.0" encoding="UTF-8"?>
* <GlobalVariableEntities>
* <description></description
* <name>default</name>
* <tag></tag>
* <defaultProfile>true</defaultProfile>
* <GlobalVariableEntity>
* <description></description>
* <initValue>'BAR'</initValue>
* <name>FOO</name>
* </GlobalVariableEntity>
* </GlobalVariableEntities>
*
* @return
*/
Map digestProfile(Path profile) {
Objects.requireNonNull(profile)
if (!Files.exists(profile)) {
throw new FileNotFoundException("${profile.toString()} is not found")
}
def keyValuePairs = [:]
GPathResult doc = xmlSlurper.parse(profile.toFile())
doc.GlobalVariableEntity.each { entity ->
keyValuePairs.put(entity.name, entity.initValue)
}
return keyValuePairs
}
/**
* Parse the given parameter string as a Groovy script, which is
* suppose to be a literal of various types.
* Evaluate the script to obtain a Object instanace and return it
*
* @param literal
* @return
*/
Object evaluateGroovyLiteral(String literal) {
Objects.requireNonNull(literal)
Object result
GroovyShell sh = new GroovyShell()
try {
result = sh.evaluate(literal)
} catch (Exception ex) {
throw new IllegalArgumentException("literal=\'${literal}\'", ex)
}
return result
}
/**
* actually update GlobalVariables
*
* @param globalVariableEntries
* @return
*/
static int loadEntries(Map globalVariableEntries) {
int count = 0
globalVariableEntries.entrySet().each({ entry ->
XGV.addGVEntity(entry.key, entry.value)
count += 1
})
return count
}
}