diff --git a/pom.xml b/pom.xml
index fc57cd8..e2fc1f6 100755
--- a/pom.xml
+++ b/pom.xml
@@ -37,21 +37,21 @@
- 2.176.3
- 1.17
- 2.19
- 2.30
- 1.23
- 2.66
- 3.2
+ 2.277.4
+ 1.22
+ 2.23
+ 2.41
+ 1.49
+ 2.90
+ 3.7
1.7.1
2.0
1.25
- 1.56
- 1.19.0
- 1.20
+ 1.76
+ 1.25.0
+ 1.34
2.13
- 2.11.2
+ 2.40
2.6
8
@@ -62,7 +62,17 @@
https://www.github.com/jenkinsci/robot-plugin
robot-2.0.0
-
+
+
+
+ io.jenkins.tools.bom
+ bom-2.222.x
+ 10
+ import
+ pom
+
+
+
org.jenkins-ci.plugins
@@ -99,13 +109,13 @@
org.jenkins-ci.plugins.workflow
workflow-basic-steps
- ${workflow-basic-steps.version}
+
test
org.jenkins-ci.plugins.workflow
workflow-durable-task-step
- ${workflow-durable-task-step.version}
+
test
@@ -123,7 +133,7 @@
org.jenkins-ci.plugins
matrix-project
- ${matrix-project.version}
+
org.jenkins-ci.plugins
@@ -149,6 +159,95 @@
${mailer.version}
true
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+ org.jenkins-ci.plugins
+ jackson2-api
+ 2.12.3
+
+
+ org.jenkins-ci.plugins
+ display-url-api
+ 2.3.5
+
+
+ org.jenkins-ci.plugins
+ scm-api
+ 2.6.4
+
+
+ org.jenkins-ci.plugins
+ variant
+ 1.4
+
+
+ org.jenkins-ci.plugins
+ credentials
+ 2.3.17
+
+
+ org.jenkins-ci
+ symbol-annotation
+ 1.22
+
+
+ org.jenkins-ci.plugins
+ cloudbees-folder
+ 6.15
+
+
+ io.jenkins.plugins
+ snakeyaml-api
+ 1.27.0
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.30
+
+
+ org.slf4j
+ log4j-over-slf4j
+ 1.7.30
+
+
+ org.slf4j
+ slf4j-jdk14
+ 1.7.30
+ test
+
+
+ org.slf4j
+ jcl-over-slf4j
+ 1.7.30
+
+
+ org.ow2.asm
+ asm
+ 9.0
+
+
+ org.ow2.asm
+ asm-tree
+ 9.0
+
+
+ org.ow2.asm
+ asm-analysis
+ 9.0
+
+
+ org.ow2.asm
+ asm-util
+ 9.0
+
+
diff --git a/src/main/java/hudson/plugins/robot/RobotParser.java b/src/main/java/hudson/plugins/robot/RobotParser.java
index 21290a5..cb527ec 100644
--- a/src/main/java/hudson/plugins/robot/RobotParser.java
+++ b/src/main/java/hudson/plugins/robot/RobotParser.java
@@ -285,16 +285,24 @@ private RobotCaseResult processTest(XMLStreamReader reader, RobotSuiteResult res
StringBuilder stackTrace = new StringBuilder();
//parse stacktrace
- String xmlTag = ignoreUntilStarts(reader, "kw", "for", "if", "doc", "tags", "tag", "status");
- while (xmlTag.equals("kw") || xmlTag.equals("for") || xmlTag.equals("if")) {
- if (xmlTag.equals("if")) {
- stackTrace.append(processIf(reader, 0));
- } else if (xmlTag.equals("for")) {
- stackTrace.append(processForLoop(reader, 0));
- } else {
- stackTrace.append(processKeyword(reader, 0));
+ String[] possible_elements = {"kw", "for", "if", "try", "while", "doc", "tags", "tag", "status"};
+ String[] elements = {"kw", "for", "if", "try", "while"};
+ String xmlTag = ignoreUntilStarts(reader, possible_elements);
+ while (isNameInElements(xmlTag, elements)) {
+ switch (xmlTag) {
+ case "if":
+ case "try":
+ stackTrace.append(processBranchable(reader, 0));
+ break;
+ case "for":
+ case "while":
+ stackTrace.append(processLoop(reader, 0));
+ break;
+ default:
+ stackTrace.append(processKeyword(reader, 0));
+ break;
}
- xmlTag = ignoreUntilStarts(reader, "kw", "for", "if", "doc", "tags", "tag", "status");
+ xmlTag = ignoreUntilStarts(reader, possible_elements);
}
caseResult.setStackTrace(stackTrace.toString().trim().replaceAll("\n+", "\n"));
@@ -341,12 +349,16 @@ private RobotCaseResult processTest(XMLStreamReader reader, RobotSuiteResult res
return caseResult;
}
- private String processForLoop(XMLStreamReader reader, int nestedCount) throws XMLStreamException {
+ private String processLoop(XMLStreamReader reader, int nestedCount) throws XMLStreamException {
StringBuilder stackTrace = new StringBuilder();
String indentation = getSpacesPerNestedLevel(nestedCount);
- stackTrace.append(indentation + "FOR " + reader.getAttributeValue(null, "flavor"));
+ String kind = reader.getLocalName();
+ stackTrace.append(indentation + kind.toUpperCase());
+ if (kind.equals("for")) {
+ stackTrace.append(" " + reader.getAttributeValue(null, "flavor"));
+ }
while (reader.hasNext()) {
- if (reader.isEndElement() && reader.getLocalName().equals("for")) {
+ if (reader.isEndElement() && reader.getLocalName().equals(kind)) {
break;
}
if (reader.isStartElement() && reader.getLocalName().equals("iter")) {
@@ -366,14 +378,25 @@ private String processIteration(XMLStreamReader reader, int nestedCount) throws
}
if (reader.isStartElement()) {
String xmlTag = reader.getLocalName();
- if (xmlTag.equals("for")) {
- stackTrace.append(processForLoop(reader, nestedCount));
- }
- if (xmlTag.equals("kw")) {
- stackTrace.append(processKeyword(reader, nestedCount));
- }
- if (xmlTag.equals("if")) {
- stackTrace.append(processIf(reader, nestedCount));
+ switch (xmlTag) {
+ case "for":
+ case "while":
+ stackTrace.append(processLoop(reader, nestedCount));
+ break;
+ case "kw":
+ stackTrace.append(processKeyword(reader, nestedCount));
+ break;
+ case "if":
+ case "try":
+ stackTrace.append(processBranchable(reader, nestedCount));
+ break;
+ case "return":
+ case "break":
+ case "continue":
+ stackTrace.append(processReturnBreakContinue(reader, nestedCount));
+ break;
+ default:
+ break;
}
}
reader.next();
@@ -382,11 +405,12 @@ private String processIteration(XMLStreamReader reader, int nestedCount) throws
return stackTrace.toString();
}
- private String processIf(XMLStreamReader reader, int nestedCount) throws XMLStreamException {
+ private String processBranchable(XMLStreamReader reader, int nestedCount) throws XMLStreamException {
StringBuilder stackTrace = new StringBuilder();
String indentation = getSpacesPerNestedLevel(nestedCount);
+ String kind = reader.getLocalName();
while (reader.hasNext()) {
- if (reader.isEndElement() && reader.getLocalName().equals("if")) {
+ if (reader.isEndElement() && reader.getLocalName().equals(kind)) {
break;
}
if (reader.isStartElement() && reader.getLocalName().equals("branch")) {
@@ -407,14 +431,25 @@ private String processBranch(XMLStreamReader reader, int nestedCount) throws XML
}
if (reader.isStartElement()) {
String xmlTag = reader.getLocalName();
- if (xmlTag.equals("for")) {
- stackTrace.append(processForLoop(reader, nestedCount));
- }
- if (xmlTag.equals("kw")) {
- stackTrace.append(processKeyword(reader, nestedCount));
- }
- if (xmlTag.equals("if")) {
- stackTrace.append(processIf(reader, nestedCount));
+ switch (xmlTag) {
+ case "for":
+ case "while":
+ stackTrace.append(processLoop(reader, nestedCount));
+ break;
+ case "kw":
+ stackTrace.append(processKeyword(reader, nestedCount));
+ break;
+ case "if":
+ case "try":
+ stackTrace.append(processBranchable(reader, nestedCount));
+ break;
+ case "return":
+ case "break":
+ case "continue":
+ stackTrace.append(processReturnBreakContinue(reader, nestedCount));
+ break;
+ default:
+ break;
}
}
reader.next();
@@ -440,13 +475,20 @@ private String processKeyword(XMLStreamReader reader, int nestedCount) throws XM
stackTrace.append(processArgs(reader));
continue; // processArgs returns with us already in . We don't want to use reader.next()
case "for":
- stackTrace.append(processForLoop(reader, nestedCount+1));
+ case "while":
+ stackTrace.append(processLoop(reader, nestedCount+1));
break;
case "kw":
stackTrace.append(processKeyword(reader, nestedCount+1));
break;
case "if":
- stackTrace.append(processIf(reader, nestedCount+1));
+ case "try":
+ stackTrace.append(processBranchable(reader, nestedCount+1));
+ break;
+ case "return":
+ case "break":
+ case "continue":
+ stackTrace.append(processReturnBreakContinue(reader, nestedCount+1));
break;
default:
break;
@@ -500,6 +542,22 @@ private List processTags(XMLStreamReader reader) throws XMLStreamExcepti
return tagList;
}
+ private String processReturnBreakContinue(XMLStreamReader reader, int nestedCount) throws XMLStreamException {
+ StringBuilder stringBuilder = new StringBuilder();
+ String kind = reader.getLocalName();
+ stringBuilder.append(getSpacesPerNestedLevel(nestedCount)).append(kind.toUpperCase());
+ while(reader.hasNext()) {
+ if (reader.isEndElement() && reader.getLocalName().equals(kind)) {
+ break;
+ }
+ if (reader.isStartElement() && reader.getLocalName().equals("kw")) {
+ stringBuilder.append(processKeyword(reader, nestedCount+1));
+ }
+ reader.next();
+ }
+ return stringBuilder.toString();
+ }
+
private static void setCriticalityIfAvailable(XMLStreamReader reader, RobotCaseResult caseResult) {
String criticality = reader.getAttributeValue(null, "critical");
if (criticality != null) {
diff --git a/src/test/java/hudson/plugins/robot/RobotParserTest.java b/src/test/java/hudson/plugins/robot/RobotParserTest.java
index 5c358ca..765c591 100644
--- a/src/test/java/hudson/plugins/robot/RobotParserTest.java
+++ b/src/test/java/hudson/plugins/robot/RobotParserTest.java
@@ -183,6 +183,16 @@ public void testRobot4If() {
final String dir = ".";
final String mask = "robot4_if_output.xml";
parse(dir, mask);
+ }
+ /** Robot Framework 5.0 introduced TRY-EXCEPT, WHILE,
+ * BREAK, and CONTINUE. The output file contains simple
+ * test cases which use new features.
+ */
+ @Test
+ public void testRobot5TryExceptFinallyWhileContinue() {
+ final String dir = "robot5";
+ final String mask = "basic_new_features_output.xml";
+ parse(dir, mask);
}
}
diff --git a/src/test/resources/hudson/plugins/robot/robot5/basic_new_features_output.xml b/src/test/resources/hudson/plugins/robot/robot5/basic_new_features_output.xml
new file mode 100644
index 0000000..592117b
--- /dev/null
+++ b/src/test/resources/hudson/plugins/robot/robot5/basic_new_features_output.xml
@@ -0,0 +1,438 @@
+
+
+
+
+
+
+
+mikki
+hiiri
+
+${arg1}
+${arg2}
+Fails if the given objects are unequal.
+mikki != hiiri
+
+
+
+
+
+
+
+
+Error caught
+Logs the given message with the given level.
+Error caught
+
+
+
+
+
+
+
+
+
+
+
+
+mikki
+mikki
+
+${arg1}
+${arg2}
+Fails if the given objects are unequal.
+
+
+
+
+
+
+
+
+Fails the test with the given message and optionally alters its tags.
+
+
+
+
+
+
+Some message
+Logs the given message with the given level.
+Some message
+
+
+
+
+
+
+
+
+
+
+${x}
+5
+Returns the given values which can then be assigned to a variables.
+${x} = 5
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+5
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 4
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+4
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 3
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+3
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 2
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+2
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 1
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+1
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 0
+
+
+
+
+
+
+
+
+
+
+${x}
+5
+Returns the given values which can then be assigned to a variables.
+${x} = 5
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+5
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+4
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+3
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+5
+Returns the given values which can then be assigned to a variables.
+${x} = 5
+
+
+
+${y}
+${x}
+
+${result}
+${arg1}-1
+Evaluates the given expression in Python and returns the result.
+${result} = 4
+
+
+
+${result}
+
+
+
+This should not be executed
+Fails the test with the given message and optionally alters its tags.
+
+
+${y} = 4
+
+
+
+${y}
+Logs the given message with the given level.
+4
+
+
+
+
+
+
+${x}
+5
+Returns the given values which can then be assigned to a variables.
+${x} = 5
+
+
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 4
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+
+
+
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 3
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+3
+
+
+
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 2
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+
+
+
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 1
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+1
+
+
+
+
+
+
+${x}
+${x}-1
+Evaluates the given expression in Python and returns the result.
+${x} = 0
+
+
+
+
+
+
+
+
+
+
+
+
+${x}
+Logs the given message with the given level.
+
+
+
+
+
+
+
+
+
+
+
+
+All Tests
+
+
+
+
+Test
+
+
+
+
+