diff --git a/pom.xml b/pom.xml
index d149b1a..8691b99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.jvnet.hudson.plugins
analysis-pom
- 5.17.0
+ 5.18.0
diff --git a/src/test/java/io/jenkins/plugins/util/IntegrationTest.java b/src/test/java/io/jenkins/plugins/util/IntegrationTest.java
index eeac83b..007552d 100644
--- a/src/test/java/io/jenkins/plugins/util/IntegrationTest.java
+++ b/src/test/java/io/jenkins/plugins/util/IntegrationTest.java
@@ -1,39 +1,27 @@
package io.jenkins.plugins.util;
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
+import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;
-import java.util.logging.Level;
+import java.util.function.Function;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Tag;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.JSONWebResponse;
-import org.jvnet.hudson.test.JenkinsRule.WebClient;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
-import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
-import com.gargoylesoftware.htmlunit.ScriptException;
-import com.gargoylesoftware.htmlunit.ScriptResult;
-import com.gargoylesoftware.htmlunit.SilentCssErrorHandler;
-import com.gargoylesoftware.htmlunit.html.DomElement;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlFormUtil;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import com.gargoylesoftware.htmlunit.javascript.JavaScriptErrorListener;
-
import edu.hm.hafner.util.PathUtil;
import edu.hm.hafner.util.ResourceTest;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.flow.FlowDefinition;
@@ -42,7 +30,6 @@
import hudson.Functions;
import hudson.model.Action;
import hudson.model.FreeStyleProject;
-import hudson.model.Item;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.Slave;
@@ -66,21 +53,11 @@
@Tag("IntegrationTest")
@SuppressWarnings({"ClassDataAbstractionCoupling", "ClassFanOutComplexity", "SameParameterValue", "PMD.SystemPrintln", "PMD.GodClass", "PMD.ExcessiveClassLength", "PMD.ExcessiveImports", "PMD.CouplingBetweenObjects", "PMD.CyclomaticComplexity"})
public abstract class IntegrationTest extends ResourceTest {
- /** Issue log files will be renamed to mach this pattern. */
- private static final String FILE_NAME_PATTERN = "%s-issues.txt";
private static final Charset UTF_8 = StandardCharsets.UTF_8;
private static final String WINDOWS_FILE_ACCESS_READ_ONLY = "RX";
private static final String WINDOWS_FILE_DENY = "/deny";
- /** Determines whether JavaScript is enabled in the {@link WebClient}. */
- public enum JavaScriptSupport {
- /** JavaScript is disabled. */
- JS_ENABLED,
- /** JavaScript is enabled. */
- JS_DISABLED
- }
-
/**
* Returns the Jenkins rule to manage the Jenkins instance.
*
@@ -88,39 +65,6 @@ public enum JavaScriptSupport {
*/
protected abstract JenkinsRule getJenkins();
- /**
- * Returns a {@link WebClient} to access the HTML pages of Jenkins.
- *
- * @param javaScriptSupport
- * determines whether JavaScript is enabled in the {@link WebClient}
- *
- * @return the web client to use
- */
- protected abstract WebClient getWebClient(JavaScriptSupport javaScriptSupport);
-
- @SuppressFBWarnings(value = "LG", justification = "Setting the logger here helps to clean up the console log for tests")
- static WebClient create(final JenkinsRule jenkins, final boolean isJavaScriptEnabled) {
- WebClient webClient = jenkins.createWebClient();
- webClient.setCssErrorHandler(new SilentCssErrorHandler());
- java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(Level.SEVERE);
- webClient.setIncorrectnessListener((s, o) -> {
- });
-
- webClient.setJavaScriptEnabled(isJavaScriptEnabled);
- webClient.setJavaScriptErrorListener(new IntegrationTestJavaScriptErrorListener());
- webClient.setAjaxController(new NicelyResynchronizingAjaxController());
- webClient.getCookieManager().setCookiesEnabled(isJavaScriptEnabled);
- webClient.getOptions().setCssEnabled(isJavaScriptEnabled);
-
- webClient.getOptions().setDownloadImages(false);
- webClient.getOptions().setUseInsecureSSL(true);
- webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
- webClient.getOptions().setThrowExceptionOnScriptError(false);
- webClient.getOptions().setPrintContentOnFailingStatusCode(false);
-
- return webClient;
- }
-
/**
* Creates a file with the specified content in the workspace.
*
@@ -143,6 +87,65 @@ protected void createFileInWorkspace(final TopLevelItem job, final String fileNa
}
}
+ /**
+ * Copies the specified files to the workspace. The copied files will have the same file name in the workspace.
+ *
+ * @param job
+ * the job to get the workspace for
+ * @param fileNames
+ * the files to copy
+ */
+ protected void copyMultipleFilesToWorkspace(final TopLevelItem job, final String... fileNames) {
+ copyWorkspaceFiles(job, fileNames, file -> Paths.get(file).getFileName().toString());
+ }
+
+ /**
+ * Copies the specified file to the workspace.
+ *
+ * @param job
+ * the job to get the workspace for
+ * @param fileName
+ * the file to copy
+ */
+ protected void copySingleFileToWorkspace(final TopLevelItem job, final String fileName) {
+ FilePath workspace = getWorkspace(job);
+
+ copySingleFileToWorkspace(workspace, fileName, fileName);
+ }
+
+ /**
+ * Copies the specified files to the workspace. Uses the specified new file name in the workspace.
+ *
+ * @param job
+ * the job to get the workspace for
+ * @param from
+ * the file to copy
+ * @param to
+ * the file name in the workspace
+ */
+ protected void copySingleFileToWorkspace(final TopLevelItem job, final String from, final String to) {
+ FilePath workspace = getWorkspace(job);
+
+ copySingleFileToWorkspace(workspace, from, to);
+ }
+
+ /**
+ * Copies the specified files to the workspace. The file names of the copied files will be determined by the
+ * specified mapper.
+ *
+ * @param job
+ * the job to get the workspace for
+ * @param fileNames
+ * the files to copy
+ * @param fileNameMapper
+ * maps input file names to output file names
+ */
+ protected void copyWorkspaceFiles(final TopLevelItem job, final String[] fileNames,
+ final Function fileNameMapper) {
+ Arrays.stream(fileNames)
+ .forEach(fileName -> copySingleFileToWorkspace(job, fileName, fileNameMapper.apply(fileName)));
+ }
+
/**
* Returns the console log as a String.
*
@@ -261,6 +264,16 @@ protected String getAbsolutePathOfWorkspaceFile(final TopLevelItem job, final St
return new PathUtil().createAbsolutePath(getWorkspace(job).getRemote(), fileName);
}
+ private void copySingleFileToWorkspace(final FilePath workspace, final String from, final String to) {
+ try {
+ workspace.child(to).copyFrom(asInputStream(from));
+ System.out.format("Copying file '%s' as workspace file '%s'%n (workspace '%s')", from, to, workspace);
+ }
+ catch (IOException | InterruptedException e) {
+ throw new AssertionError(e);
+ }
+ }
+
/**
* Creates an {@link DumbSlave agent} with the specified label.
*
@@ -367,18 +380,6 @@ protected void copySingleFileToAgentWorkspace(final Slave agent, final TopLevelI
copyFileToWorkspace(workspace, from, to);
}
- /**
- * Creates a pre-defined filename for a workspace file.
- *
- * @param fileNamePrefix
- * prefix of the filename
- *
- * @return the whole file name of the workspace file
- */
- protected String createWorkspaceFileName(final String fileNamePrefix) {
- return String.format(FILE_NAME_PATTERN, FilenameUtils.getBaseName(fileNamePrefix));
- }
-
/**
* Creates a new {@link FreeStyleProject freestyle job}. The job will get a generated name.
*
@@ -470,9 +471,7 @@ protected CpsFlowDefinition asStage(final String... steps) {
}
/**
- * Creates an empty pipeline job and populates the workspace of that job with copies of the specified files. In
- * order to simplify the scanner pattern, all files follow the filename pattern in {@link
- * IntegrationTest#createWorkspaceFileName(String)}.
+ * Creates an empty pipeline job and populates the workspace of that job with copies of the specified files.
*
* @param fileNames
* the files to copy to the workspace
@@ -533,6 +532,22 @@ protected FlowDefinition readJenkinsFile(final String fileName) {
return buildWithResult(job, Result.SUCCESS);
}
+ /**
+ * Asserts that the builds result is equal to {@link Result#SUCCESS}.
+ *
+ * @param run
+ * the run to check
+ */
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ protected void assertSuccessfulBuild(final Run, ?> run) {
+ try {
+ getJenkins().assertBuildStatus(Result.SUCCESS, run);
+ }
+ catch (Exception exception) {
+ throw new AssertionError(exception);
+ }
+ }
+
/**
* Schedules a build for the specified job and waits for the job to finish. After the build has been finished the
* builds result is checked to be equals to {@code expectedResult}.
@@ -569,105 +584,20 @@ private void logJenkinsFile(final String script) {
}
/**
- * Clicks the specified DOM element and returns the HTML page content of the page that is the target of the link.
- *
- * @param element
- * the element that receives the click event
+ * Prints the console log of the specified build to StdOut.
*
- * @return the HTML page
- */
- protected HtmlPage clickOnLink(final DomElement element) {
- try {
- return element.click();
- }
- catch (IOException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Returns the HTML page content of the specified URL for a given job.
- *
- * @param javaScriptSupport
- * determines whether JavaScript is enabled in the {@link WebClient}
- * @param job
- * the job that owns the URL
- * @param relativeUrl
- * the relative URL within the job
- *
- * @return the HTML page
- */
- protected HtmlPage getWebPage(final JavaScriptSupport javaScriptSupport, final Item job, final String relativeUrl) {
- try {
- return getWebClient(javaScriptSupport).getPage(job, relativeUrl);
- }
- catch (SAXException | IOException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Returns the HTML page content of the specified job.
- *
- * @param javaScriptSupport
- * determines whether JavaScript is enabled in the {@link WebClient}
- * @param job
- * the job to show the page for
- *
- * @return the HTML page
- */
- protected HtmlPage getWebPage(final JavaScriptSupport javaScriptSupport, final Item job) {
- return getWebPage(javaScriptSupport, job, StringUtils.EMPTY);
- }
-
- /**
- * Returns the HTML page content of the specified build.
- *
- * @param javaScriptSupport
- * determines whether JavaScript is enabled in the {@link WebClient}
* @param build
- * the build to show the page for
- *
- * @return the HTML page
- */
- protected HtmlPage getWebPage(final JavaScriptSupport javaScriptSupport, final Run, ?> build) {
- return getWebPage(javaScriptSupport, build, StringUtils.EMPTY);
- }
-
- /**
- * Returns the HTML page content of the specified URL for a given build.
- *
- * @param javaScriptSupport
- * determines whether JavaScript is enabled in the {@link WebClient}
- * @param build
- * the build to show the page for
- * @param relativeUrl
- * the relative URL within the job
- *
- * @return the HTML page
- */
- protected HtmlPage getWebPage(final JavaScriptSupport javaScriptSupport, final Run, ?> build,
- final String relativeUrl) {
- try {
- return getWebClient(javaScriptSupport).getPage(build, relativeUrl);
- }
- catch (SAXException | IOException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Submit the supplied {@link HtmlForm}. Locates the submit element/button on the form.
- *
- * @param form
- * the {@link HtmlForm}
+ * the build
*/
- protected void submit(final HtmlForm form) {
- try {
- HtmlFormUtil.submit(form);
+ protected void printConsoleLog(final Run, ?> build) {
+ System.out.println("----- Console Log -----");
+ try (Reader reader = build.getLogReader()) {
+ try (BufferedReader bufferedReader = new BufferedReader(reader)) {
+ bufferedReader.lines().forEach(System.out::println);
+ }
}
- catch (IOException e) {
- throw new AssertionError(e);
+ catch (IOException exception) {
+ throw new AssertionError(exception);
}
}
@@ -795,24 +725,6 @@ protected String join(final String... arguments) {
return builder.toString();
}
- /**
- * Returns the model of a chart in the specified HTML page.
- *
- * @param page
- * the HTML page that contains the chart
- * @param id
- * the element ID of the chart placeholder (that has the EChart instance attached in property @{@code
- * echart}
- *
- * @return the model (as JSON representation)
- */
- protected String getChartModel(final HtmlPage page, final String id) {
- ScriptResult scriptResult = page.executeJavaScript(
- String.format("JSON.stringify(document.getElementById(\"%s\").echart.getOption());", id));
-
- return scriptResult.getJavaScriptResult().toString();
- }
-
/**
* Calls Jenkins remote API with the specified URL. Calls the JSON format.
*
@@ -846,78 +758,4 @@ protected Document callXmlRemoteApi(final String url) {
throw new AssertionError(e);
}
}
-
- @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"})
- private static class IntegrationTestJavaScriptErrorListener implements JavaScriptErrorListener {
- /**
- * Informs about a javascript exceptions.
- *
- * @param page
- * the page that causes the problem
- * @param scriptException
- * the occurred script exception
- */
- @Override
- public void scriptException(final HtmlPage page, final ScriptException scriptException) {
- System.out.println("A JavaScript exception occurred at: " + page.toString());
- scriptException.printStackTrace();
- }
-
- /**
- * Informs about a javascript timeout error.
- *
- * @param page
- * the page that causes the problem
- * @param allowedTime
- * the max time allowed for the execution
- * @param executionTime
- * the already consumed time
- */
- @Override
- public void timeoutError(final HtmlPage page, final long allowedTime, final long executionTime) {
- System.out.println("A JavaScript timeout occurred at: " + page.toString() + ". Allowed: "
- + allowedTime + " timed out after: " + executionTime);
- }
-
- /**
- * Informs about a malformed url referencing to to script.
- *
- * @param page
- * the page that causes the problem
- * @param url
- * the malformed url
- * @param malformedURLException
- * the occurred exception
- */
- @Override
- public void malformedScriptURL(final HtmlPage page, final String url,
- final MalformedURLException malformedURLException) {
- System.out.println("A JavaScript exception occurred at: " + page.toString()
- + ", due to the malformed URL: " + url);
- malformedURLException.printStackTrace();
- }
-
- /**
- * Informs about an exception during load of a javascript file refereed from a page.
- *
- * @param page
- * the page that causes the problem
- * @param scriptUrl
- * the url to load the script from
- * @param exception
- * the occurred exception
- */
- @Override
- public void loadScriptError(final HtmlPage page, final URL scriptUrl, final Exception exception) {
- System.out.println("A JavaScript exception occured at: " + page.toString()
- + ", while loading the file from the URL: " + scriptUrl.toString());
- exception.printStackTrace();
- }
-
- @Override
- public void warn(final String message, final String sourceName, final int line, final String lineSource,
- final int lineOffset) {
- // ignore warnings
- }
- }
}
diff --git a/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerSuite.java b/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerSuite.java
index cb894bd..9040b49 100644
--- a/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerSuite.java
+++ b/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerSuite.java
@@ -1,9 +1,7 @@
package io.jenkins.plugins.util;
-import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.JenkinsRule.WebClient;
/**
* Base class for integration tests in Jenkins. Sub classes will get a new and fresh Jenkins instance for each test
@@ -20,19 +18,4 @@ public abstract class IntegrationTestWithJenkinsPerSuite extends IntegrationTest
protected JenkinsRule getJenkins() {
return JENKINS_PER_SUITE;
}
-
- private static WebClient noJsWebClient;
- private static WebClient jsEnabledClient;
-
- /** Creates two web clients, one with and one without JS support. */
- @BeforeClass
- public static void createWebClients() {
- noJsWebClient = create(JENKINS_PER_SUITE, false);
- jsEnabledClient = create(JENKINS_PER_SUITE, true);
- }
-
- @Override
- protected WebClient getWebClient(final JavaScriptSupport javaScriptSupport) {
- return javaScriptSupport == JavaScriptSupport.JS_DISABLED ? noJsWebClient : jsEnabledClient;
- }
}
diff --git a/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerTest.java b/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerTest.java
index d44cd97..27ed28a 100644
--- a/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerTest.java
+++ b/src/test/java/io/jenkins/plugins/util/IntegrationTestWithJenkinsPerTest.java
@@ -1,9 +1,7 @@
package io.jenkins.plugins.util;
-import org.junit.Before;
import org.junit.Rule;
import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.JenkinsRule.WebClient;
/**
* Base class for integration tests in Jenkins. Sub classes will get a new and fresh Jenkins instance for each
@@ -20,19 +18,4 @@ public abstract class IntegrationTestWithJenkinsPerTest extends IntegrationTest
protected JenkinsRule getJenkins() {
return jenkinsPerTest;
}
-
- private WebClient noJsWebClient;
- private WebClient jsEnabledClient;
-
- /** Creates two web clients, one with and one without JS support. */
- @Before
- public void createWebClients() {
- noJsWebClient = create(jenkinsPerTest, false);
- jsEnabledClient = create(jenkinsPerTest, true);
- }
-
- @Override
- protected WebClient getWebClient(final JavaScriptSupport javaScriptSupport) {
- return javaScriptSupport == JavaScriptSupport.JS_DISABLED ? noJsWebClient : jsEnabledClient;
- }
}
diff --git a/src/test/java/io/jenkins/plugins/util/PageObject.java b/src/test/java/io/jenkins/plugins/util/PageObject.java
deleted file mode 100644
index af08c67..0000000
--- a/src/test/java/io/jenkins/plugins/util/PageObject.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.jenkins.plugins.util;
-
-import java.io.IOException;
-
-import com.gargoylesoftware.htmlunit.html.DomElement;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-
-/**
- * Parent class for all page objects. This base class just provides access to the underlying main page and to some
- * utility methods.
- *
- * @author Ullrich Hafner
- * @see Page Object pattern
- * @deprecated UI tests should use ATH plugin tests
- */
-@Deprecated
-public class PageObject {
- private final HtmlPage page;
-
- /**
- * Creates a page object for the given HTML page.
- *
- * @param page
- * the page that will be analyzed in tests
- */
- protected PageObject(final HtmlPage page) {
- this.page = page;
- }
-
- protected HtmlPage getPage() {
- return page;
- }
-
- /**
- * Returns the HTML page of this page object as plain text.
- *
- * @return the HTML page of this page object
- */
- public String getPageAsText() {
- return getPage().asText();
- }
-
- /**
- * Clicks the selected element.
- *
- * @param element
- * the element to click
- *
- * @return the resulting HTML page
- */
- public static HtmlPage clickOnElement(final DomElement element) {
- try {
- return element.click();
- }
- catch (IOException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Reloads the current page.
- */
- public void refresh() {
- try {
- getPage().refresh();
- }
- catch (IOException e) {
- throw new AssertionError("WebPage refresh failed.", e);
- }
- }
-}