Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>katalon</artifactId>
<version>1.0.3-SNAPSHOT</version>
<version>1.0.7-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>Katalon Studio Plugin</name>
<description>Execute Katalon Studio in Jenkins</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

public class ExecuteKatalonStudioTask extends Builder {

Expand All @@ -26,11 +23,22 @@ public class ExecuteKatalonStudioTask extends Builder {

private String executeArgs;

private String x11Display;

private String xvfbConfiguration;

@DataBoundConstructor
public ExecuteKatalonStudioTask(String version, String location, String executeArgs) {
public ExecuteKatalonStudioTask(
String version,
String location,
String executeArgs,
String x11Display,
String xvfbConfiguration) {
this.version = version;
this.location = location;
this.executeArgs = executeArgs;
this.x11Display = x11Display;
this.xvfbConfiguration = xvfbConfiguration;
}

public String getVersion() {
Expand All @@ -57,67 +65,53 @@ public void setExecuteArgs(String executeArgs) {
this.executeArgs = executeArgs;
}

private void executeKatalon(String katalonExecutableFile, String workSpace, BuildListener buildListener) throws IOException {
File file = new File(katalonExecutableFile);
if (!file.exists()) {
file = new File(katalonExecutableFile + ".exe");
}
if (file.exists()) {
file.setExecutable(true);
}
if (katalonExecutableFile.contains(" ")) {
katalonExecutableFile = "\"" + katalonExecutableFile + "\"";
}
String command = katalonExecutableFile +
" -noSplash " +
" -runMode=console " +
" -projectPath=\"" + workSpace + "\" " +
this.executeArgs;
public String getX11Display() {
return x11Display;
}

OsUtils.runCommand(buildListener, command);
public void setX11Display(String x11Display) {
this.x11Display = x11Display;
}

public String getXvfbConfiguration() {
return xvfbConfiguration;
}

public void setXvfbConfiguration(String xvfbConfiguration) {
this.xvfbConfiguration = xvfbConfiguration;
}

@Override
public boolean perform(AbstractBuild<?, ?> abstractBuild, Launcher launcher, BuildListener buildListener) throws InterruptedException, IOException {
public boolean perform(AbstractBuild<?, ?> abstractBuild, Launcher launcher, BuildListener buildListener)
throws InterruptedException, IOException {
try {

FilePath workspace = abstractBuild.getWorkspace();

if (workspace != null) {
String workspaceLocation = workspace.getRemote();

if (workspaceLocation != null) {

String katalonDirPath;

if (StringUtils.isBlank(this.location)) {
File katalonDir = KatalonUtils.getKatalonPackage(buildListener, this.version);
katalonDirPath = katalonDir.getAbsolutePath();
} else {
katalonDirPath = this.location;
}

LogUtils.log(buildListener, "Using Katalon Studio at " + katalonDirPath);
String katalonExecutableFile;
String os = OsUtils.getOSVersion(buildListener);
if (os.contains("macos")) {
katalonExecutableFile = Paths.get(katalonDirPath, "Contents", "MacOS", "katalon")
.toAbsolutePath()
.toString();
} else {
katalonExecutableFile = Paths.get(katalonDirPath, "katalon")
.toAbsolutePath()
.toString();
}
executeKatalon(katalonExecutableFile, workspaceLocation, buildListener);
return KatalonUtils.executeKatalon(
buildListener,
this.version,
this.location,
workspaceLocation,
this.executeArgs,
this.x11Display,
this.xvfbConfiguration);

}
}

return true;

} catch (Exception e) {
String stackTrace = Throwables.getStackTraceAsString(e);
LogUtils.log(buildListener, stackTrace);
return false;
}
return true;
}

@Extension
Expand Down
70 changes: 70 additions & 0 deletions src/main/java/com/katalon/jenkins/plugin/KatalonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hudson.FilePath;
import hudson.model.BuildListener;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -134,4 +135,73 @@ static File getKatalonPackage(

return katalonContainingDir;
}

private static boolean executeKatalon(
BuildListener buildListener,
String katalonExecutableFile,
String projectPath,
String executeArgs,
String x11Display,
String xvfbConfiguration)
throws IOException, InterruptedException {
File file = new File(katalonExecutableFile);
if (!file.exists()) {
file = new File(katalonExecutableFile + ".exe");
}
if (file.exists()) {
file.setExecutable(true);
}
if (katalonExecutableFile.contains(" ")) {
katalonExecutableFile = "\"" + katalonExecutableFile + "\"";
}
String command = katalonExecutableFile +
" -noSplash " +
" -runMode=console ";
if (!executeArgs.contains("-projectPath")) {
command += " -projectPath=\"" + projectPath + "\" ";
}
command += " " + executeArgs + " ";

return OsUtils.runCommand(buildListener, command, x11Display, xvfbConfiguration);
}

public static boolean executeKatalon(
BuildListener buildListener,
String version,
String location,
String projectPath,
String executeArgs,
String x11Display,
String xvfbConfiguration)
throws IOException, InterruptedException {

String katalonDirPath;

if (StringUtils.isBlank(location)) {
File katalonDir = KatalonUtils.getKatalonPackage(buildListener, version);
katalonDirPath = katalonDir.getAbsolutePath();
} else {
katalonDirPath = location;
}

LogUtils.log(buildListener, "Using Katalon Studio at " + katalonDirPath);
String katalonExecutableFile;
String os = OsUtils.getOSVersion(buildListener);
if (os.contains("macos")) {
katalonExecutableFile = Paths.get(katalonDirPath, "Contents", "MacOS", "katalon")
.toAbsolutePath()
.toString();
} else {
katalonExecutableFile = Paths.get(katalonDirPath, "katalon")
.toAbsolutePath()
.toString();
}
return executeKatalon(
buildListener,
katalonExecutableFile,
projectPath,
executeArgs,
x11Display,
xvfbConfiguration);
}
}
33 changes: 25 additions & 8 deletions src/main/java/com/katalon/jenkins/plugin/OsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

import hudson.model.BuildListener;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class OsUtils {

Expand Down Expand Up @@ -43,16 +45,29 @@ static String getOSVersion(BuildListener buildListener) {
return "";
}

static void runCommand(BuildListener buildListener, String command) throws IOException {
static boolean runCommand(
BuildListener buildListener,
String command,
String x11Display,
String xvfbConfiguration)
throws IOException, InterruptedException {

String[] cmdarray;
if (SystemUtils.IS_OS_WINDOWS) {
cmdarray = Arrays.asList("cmd", "/c", command).toArray(new String[]{});
} else {
cmdarray = Arrays.asList("sh", "-c", command).toArray(new String[]{});
if (!StringUtils.isBlank(x11Display)) {
command = "DISPLAY=" + x11Display + " " + command;
}
if (!StringUtils.isBlank(xvfbConfiguration)) {
command = "xvfb-run " + xvfbConfiguration + " " + command;
}
List<String> cmdlist = Arrays.asList("sh", "-c", command);
cmdarray = cmdlist.toArray(new String[]{});
}
LogUtils.log(buildListener, "Execute " + command);
Process cmdProc = Runtime.getRuntime().exec(cmdarray);
Path workingDirectory = Files.createTempDirectory("katalon-");
LogUtils.log(buildListener, "Execute " + Arrays.toString(cmdarray) + " in " + workingDirectory);
Process cmdProc = Runtime.getRuntime().exec(cmdarray, null, workingDirectory.toFile());
try (
BufferedReader stdoutReader = new BufferedReader(
new InputStreamReader(
Expand All @@ -67,5 +82,7 @@ static void runCommand(BuildListener buildListener, String command) throws IOExc
LogUtils.log(buildListener, line);
}
}
cmdProc.waitFor();
return cmdProc.exitValue() == 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<f:entry title="Download Katalon Studio version (e.g. 5.8.3)" field="version">
<f:entry title="Download Katalon Studio version" field="version">
<f:textbox />
</f:entry>

<f:entry title="Use pre-installed Katalon Studio" field="location">
<f:textbox />
</f:entry>

<f:entry title="Command arguments (except -runMode and -projectPath)" field="executeArgs">
<f:entry title="Command arguments" field="executeArgs">
<f:textarea />
</f:entry>

<f:entry title="X11 DISPLAY (for Linux)" field="x11Display">
<f:textbox />
</f:entry>

<f:entry title="Xvfb-run configuration (for Linux)" field="xvfbConfiguration">
<f:textbox />
</f:entry>

</j:jelly>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div>E.g. -browserType="Chrome" -retry=0 -statusDelay=15 -testSuitePath="Test Suites/Regression Tests/All tests".</div>
<div>E.g. <code>-browserType="Chrome" -retry=0 -statusDelay=15 -testSuitePath="Test Suites/Regression Tests/All tests"</code>. Please leave out <code>-runMode</code>. If not specified, <code>-projectPath</code> will be set to the current workspace directory.</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>E.g. <code>/var/lib/jenkins/Katalon_Studio_Linux_64-5.10.1</code>. Use this field when Katalon Studio cannot be downloaded automatically (often due to network conditions).</div>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div>The list of all releases can be retrieved from <a href="https://github.com/katalon-studio/katalon-studio/releases" target="_blank">here</a>.</div>
<div>E.g. <code>5.10.1</code>. The list of all releases can be retrieved from <a href="https://github.com/katalon-studio/katalon-studio/releases" target="_blank">here</a>.</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div>E.g. <code>:1</code>. This value will be used as the <code>DISPLAY</code> environment variable.
Jenkins must be allowed to connect to the display, see <code>xhost</code> if you encounter access control issues.</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>E.g. <code>-a -n 0 -s "-screen 0 1024x768x24"</code>. If specified, <code>xvfb-run</code> will be used. Please make sure Xvfb has been installed.</div>