├── .github └── workflows │ ├── codeql-analysis.yml │ └── maven.yml ├── .gitignore ├── BUILD.md ├── README.md ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── robotframework │ │ └── mavenplugin │ │ ├── AbstractMojoWithLoadedClasspath.java │ │ ├── AcceptanceTestMojo.java │ │ ├── Arguments.java │ │ ├── ExternalRunnerConfiguration.java │ │ ├── LibDocConfiguration.java │ │ ├── LibDocMojo.java │ │ ├── PythonRunner.java │ │ ├── RebotMojo.java │ │ ├── RobotFrameworkMojo.java │ │ ├── RobotMojoClassLoader.java │ │ ├── TestDocConfiguration.java │ │ ├── TestDocMojo.java │ │ ├── VerifyMojo.java │ │ └── harvesters │ │ ├── AntPatternClassPredicate.java │ │ ├── ClassNameHarvester.java │ │ ├── HarvestUtils.java │ │ ├── NameHarvester.java │ │ ├── ResourceNameHarvester.java │ │ └── SourceFileNameHarvester.java └── resources │ └── org │ └── robotframework │ └── mavenplugin │ └── robotframework-report.properties ├── site ├── apt │ ├── examples │ │ ├── javalibraries.apt │ │ └── seleniumlibrary.apt │ ├── index.apt │ └── transitioning.apt └── site.xml └── test ├── java └── org │ └── robotframework │ └── mavenplugin │ ├── AbstractRFMojoTestCase.java │ ├── AcceptanceTestAndVerifyMojoIT.java │ ├── AcceptanceTestMojoTest.java │ ├── ArgumentsTest.java │ ├── ExampleLib.java │ ├── LibDocMojoTest.java │ ├── RebotMojoTest.java │ ├── RobotFrameworkMojoTest.java │ ├── RobotFrameworkSkipTest.java │ ├── TestDocMojoTest.java │ ├── VerifyMojoTest.java │ └── harvesters │ ├── A.java │ ├── AntPatternClassPredicateTest.java │ ├── B.java │ ├── ClassNameHarvesterTest.java │ ├── HarvestUtilsTest.java │ ├── ResourceNameHarvesterTest.java │ └── SourceFileNameHarvesterTest.java ├── projects └── acceptance-and-verify │ ├── pom.xml │ ├── pom_with_classpaths.xml │ ├── pom_with_external_runner.xml │ ├── pom_with_noncritical_failures.xml │ ├── pom_with_tests_configured.xml │ ├── pom_without_classpaths.xml │ └── src │ └── test │ └── robotframework │ ├── acceptance │ ├── anotherSuccessfulTest.robot │ ├── failingTest.robot │ ├── lib.py │ ├── secondFailingTest.robot │ └── successfulTest.robot │ └── classpath-acceptance │ └── classpathTests.robot └── resources ├── files ├── embed1 │ ├── resourcesA.txt │ └── test.java ├── embed2 │ └── test2.txt ├── resources.txt └── test.txt ├── output-for-rebot ├── output-rebot-20181115-081427.xml └── output-rebot-20181115-081428.xml ├── pom-configure-runner.xml ├── pom-error.xml ├── pom-fail.xml ├── pom-hsqldb.xml ├── pom-libdoc-libraryname-java.xml ├── pom-libdoc-libraryname-python-subpackage.xml ├── pom-libdoc-libraryname-python.xml ├── pom-libdoc-robotfile.xml ├── pom-libdoc.xml ├── pom-rebot-merged.xml ├── pom-rebot.xml ├── pom-runmodes.xml ├── pom-success.xml ├── pom-testdoc-robotfile-doc.xml ├── pom-testdoc-robotfile-name.xml ├── pom-testdoc-robotfile-title.xml ├── pom-testdoc-robotfile.xml ├── python ├── DatabaseLibrary │ ├── __init__.py │ ├── assertion.py │ ├── connection_manager.py │ ├── manipulation.py │ └── query.py └── jaydebeapi │ ├── __init__.py │ └── dbapi2.py ├── robot-external └── successfulTest.robot ├── robot-fail ├── failingTest.robot └── secondFailingTest.robot ├── robot-hsqldb └── hsqldb.robot ├── robot-libdoc-folder-only └── html_resource.robot ├── robot-libdoc-libraryname ├── mylib.py └── mypackage │ ├── __init__.py │ └── mylib.py ├── robot-libdoc ├── html_resource.robot ├── invalid_login.robot └── valid_login.robot ├── robot-success ├── anotherSuccessfulTest.robot └── successfulTest.robot ├── robot-testdoc └── invalid_login.robot └── xunitresults ├── TEST-nothing-here.xml ├── TEST-robot-fail.xml └── TEST-robot-success.xml /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ develop, gh-pages, master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ develop ] 20 | schedule: 21 | - cron: '35 7 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java', 'python' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build_and_test: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | # test against LTS java versions: 11 | java: [ 8, 11 ] 12 | name: Test with Java ${{ matrix.java }} 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up JDK ${{ matrix.java }} 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: ${{ matrix.java }} 19 | - name: Build with Maven 20 | run: mvn -B verify --file pom.xml 21 | release: 22 | needs: [build_and_test] 23 | if: github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/') 24 | runs-on: ubuntu-latest 25 | name: Release package 26 | steps: 27 | - uses: actions/checkout@v2 28 | - name: Set up JDK 29 | uses: actions/setup-java@v1 30 | with: 31 | java-version: 8 32 | - name: Release Maven package 33 | uses: samuelmeuli/action-maven-publish@201a45a3f311b2ee888f252ba9f4194257545709 #v1.4.0 34 | with: 35 | gpg_private_key: ${{ secrets.gpg_private_key }} 36 | gpg_passphrase: ${{ secrets.gpg_passphrase }} 37 | nexus_username: ${{ secrets.nexus_username }} 38 | nexus_password: ${{ secrets.nexus_password }} 39 | maven_args: -DskipTests 40 | - name: Publish site 41 | if: startsWith(github.ref, 'refs/tags/') 42 | run: mvn clean site -Dgithub.site.password=${{ secrets.github_site_password }} -Dgithub.site.userName=${{ secrets.github_site_username }} 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .idea 3 | *.iws 4 | *.iml 5 | *.ipr 6 | *$py.class 7 | .DS_store 8 | src/test/projects/acceptance-and-verify/log.txt 9 | docs/_build 10 | .classpath 11 | .settings/ 12 | .project 13 | .factorypath 14 | .vscode -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | Branches 2 | ======== 3 | 4 | `master` = "Release" branch, contains always version that's release to Maven Central 5 | 6 | `develop` = Developent time branch. All PRs should be targetted (and usually also started) from here. 7 | 8 | `gh-pages` = Github internal branch containing 9 | 10 | Building 11 | ======== 12 | 13 | To run the unit tests, execute goal: 14 | ```bash 15 | mvn test 16 | ``` 17 | To run all tests, including the integration tests: 18 | ```bash 19 | mvn verify 20 | ``` 21 | To install the plugin locally: 22 | ```bash 23 | mvn install 24 | ``` 25 | To generate the documentation: 26 | ```bash 27 | mvn site:site 28 | ``` 29 | 30 | Releasing 31 | ========= 32 | 33 | * update the version numbers, first the pom, then from other files and docs. 34 | 35 | osx: 36 | ```bash 37 | grep -rl 'sion>2.1.02.1.02.1.12.1.02.1.02.1.1 89 | 90 | github 91 | GitHubLogin 92 | GitHubPassw0rd 93 | 94 | 95 | ``` 96 | 97 | then: 98 | 99 | ```bash 100 | mvn site 101 | ``` 102 | Deploy project to Sonatype 103 | -------------------------- 104 | 105 | As a prerequisite, you need account at Sonatype Jira, gpg keys, and Sonatype servers configured to your settings.xml. 106 | See https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide 107 | 108 | ```bash 109 | mvn deploy -Pdeploy 110 | ``` 111 | Then do close and release from Staging Repository at https://oss.sonatype.org/index.html#welcome 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MavenPlugin 2 | =========== 3 | 4 | Maven plugin for using the Robot Framework. Goal of this plugin is to be able to use Robot Framework in a Maven project 5 | without the need to install anything extra (e.g. Robot Framework, Jython, etc). In short, it's a non-invasive way of 6 | introducing acceptance test driven development to your existing projects quickly. 7 | 8 | Plugin documentation is available at http://robotframework.github.com/MavenPlugin/ 9 | 10 | > This project was forked from http://code.google.com/p/robotframework-maven-plugin 11 | > in order to be able to make backwards incompatible changes to configuration. 12 | 13 | Maven Goals 14 | ----------- 15 | 16 | The plugin currently has three goals: 17 | 18 | * run - behaves like invoking the "jybot" Robot Framework command for executing test cases 19 | * libdoc - invokes the "libdoc.py" Robot Framework command for generating keyword documentation for test libraries and resource files 20 | * testdoc - invokes the "testdoc.py" Robot Framework command for generating high level documentation based on test cases 21 | 22 | Quick Start 23 | ----------- 24 | 25 | Add the plugin to your build: 26 | 27 | ```xml 28 | 29 | 30 | 31 | .. 32 | .. 33 | 34 | .. 35 | .. 36 | 37 | 38 | org.robotframework 39 | robotframework-maven-plugin 40 | 2.1.0 41 | 42 | 43 | 44 | run 45 | 46 | 47 | 48 | 49 | 50 | .. 51 | .. 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | By default, you can add your test cases to ${project.basedir}/src/test/robotframework/acceptance 59 | 60 | Third party libraries (e.g. Selenium Library) can be added to ${project.basedir}/src/test/resources/robotframework/libraries 61 | 62 | During mvn install invocation, run command will be invoked during the integration-test phase. 63 | 64 | For more detailed documentation please see http://robotframework.github.com/MavenPlugin/ 65 | 66 | *NOTE*: If needing plugin with Java 1.7, latest version supporting that is 1.4.9 67 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/AbstractMojoWithLoadedClasspath.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import org.apache.maven.plugin.AbstractMojo; 21 | import org.apache.maven.plugin.MojoExecutionException; 22 | import org.apache.maven.plugin.MojoFailureException; 23 | import org.python.util.PythonInterpreter; 24 | 25 | import java.io.File; 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | import java.util.*; 29 | 30 | public abstract class AbstractMojoWithLoadedClasspath 31 | extends AbstractMojo { 32 | 33 | private static RobotMojoClassLoader currentMojoLoader; 34 | private static String ROBOT_ARTIFACT = join(File.separator, "org", "robotframework", "robotframework"); 35 | 36 | /** 37 | * @parameter property="project.testClasspathElements" 38 | * @required 39 | * @readonly 40 | */ 41 | private List classpathElements; 42 | 43 | /** 44 | * @parameter property="settings.localRepository" 45 | * @required 46 | * @readonly 47 | */ 48 | private String localRepository; 49 | 50 | /** 51 | *

Test are executed in a new process if this configuration is used.

52 | *

The classpath for the new process will include by default all the test 53 | * scope dependencies from the pom.

54 | * 55 | * 63 | * 64 | * Example: 65 | *
{@code 
 66 |      *      
 67 |      *          bar
 68 |      *          this-should-be-seen-by-external-process.jar
 69 |      *      
 70 |      *      
 71 |      *          -XX:PermSize=128m
 72 |      *          -XX:MaxPermSize=256m
 73 |      *          -Xmx512m
 74 |      *      
 75 |      *      true
 76 |      *      org.robotframework.RobotFramework
 77 |      *      false
 78 |      * }
79 | * @parameter 80 | */ 81 | protected ExternalRunnerConfiguration externalRunner; 82 | 83 | public void execute() 84 | throws MojoExecutionException, MojoFailureException { 85 | loadClassPath(); 86 | subclassExecute(); 87 | } 88 | 89 | protected abstract void subclassExecute() 90 | throws MojoExecutionException, MojoFailureException; 91 | 92 | private void loadClassPath() 93 | throws MojoExecutionException { 94 | List urls = new ArrayList(); 95 | 96 | if (classpathElements != null) { 97 | for (String element : classpathElements) { 98 | File elementFile = new File(element); 99 | try { 100 | urls.add(elementFile.toURI().toURL()); 101 | } catch (MalformedURLException e) { 102 | throw new MojoExecutionException("Classpath loading error: " + element); 103 | } 104 | } 105 | } 106 | 107 | if (urls.size() > 0) { 108 | updateMojoLoader(urls); 109 | Thread.currentThread().setContextClassLoader(currentMojoLoader); 110 | } 111 | } 112 | 113 | protected String getClassPathString() { 114 | if (localRepository ==null || classpathElements==null) { 115 | // when executed outside of maven (like in unit tests) 116 | return System.getProperty("java.class.path"); 117 | } 118 | String result= getRobotJar(); 119 | for (String elem: classpathElements) { 120 | result +=File.pathSeparator + elem; 121 | } 122 | return result; 123 | } 124 | 125 | protected String getRobotJar() { 126 | File robots = new File(localRepository, ROBOT_ARTIFACT); 127 | String configured = currentVersion(); 128 | return join(File.separator, robots.toString(), configured, "robotframework-"+configured+".jar"); 129 | } 130 | 131 | static String currentVersion() { 132 | PythonInterpreter interp = new PythonInterpreter(); 133 | try { 134 | interp.exec("from robot import version"); 135 | interp.exec("rf_version = version.VERSION"); 136 | return interp.get("rf_version").toString(); 137 | } finally { 138 | interp.cleanup(); 139 | } 140 | } 141 | 142 | protected static String join(String joiner, String... elements) { 143 | StringBuilder result = new StringBuilder(); 144 | for (String elem: elements) { 145 | result.append(elem).append(joiner); 146 | } 147 | return result.substring(0, result.length()-joiner.length()); 148 | } 149 | 150 | private void updateMojoLoader(List urls) { 151 | if (currentMojoLoader==null) 152 | currentMojoLoader = new RobotMojoClassLoader(urls.toArray(new URL[0]), getClass().getClassLoader()); 153 | else 154 | currentMojoLoader.append(urls); 155 | } 156 | 157 | public File makeAbsolute(File folder, File file) { 158 | final File output; 159 | if (file.isAbsolute()) { 160 | output = file; 161 | } else { 162 | output = new File(folder, file.getName()); 163 | } 164 | return output; 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/Arguments.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import org.codehaus.plexus.util.StringUtils; 21 | import java.io.File; 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.List; 25 | 26 | 27 | public class Arguments { 28 | 29 | private final List arguments = new ArrayList(); 30 | 31 | 32 | public void addFileToArguments(File file, String flag) { 33 | if (isFileValid(file)) { 34 | String path = !file.getName().toUpperCase().equals("NONE") ? file.getPath() : file.getName(); 35 | add(flag, path); 36 | } 37 | } 38 | 39 | protected boolean isFileValid(File file) { 40 | return file != null && file.getPath() != null && !file.getPath().equals(""); 41 | } 42 | 43 | public void addNonEmptyStringToArguments(String variableToAdd, String flag) { 44 | if (!StringUtils.isEmpty(variableToAdd)) { 45 | addStringToArguments(variableToAdd, flag); 46 | } 47 | } 48 | 49 | public void addFlagToArguments( boolean flag, String argument) { 50 | if (flag == true) { 51 | add(argument); 52 | } 53 | } 54 | 55 | public void addStringToArguments(String variableToAdd, String flag) { 56 | add(flag, variableToAdd); 57 | } 58 | 59 | public void addListToArguments(String variablesToAdd, String flag) { 60 | if (variablesToAdd == null) { 61 | return; 62 | } 63 | addListToArguments(new ArrayList(Arrays.asList(StringUtils.split(variablesToAdd, ","))), flag); 64 | } 65 | 66 | public void addListToArguments(List variablesToAdd, String flag) { 67 | if (variablesToAdd == null) { 68 | return; 69 | } 70 | for (String variableToAdd : variablesToAdd) { 71 | if (!StringUtils.isEmpty(variableToAdd)) { 72 | add(flag, variableToAdd); 73 | } 74 | } 75 | } 76 | 77 | public void addFileListToArguments( List variablesToAdd, String flag) { 78 | if (variablesToAdd == null) { 79 | return; 80 | } 81 | for (File variableToAdd : variablesToAdd) { 82 | addFileToArguments(variableToAdd, flag); 83 | } 84 | } 85 | 86 | public void add(String... values) { 87 | for (String value:values) 88 | arguments.add(value); 89 | } 90 | 91 | public String[] toArray() { 92 | return arguments.toArray(new String[arguments.size()]); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/ExternalRunnerConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | public class ExternalRunnerConfiguration { 25 | 26 | /** 27 | * Environment variables for the new runner process. 28 | * 29 | * @parameter 30 | */ 31 | private Map environmentVariables; 32 | 33 | /** 34 | * Exclude dependencies from classpath. 35 | * 36 | * @parameter default-value="false" 37 | */ 38 | private boolean excludeDependencies; 39 | 40 | /** 41 | * Execute with pure Python (needs to be available when running). 42 | * 43 | * @parameter default-value="false" 44 | */ 45 | private boolean runWithPython; 46 | 47 | /** 48 | * Runner class to start test run. 49 | * 50 | * @parameter default-value="org.robotframework.RobotFramework" 51 | */ 52 | private String runnerClass; 53 | 54 | public Map getEnvironmentVariables() { 55 | return environmentVariables != null ? environmentVariables : Collections.EMPTY_MAP; 56 | } 57 | public boolean getExcludeDependencies() { 58 | return excludeDependencies; 59 | } 60 | 61 | public boolean getRunWithPython() { 62 | return runWithPython; 63 | } 64 | 65 | public String getRunnerClass() { 66 | return runnerClass; 67 | } 68 | 69 | /** 70 | * JVM arguments for the new runner process. 71 | * 72 | * @parameter 73 | */ 74 | private List jvmArgs; 75 | 76 | public List getJvmArgs() { 77 | if(jvmArgs==null){ 78 | return Collections.emptyList(); 79 | } else { 80 | return jvmArgs; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/LibDocConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.Collections; 25 | import java.util.List; 26 | import java.util.Set; 27 | 28 | import org.codehaus.plexus.util.StringUtils; 29 | import org.robotframework.mavenplugin.harvesters.ClassNameHarvester; 30 | import org.robotframework.mavenplugin.harvesters.HarvestUtils; 31 | import org.robotframework.mavenplugin.harvesters.ResourceNameHarvester; 32 | import org.robotframework.mavenplugin.harvesters.SourceFileNameHarvester; 33 | 34 | public class LibDocConfiguration { 35 | 36 | public List generateRunArguments(File projectBaseDir) { 37 | ArrayList result = new ArrayList(); 38 | 39 | // Phase I - harvest the files/classes/resources, if any 40 | ArrayList fileArguments = harvestResourceOrFileCandidates(projectBaseDir, libraryOrResourceFile); 41 | 42 | // Phase II - prepare the argument lines for the harvested 43 | // files/classes/resources. 44 | boolean multipleOutputs = fileArguments.size() > 1; // with single 45 | // argument line, we 46 | // can use the 47 | // original single 48 | // entity 49 | // parameters, so 50 | // use this flag to 51 | // switch. 52 | for (String fileArgument : fileArguments) { 53 | Arguments generatedArguments = generateLibdocArgumentList(projectBaseDir, multipleOutputs, fileArgument); 54 | result.add(generatedArguments.toArray()); 55 | } 56 | return result; 57 | } 58 | 59 | private Arguments generateLibdocArgumentList(File projectBaseDir, boolean multipleOutputs, String fileArgument) { 60 | Arguments result = new Arguments(); 61 | result.add("libdoc"); 62 | if (multipleOutputs) { 63 | // Derive the name from the input. 64 | result.addNonEmptyStringToArguments(HarvestUtils.extractName(fileArgument), "--name"); 65 | } else { 66 | // Preserve the original single-file behavior. 67 | result.addNonEmptyStringToArguments(name, "--name"); 68 | } 69 | result.addNonEmptyStringToArguments(version, "--version"); 70 | result.addFileListToArguments(getExtraPathDirectoriesWithDefault(), "--pythonpath"); 71 | result.add(fileArgument); 72 | 73 | if (multipleOutputs) { 74 | // Derive the output file name id from the source and from the 75 | // output file given. 76 | String normalizedArgument; 77 | // Generate a unique name. 78 | if (HarvestUtils.isAbsolutePathFragment(fileArgument)) { 79 | // Cut out the project directory, so that we have shorter id 80 | // names. 81 | // TODO - perhaps later, we can preserve the directory structure 82 | // relative to the output directory. 83 | normalizedArgument = HarvestUtils.removePrefixDirectory(projectBaseDir, fileArgument); 84 | } else { 85 | normalizedArgument = fileArgument; 86 | } 87 | result.add(outputDirectory + File.separator + HarvestUtils.generateIdName(normalizedArgument) 88 | + HarvestUtils.extractExtension(outputFile.getName())); 89 | } else { 90 | // Preserve original single-file behavior. 91 | if (outputFile.getName().contains("*")) { 92 | // We deal with a pattern, so we need to get the name from the 93 | // input file. 94 | File tf = new File(fileArgument); 95 | result.add(outputDirectory + File.separator + tf.getName() 96 | + HarvestUtils.extractExtension(outputFile.getName())); 97 | } else { 98 | // Use the output name directly. 99 | result.add(outputDirectory + File.separator + outputFile.getName()); 100 | } 101 | } 102 | return result; 103 | } 104 | 105 | private ArrayList harvestResourceOrFileCandidates(File projectBaseDir, String pattern) { 106 | File libOrResource = new File(pattern); 107 | ArrayList fileArguments = new ArrayList(); 108 | if (libOrResource.isFile()) { 109 | // Single file specification, no patterns. 110 | fileArguments.add(libOrResource.getAbsolutePath()); 111 | } else { 112 | // Possible pattern, process further. 113 | if (HarvestUtils.hasDirectoryStructure(pattern)) { 114 | // Directory structure, no class resolution, harvest file names. 115 | SourceFileNameHarvester harv = new SourceFileNameHarvester(projectBaseDir); 116 | fileArguments.addAll(harv.harvest(pattern)); 117 | } else { 118 | // A) May have files, try for harvesting file names first. 119 | SourceFileNameHarvester harv = new SourceFileNameHarvester(projectBaseDir); 120 | Set harvested = harv.harvest(pattern); 121 | if (harvested.size() > 0) { 122 | fileArguments.addAll(harvested); 123 | } else { 124 | // B) If no files found, try harvesting classes. 125 | ClassNameHarvester charv = new ClassNameHarvester(); 126 | harvested = charv.harvest(pattern); 127 | if (harvested.size() > 0) { 128 | fileArguments.addAll(harvested); 129 | } else { 130 | // C) If no files found, try harvesting resources. 131 | ResourceNameHarvester rharv = new ResourceNameHarvester(); 132 | fileArguments.addAll(rharv.harvest(pattern)); 133 | } // resources 134 | } // classes 135 | } // files 136 | } // single file or pattern 137 | return fileArguments; 138 | } 139 | 140 | private List getExtraPathDirectoriesWithDefault() { 141 | if (extraPathDirectories == null) { 142 | return Collections.singletonList(defaultExtraPath); 143 | } else { 144 | return Arrays.asList(extraPathDirectories); 145 | } 146 | } 147 | 148 | public void ensureOutputDirectoryExists() throws IOException { 149 | if (outputDirectory == null) { 150 | String baseDir = System.getProperty("basedir"); 151 | // FIXME: this is to get around the problem that default-value does 152 | // not currently work 153 | if (baseDir == null) 154 | baseDir = "."; 155 | outputDirectory = new File(joinPaths(baseDir, "target", "robotframework", "libdoc")); 156 | } 157 | if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { 158 | throw new IOException("Target output directory cannot be created: " + outputDirectory.getAbsolutePath()); 159 | } 160 | } 161 | 162 | private String joinPaths(String... parts) { 163 | return StringUtils.join(parts, File.separator); 164 | } 165 | 166 | public void populateDefaults(LibDocMojo defaults) { 167 | if (this.outputDirectory == null) 168 | this.outputDirectory = defaults.defaultLibdocOutputDirectory; 169 | this.defaultExtraPath = defaults.libdocDefaultExtraPath; 170 | } 171 | 172 | /** 173 | * Specifies the directory where documentation files are written. Considered 174 | * to be relative to the ${basedir} of the project. 175 | */ 176 | private File outputDirectory; 177 | 178 | /** 179 | * Specifies the filename of the created documentation. Considered to be 180 | * relative to the {@link #outputDirectory} of the project. 181 | */ 182 | private File outputFile; 183 | 184 | /** 185 | * Sets the name of the documented library or resource. 186 | */ 187 | private String name; 188 | 189 | /** 190 | * Sets the version of the documented library or resource. 191 | */ 192 | private String version; 193 | 194 | /** 195 | * Name or path of the documented library or resource file. 196 | *

197 | * Name must be in the same format as when used in Robot Framework test 198 | * data, for example BuiltIn or 199 | * com.acme.FooLibrary. When name is used, the library is 200 | * imported the same as when running the tests. Use 201 | * {@link #extraPathDirectories} to set PYTHONPATH/CLASSPATH accordingly. 202 | *

203 | * Paths are considered relative to the location of pom.xml and 204 | * must point to a valid Python/Java source file or a resource file. For 205 | * example src/main/java/com/test/ExampleLib.java 206 | * 207 | * One may also use ant-like patterns, for example 208 | * src/main/java/com/**{@literal /}*Lib.java 209 | * 210 | */ 211 | private String libraryOrResourceFile; 212 | 213 | /** 214 | * A directory to be added to the PYTHONPATH/CLASSPATH when creating 215 | * documentation. 216 | *

217 | * e.g. src/main/java/com/test/ 218 | */ 219 | private File[] extraPathDirectories; 220 | 221 | private File defaultExtraPath; 222 | } 223 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/LibDocMojo.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.util.List; 23 | 24 | import org.apache.maven.plugin.MojoExecutionException; 25 | import org.apache.maven.plugin.MojoFailureException; 26 | import org.robotframework.RobotFramework; 27 | 28 | /** 29 | * Create documentation of test libraries or resource files using the Robot Framework libdoc tool. 30 | * 31 | * Uses the libdoc bundled in Robot Framework jar distribution. For more help see 32 | * libdoc documentation. 33 | * 34 | * @goal libdoc 35 | * @requiresDependencyResolution test 36 | */ 37 | public class LibDocMojo extends AbstractMojoWithLoadedClasspath { 38 | 39 | protected void subclassExecute() throws MojoExecutionException, MojoFailureException { 40 | try { 41 | runLibDoc(); 42 | } catch (IOException e) { 43 | throw new MojoExecutionException("Failed to execute libdoc script: " + e.getMessage()); 44 | } 45 | } 46 | 47 | public void runLibDoc() throws IOException { 48 | libdoc.populateDefaults(this); 49 | libdoc.ensureOutputDirectoryExists(); 50 | 51 | if (projectBaseDir == null) 52 | projectBaseDir = new File(""); 53 | List runArgs = libdoc.generateRunArguments(projectBaseDir); 54 | for (String[] args : runArgs) { 55 | if (externalRunner != null && externalRunner.getRunWithPython()) { 56 | PythonRunner.run(args); 57 | } else { 58 | RobotFramework.run(args); 59 | } 60 | } 61 | } 62 | 63 | /** 64 | * Library documentation configuration. 65 | * 66 | * Required settings: 67 | *
    68 | *
  • outputFile The name for the output file. Documentation output format is deduced from the file extension. 69 | * We also support patterns like {@code *.html}, which indicates to derive the output name from the original name.
  • 70 | *
  • libraryOrResourceFile Name or path of the documented library or resource file. Supports ant-like pattern format to match multiple inputs, such as src/java/**{@literal /}*.java 71 | *

    72 | * Name must be in the same format as when used in Robot Framework test data, for example BuiltIn or 73 | * com.acme.FooLibrary. When name is used, the library is imported the same as when running the tests. 74 | * Use extraPathDirectories to set PYTHONPATH/CLASSPATH accordingly. 75 | * 76 | * Paths are considered relative to the location of pom.xml and must point to a valid Python/Java 77 | * source file or a resource file. For example src/main/python/test/ExampleLib.py 78 | * 79 | * Note that you should preferably import java classes by classname, not path. Dynamic libraries will not be compiled correctly with path.
  • 80 | *
81 | * Optional settings: 82 | *
    83 | *
  • outputDirectory Specifies the directory where documentation files are written. 84 | * Considered relative to the ${basedir} of the project, but also supports absolute paths. 85 | * Defaults to ${project.build.directory}/robotframework/libdoc
  • 86 | *
  • name Sets the name of the documented library or resource.
  • 87 | *
  • version Sets the version of the documented library or resource.
  • 88 | *
  • extraPathDirectories A directory to be added to the PYTHONPATH/CLASSPATH when creating documentation. 89 | * e.g. src/main/java/com/test/
  • 90 | *
91 | * 92 | * Example 1: 93 | *

 94 |      *      MyLib.html
 95 |      *      com.mylib.MyLib
 96 |      * ]]>
97 | * 98 | * Example 2: 99 | *

100 |      *      *.html
101 |      *      src/java/**{@literal /}*Lib.java
102 |      * ]]>
103 | 104 | * Example 3: 105 | *

106 |      *      *.html
107 |      *      com.**.*Lib
108 |      * ]]>
109 | * @parameter 110 | * @required 111 | */ 112 | private LibDocConfiguration libdoc; 113 | 114 | /** 115 | * Default output directory. Effective if outputDirectory is empty. Cannot be overridden. 116 | * 117 | * @parameter default-value="${project.build.directory}/robotframework/libdoc" 118 | * @readonly 119 | */ 120 | File defaultLibdocOutputDirectory; 121 | 122 | /** 123 | * The default location where extra packages will be searched. Effective if extraPathDirectories attribute is not 124 | * used. Cannot be overridden. 125 | * 126 | * @parameter default-value="${project.basedir}/src/test/resources/robotframework/libraries" 127 | * @readonly 128 | */ 129 | File libdocDefaultExtraPath; 130 | 131 | /** 132 | * The base dir of the project. 133 | * @parameter default-value="${project.basedir}" 134 | * @readonly 135 | */ 136 | File projectBaseDir; 137 | 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/PythonRunner.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.commons.lang3.ArrayUtils; 6 | 7 | public class PythonRunner{ 8 | public static void run(String[] commandWithRunArguments) { 9 | try { 10 | exec(commandWithRunArguments); 11 | } catch (Exception e) { 12 | // Nothing to do 13 | } 14 | } 15 | 16 | public static int exec(String command, String[] runArguments) throws IOException, 17 | InterruptedException { 18 | return exec(ArrayUtils.insert(0, runArguments, command)); 19 | } 20 | 21 | public static int exec(String[] commandWithRunArguments) throws IOException, 22 | InterruptedException { 23 | Process process = Runtime.getRuntime().exec(String.join(" ", commandWithRunArguments)); 24 | StreamReader stdout = new StreamReader(process.getInputStream()); 25 | StreamReader stderr = new StreamReader(process.getErrorStream()); 26 | stdout.start(); 27 | stderr.start(); 28 | return process.waitFor(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/RebotMojo.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.util.List; 23 | 24 | import org.apache.maven.plugin.MojoExecutionException; 25 | import org.apache.maven.plugin.MojoFailureException; 26 | import org.codehaus.plexus.util.StringUtils; 27 | import org.robotframework.RobotFramework; 28 | 29 | /** 30 | * Creates report files from output.xml using the Robot Framework rebot tool. 31 | * 32 | * Uses the rebot bundled in Robot Framework jar distribution. For more help see 33 | * rebot documentation. 34 | * 35 | * @goal rebot 36 | * @requiresDependencyResolution test 37 | */ 38 | public class RebotMojo 39 | extends AbstractMojoWithLoadedClasspath { 40 | 41 | protected void subclassExecute() 42 | throws MojoExecutionException, MojoFailureException { 43 | try { 44 | runRebot(); 45 | } catch (IOException e) { 46 | throw new MojoExecutionException("Failed to execute rebot script: " + e.getMessage()); 47 | } 48 | } 49 | 50 | public void runRebot() 51 | throws IOException { 52 | this.ensureOutputDirectoryExists(); 53 | if (externalRunner != null && externalRunner.getRunWithPython()) { 54 | PythonRunner.run(this.generateRunArguments()); 55 | } else { 56 | RobotFramework.run(this.generateRunArguments()); 57 | } 58 | } 59 | 60 | 61 | public String[] generateRunArguments() { 62 | Arguments generatedArguments = new Arguments(); 63 | generatedArguments.add("rebot"); 64 | generatedArguments.addFileToArguments(outputDirectory, "-d"); 65 | generatedArguments.addFileToArguments(output, "-o"); 66 | generatedArguments.addFileToArguments(log, "-l"); 67 | generatedArguments.addNonEmptyStringToArguments(logTitle, "--logtitle"); 68 | generatedArguments.addFileToArguments(report, "-r"); 69 | generatedArguments.addNonEmptyStringToArguments(reportTitle, "--reporttitle"); 70 | generatedArguments.addNonEmptyStringToArguments(splitOutputs, "--splitoutputs"); 71 | generatedArguments.addFlagToArguments(merge, "--merge"); 72 | generatedArguments.addFileToArguments(xunitFile, "-x"); 73 | generatedArguments.addNonEmptyStringToArguments(logLevel, "-L"); 74 | generatedArguments.addFlagToArguments(true, "--xunitskipnoncritical"); 75 | generatedArguments.addFlagToArguments(rpa, "--rpa"); 76 | generatedArguments.addListToArguments(removeKeywords, "--removekeywords"); 77 | generatedArguments.addListToArguments(flattenKeywords, "--flattenkeywords"); 78 | generatedArguments.add(getOutputPath()); 79 | return generatedArguments.toArray(); 80 | } 81 | 82 | private String getOutputPath() { 83 | return outputDirectory + File.separator + "output*.xml"; 84 | } 85 | 86 | public void ensureOutputDirectoryExists() 87 | throws IOException { 88 | if (outputDirectory == null) { 89 | String baseDir = System.getProperty("basedir"); 90 | // FIXME: this is to get around the problem that default-value does not currently work 91 | if (baseDir == null) 92 | baseDir = "."; 93 | outputDirectory = new File(joinPaths(baseDir, "target", "robotframework-reports")); 94 | } 95 | if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { 96 | throw new IOException("Target output directory cannot be created: " + outputDirectory.getAbsolutePath()); 97 | } 98 | } 99 | 100 | private String joinPaths(String... parts) { 101 | return StringUtils.join(parts, File.separator); 102 | } 103 | 104 | /** 105 | * Configures where generated reports are to be placed. 106 | * 107 | * @parameter default-value="${project.build.directory}/robotframework-reports" 108 | */ 109 | private File outputDirectory; 110 | 111 | /** 112 | * 113 | * When combining results, merge outputs together 114 | * instead of putting them under a new top level suite. 115 | * 116 | * @parameter default-value="false" 117 | */ 118 | private boolean merge; 119 | 120 | /** 121 | * Sets the threshold level for logging. 122 | * 123 | * @parameter 124 | */ 125 | private String logLevel; 126 | 127 | /** 128 | * Sets the path to the generated output file. 129 | * 130 | * @parameter 131 | */ 132 | private File output; 133 | 134 | /** 135 | * Sets the path to the generated log file. 136 | * 137 | * @parameter 138 | */ 139 | private File log; 140 | 141 | /** 142 | * Sets a title for the generated tests log. 143 | * 144 | * @parameter 145 | */ 146 | private String logTitle; 147 | 148 | /** 149 | * Sets the path to the generated report file. 150 | * 151 | * @parameter 152 | */ 153 | private File report; 154 | 155 | /** 156 | * Sets a title for the generated tests report. 157 | * 158 | * @parameter 159 | */ 160 | private String reportTitle; 161 | 162 | /** 163 | * Splits output and log files. 164 | * 165 | * @parameter 166 | */ 167 | private String splitOutputs; 168 | 169 | /** 170 | * Sets the path to the generated XUnit compatible result file, relative to outputDirectory. The 171 | * file is in xml format. By default, the file name is derived from the testCasesDirectory 172 | * parameter, replacing blanks in the directory name by underscores. 173 | * 174 | * @parameter default-value="${project.build.directory}/robotframework-reports/rebot-xunit-results.xml" 175 | */ 176 | private File xunitFile; 177 | 178 | /** 179 | * Turn on generic automation mode. 180 | * 181 | * @parameter default-value="false" 182 | */ 183 | private boolean rpa; 184 | 185 | /** 186 | * Remove keywords and their messages altogether. 187 | * Instructions at http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#removing-keywords. 188 | * 189 | *
    190 | *
  • 'ALL' - Remove data from all keywords unconditionally.
  • 191 | *
  • 'PASSED' -Remove keyword data from passed test cases. In most 192 | * cases, log files created using this option contain enough information 193 | * to investigate possible failures.
  • 194 | *
  • 'FOR' - Remove all passed iterations from for loops except the last one.
  • 195 | *
  • 'WUKS' - Remove all failing keywords inside BuiltIn keyword 196 | * 'Wait Until Keyword Succeeds' except the last one.
  • 197 | *
  • 'NAME:{@literal <}pattern{@literal >}' - Remove data from all keywords matching the given pattern regardless the keyword status.
  • 198 | *
  • 'TAG:{@literal <}pattern{@literal >}' - Remove data from keywords with tags that match the given pattern.
  • 199 | *
200 | * 201 | * The {@literal <}pattern{@literal >} is case, space, and underscore insensitive, and it supports simple patterns with * and ? as wildcards. 202 | * 203 | * @parameter 204 | */ 205 | private List removeKeywords; 206 | 207 | /** 208 | * Flatten keywords and their messages altogether. 209 | * Instructions at http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#flattening-keywords. 210 | * 211 | *
    212 | *
  • 'FOR' - Flatten for loops fully.
  • 213 | *
  • 'FORITEM' - Flatten individual for loop iterations.
  • 214 | *
  • 'NAME:{@literal <}pattern{@literal >}' - Flatten keywords matching the given pattern.
  • 215 | *
  • 'TAG:{@literal <}pattern{@literal >}' - Flatten keywords with tags matching the given pattern.
  • 216 | *
217 | * 218 | * The {@literal <}pattern{@literal >} is case, space, and underscore insensitive, and it supports simple patterns with * and ? as wildcards. 219 | * 220 | * @parameter 221 | */ 222 | private List flattenKeywords; 223 | 224 | } 225 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/RobotFrameworkMojo.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import org.apache.maven.plugin.MojoExecutionException; 21 | import org.apache.maven.plugin.MojoFailureException; 22 | 23 | /** 24 | * Runs the Robot tests. Behaves like invoking the "jybot" command. 25 | * 26 | * Robot Framework tests cases are created in files and directories, and they are executed by configuring the path to 27 | * the file or directory in question to the testCasesDirectory configuration. The given file or directory creates the 28 | * top-level tests suites, which gets its name, unless overridden with the "name" option, from the file or directory 29 | * name. 30 | * 31 | * @goal run 32 | * @requiresDependencyResolution test 33 | */ 34 | public class RobotFrameworkMojo 35 | extends AcceptanceTestMojo { 36 | 37 | protected void evaluateReturnCode(int robotRunReturnValue) 38 | // ======== ========================================== 39 | // RC Explanation 40 | // ======== ========================================== 41 | // 0 All critical tests passed. 42 | // 1-249 Returned number of critical tests failed. 43 | // 250 250 or more critical failures. 44 | // 251 Help or version information printed. 45 | // 252 Invalid test data or command line options. 46 | // 253 Test execution stopped by user. 47 | // 255 Unexpected internal error. 48 | // ======== ========================================== 49 | throws MojoFailureException, MojoExecutionException { 50 | switch (robotRunReturnValue) { 51 | case 0: 52 | // success 53 | break; 54 | case 1: 55 | throw new MojoFailureException("1 critical test case failed. Check the logs for details."); 56 | case 250: 57 | throw new MojoFailureException("250 or more critical test cases failed. Check the logs for details."); 58 | case 251: 59 | getLog().info("Help or version information printed. No tests were executed."); 60 | break; 61 | case 252: 62 | throw new MojoExecutionException("Invalid test data or command line options."); 63 | case 255: 64 | throw new MojoExecutionException("Unexpected internal error."); 65 | case 253: 66 | getLog().info("Test execution stopped by user."); 67 | break; 68 | default: 69 | throw new MojoFailureException(robotRunReturnValue 70 | + " critical test cases failed. Check the logs for details."); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/RobotMojoClassLoader.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.net.URL; 21 | import java.net.URLClassLoader; 22 | import java.net.URLStreamHandlerFactory; 23 | import java.util.Arrays; 24 | import java.util.List; 25 | 26 | 27 | public class RobotMojoClassLoader extends URLClassLoader { 28 | 29 | public RobotMojoClassLoader(URL[] urls, ClassLoader parent) { 30 | super(urls, parent); 31 | } 32 | 33 | public RobotMojoClassLoader(URL[] urls) { 34 | super(urls); 35 | } 36 | 37 | public RobotMojoClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { 38 | super(urls, parent, factory); 39 | } 40 | 41 | public void addIfNotAlready(URL url) { 42 | URL[] urls = getURLs(); 43 | if (!Arrays.asList(urls).contains(url)) 44 | super.addURL(url); 45 | } 46 | 47 | public void append(List urls) { 48 | for (URL url: urls) 49 | addIfNotAlready(url); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/TestDocConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * Copyright 2013 Gaurav Arora 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | import java.io.File; 22 | import java.io.IOException; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Set; 26 | 27 | import org.codehaus.plexus.util.StringUtils; 28 | import org.robotframework.mavenplugin.harvesters.HarvestUtils; 29 | import org.robotframework.mavenplugin.harvesters.ResourceNameHarvester; 30 | import org.robotframework.mavenplugin.harvesters.SourceFileNameHarvester; 31 | 32 | 33 | public class TestDocConfiguration { 34 | 35 | public List generateRunArguments(File projectBaseDir) { 36 | ArrayList result = new ArrayList(); 37 | 38 | // Phase I - harvest the files/resources, if any 39 | ArrayList fileArguments = harvestResourceOrFileCandidates(projectBaseDir, dataSourceFile); 40 | 41 | // Phase II - prepare the argument lines for the harvested 42 | // files/resources. 43 | boolean multipleOutputs = fileArguments.size() > 1; // with single 44 | // argument line, we 45 | // can use the 46 | // original single 47 | // entity 48 | // parameters, so 49 | // use this flag to 50 | // switch. 51 | for (String fileArgument : fileArguments) { 52 | Arguments generatedArguments = generateTestdocArgumentList(projectBaseDir, multipleOutputs, fileArgument); 53 | result.add(generatedArguments.toArray()); 54 | } 55 | return result; 56 | } 57 | 58 | private Arguments generateTestdocArgumentList(File projectBaseDir, boolean multipleOutputs, String fileArgument) { 59 | Arguments result = new Arguments(); 60 | result.add("testdoc"); 61 | result.addNonEmptyStringToArguments(title, "--title"); 62 | result.addNonEmptyStringToArguments(name, "--name"); 63 | result.addNonEmptyStringToArguments(doc, "--doc"); 64 | result.add(fileArgument); 65 | 66 | if (multipleOutputs) { 67 | // Derive the output file name id from the source and from the 68 | // output file given. 69 | String normalizedArgument; 70 | // Generate a unique name. 71 | if (HarvestUtils.isAbsolutePathFragment(fileArgument)) { 72 | // Cut out the project directory, so that we have shorter id 73 | // names. 74 | // TODO - perhaps later, we can preserve the directory structure 75 | // relative to the output directory. 76 | normalizedArgument = HarvestUtils.removePrefixDirectory(projectBaseDir, fileArgument); 77 | } else { 78 | normalizedArgument = fileArgument; 79 | } 80 | result.add(outputDirectory + File.separator + HarvestUtils.generateIdName(normalizedArgument) 81 | + HarvestUtils.extractExtension(outputFile.getName())); 82 | } else { 83 | // Preserve original single-file behavior. 84 | if (outputFile.getName().contains("*")) { 85 | // We deal with a pattern, so we need to get the name from the 86 | // input file. 87 | File tf = new File(fileArgument); 88 | result.add(outputDirectory + File.separator + tf.getName() 89 | + HarvestUtils.extractExtension(outputFile.getName())); 90 | } else { 91 | // Use the output name directly. 92 | result.add(outputDirectory + File.separator + outputFile.getName()); 93 | } 94 | } 95 | return result; 96 | } 97 | 98 | private ArrayList harvestResourceOrFileCandidates(File projectBaseDir, String pattern) { 99 | File entity = new File(pattern); 100 | ArrayList fileArguments = new ArrayList(); 101 | if (entity.isFile()) { 102 | // Single file specification, no patterns. 103 | fileArguments.add(entity.getAbsolutePath()); 104 | } else { 105 | // Possible pattern, process further. 106 | if (HarvestUtils.hasDirectoryStructure(pattern)) { 107 | // Directory structure, no class resolution, harvest file names. 108 | SourceFileNameHarvester harv = new SourceFileNameHarvester(projectBaseDir); 109 | fileArguments.addAll(harv.harvest(pattern)); 110 | } else { 111 | // A) May have files, try for harvesting file names first. 112 | SourceFileNameHarvester harv = new SourceFileNameHarvester(projectBaseDir); 113 | Set harvested = harv.harvest(pattern); 114 | if (harvested.size() > 0) { 115 | fileArguments.addAll(harvested); 116 | } else { 117 | // B) If no files found, try harvesting resources. 118 | ResourceNameHarvester rharv = new ResourceNameHarvester(); 119 | fileArguments.addAll(rharv.harvest(pattern)); 120 | } // resources 121 | } // files 122 | } // single file or pattern 123 | return fileArguments; 124 | } 125 | 126 | public void ensureOutputDirectoryExists() 127 | throws IOException { 128 | if (outputDirectory == null) { 129 | String baseDir = System.getProperty("basedir"); 130 | // FIXME: this is to get around the problem that default-value does not currently work 131 | if (baseDir == null) 132 | baseDir = "."; 133 | outputDirectory = new File(joinPaths(baseDir, "target", "robotframework", "testdoc")); 134 | } 135 | if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { 136 | throw new IOException("Target output directory cannot be created: " + outputDirectory.getAbsolutePath()); 137 | } 138 | } 139 | 140 | private String joinPaths(String... parts) { 141 | return StringUtils.join(parts, File.separator); 142 | } 143 | 144 | public void populateDefaults(TestDocMojo defaults) { 145 | if (this.outputDirectory == null) 146 | this.outputDirectory = defaults.defaultTestdocOutputDirectory; 147 | } 148 | 149 | /** 150 | * Specifies the directory where documentation files are written. Considered to be relative to the ${basedir} of the 151 | * project. 152 | */ 153 | private File outputDirectory; 154 | 155 | /** 156 | * Specifies the filename of the created documentation. Considered to be relative to the {@link #outputDirectory} of 157 | * the project. 158 | */ 159 | private File outputFile; 160 | 161 | /** 162 | * Name or path of the documented library or resource file. 163 | *

164 | * Name must be in the same format as when used in Robot Framework test data, for example BuiltIn or 165 | * com.acme.FooLibrary. When name is used, the library is imported the same as when running the tests. 166 | * Use {@link #extraPathDirectories} to set PYTHONPATH/CLASSPATH accordingly. 167 | *

168 | * Paths are considered relative to the location of pom.xml and must point to a valid Python/Java 169 | * source file or a resource file. For example src/main/java/com/test/ExampleLib.java 170 | * 171 | * One may also use ant-like patterns, for example 172 | * src/main/robot/**{@literal /}*.robot 173 | */ 174 | private String dataSourceFile; 175 | 176 | /** 177 | * Set the title of the generated documentation. Underscores in the title are converted to spaces. The default title is the name of the top level suite. 178 | */ 179 | private String title; 180 | 181 | /** 182 | * Override the name of the top level test suite. 183 | */ 184 | private String name; 185 | 186 | /** 187 | * Override the documentation of the top level test suite. 188 | */ 189 | private String doc; 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/TestDocMojo.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * Copyright 2013 Gaurav Arora 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | import java.io.File; 22 | 23 | import java.io.IOException; 24 | import java.util.List; 25 | 26 | import org.apache.maven.plugin.MojoExecutionException; 27 | import org.apache.maven.plugin.MojoFailureException; 28 | import org.robotframework.RobotFramework; 29 | 30 | /** 31 | * Create documentation of test suites using the Robot Framework testdoc tool. 32 | *
33 | * Uses the testdoc bundled in Robot Framework jar distribution. For more help see 34 | * testdoc documentation. 35 | * 36 | * @goal testdoc 37 | * @requiresDependencyResolution test 38 | */ 39 | public class TestDocMojo 40 | extends AbstractMojoWithLoadedClasspath { 41 | 42 | protected void subclassExecute() 43 | throws MojoExecutionException, MojoFailureException { 44 | try { 45 | runTestDoc(); 46 | } catch (IOException e) { 47 | throw new MojoExecutionException("Failed to execute testdoc script: " + e.getMessage()); 48 | } 49 | } 50 | 51 | public void runTestDoc() 52 | throws IOException { 53 | testdoc.populateDefaults(this); 54 | testdoc.ensureOutputDirectoryExists(); 55 | 56 | if (projectBaseDir == null) 57 | projectBaseDir = new File(""); 58 | List runArgs = testdoc.generateRunArguments(projectBaseDir); 59 | for (String[] args : runArgs) { 60 | getLog().debug("Run arguments -> " + args); 61 | if (externalRunner != null && externalRunner.getRunWithPython()) { 62 | PythonRunner.run(args); 63 | } else { 64 | RobotFramework.run(args); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Test case documentation configuration. 71 | * 72 | * Required settings: 73 | *
    74 | *
  • outputFile The name for the output file. 75 | * We also support patterns like {@code *.html}, which indicates to derive the output name from the original name.
  • 76 | *
  • dataSourceFile Name or path of the documented test case(s). Supports ant-like pattern format to match multiple inputs, such as src/robot/**{@literal /}*.robot
  • 77 | *
78 | *

79 | * Paths are considered relative to the location of pom.xml and must point to a valid test case file. 80 | * For example src/main/test/ExampleTest.txt 81 | * Optional settings: 82 | *
    83 | *
  • outputDirectory Specifies the directory where documentation files are written. 84 | * Considered to be relative to the ${basedir} of the project. 85 | * Default ${project.build.directory}/robotframework/testdoc
  • 86 | *
  • title Set the title of the generated documentation. Underscores in 87 | * the title are converted to spaces. The default title is the 88 | * name of the top level suite.
  • 89 | *
  • name Override the name of the top level test suite.
  • 90 | *
  • doc Override the documentation of the top level test suite.
  • 91 | *
92 | * 93 | * Example 1: 94 | *

 95 |      *      MyTests.html
 96 |      *      src/test/resources/MyTests.txt
 97 |      * ]]>
98 | * 99 | * Example 2: 100 | *

101 |      *      *.html
102 |      *      src/robot/**{@literal /}*.robot
103 |      * ]]>
104 | * 105 | * @parameter 106 | * @required 107 | */ 108 | private TestDocConfiguration testdoc; 109 | 110 | /** 111 | * Default output directory. Effective if outputDirectory is empty. Cannot be overridden. 112 | * 113 | * @parameter default-value="${project.build.directory}/robotframework/testdoc" 114 | * @readonly 115 | */ 116 | File defaultTestdocOutputDirectory; 117 | 118 | /** 119 | * The base dir of the project. 120 | * @parameter default-value="${project.basedir}" 121 | * @readonly 122 | */ 123 | File projectBaseDir; 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/VerifyMojo.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /* 4 | * Copyright 2011 Michael Mallete, Dietrich Schulten 5 | * Copyright 2013 Nokia Siemens Networks Oyj 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import java.io.File; 21 | 22 | import javax.xml.parsers.DocumentBuilder; 23 | import javax.xml.parsers.DocumentBuilderFactory; 24 | import javax.xml.xpath.XPath; 25 | import javax.xml.xpath.XPathConstants; 26 | import javax.xml.xpath.XPathExpressionException; 27 | import javax.xml.xpath.XPathFactory; 28 | 29 | import org.apache.maven.plugin.MojoExecutionException; 30 | import org.apache.maven.plugin.MojoFailureException; 31 | import org.w3c.dom.Document; 32 | import org.w3c.dom.NamedNodeMap; 33 | import org.w3c.dom.Node; 34 | import org.w3c.dom.NodeList; 35 | 36 | /** 37 | * Verifies the results from acceptance-test goal. 38 | * 39 | * @goal verify 40 | * @phase verify 41 | * @requiresDependencyResolution test 42 | */ 43 | public class VerifyMojo 44 | extends AbstractMojoWithLoadedClasspath { 45 | 46 | /** 47 | * The directory where the test cases are located. 48 | * 49 | * @parameter default-value="${project.basedir}/src/test/resources/robotframework/acceptance" 50 | */ 51 | private File testCasesDirectory; 52 | 53 | /** 54 | * Sets the path to the generated XUnit compatible result file, relative to outputDirectory. The file is in xml 55 | * format. By default, the file name is derived from the testCasesDirectory parameter, replacing blanks in the 56 | * directory name by underscores. 57 | * 58 | * @parameter 59 | */ 60 | private File xunitFile; 61 | 62 | /** 63 | * Configures where generated reports are to be placed. 64 | * 65 | * @parameter default-value="${project.build.directory}/robotframework-reports" 66 | */ 67 | private File outputDirectory; 68 | 69 | /** 70 | * Log failures without failing the build. 71 | * 72 | * @parameter default-value="false" 73 | */ 74 | private boolean isTestFailureIgnore; 75 | 76 | /** 77 | * Skip verification of tests. Bound to -DskipTests. This allows to skip acceptance tests together with all 78 | * other tests. 79 | * 80 | * @parameter property="skipTests" 81 | */ 82 | private boolean skipTests; 83 | 84 | /** 85 | * Skip verification of acceptance tests executed by this plugin. Bound to -DskipATs. This allows to run tests 86 | * and integration tests, but no acceptance tests. 87 | * 88 | * @parameter property="skipATs" 89 | */ 90 | private boolean skipATs; 91 | 92 | /** 93 | * Skip verification of acceptance tests executed by this plugin together with other integration tests, e.g. 94 | * tests run by the maven-failsafe-plugin. Bound to -DskipITs 95 | * 96 | * @parameter property="skipITs" 97 | */ 98 | private boolean skipITs; 99 | 100 | /** 101 | * Skip verification of tests, bound to -Dmaven.test.skip, which suppresses test compilation as well. 102 | * 103 | * @parameter default-value="false" property="maven.test.skip" 104 | */ 105 | private boolean skip; 106 | 107 | private boolean shouldSkipTests() { 108 | return skipTests || skipITs || skipATs || skip; 109 | } 110 | 111 | /** 112 | * {@inheritDoc} 113 | */ 114 | @Override 115 | protected void subclassExecute() 116 | throws MojoExecutionException, MojoFailureException { 117 | // TODO: Refactor 118 | if (shouldSkipTests()) { 119 | getLog().info("RobotFramework tests are skipped."); 120 | return; 121 | } 122 | if (xunitFile == null) { 123 | String testCasesFolderName = testCasesDirectory.getName(); 124 | xunitFile = new File("TEST-" + testCasesFolderName.replace(' ', '_') + ".xml"); 125 | } 126 | 127 | getLog().debug("Output directory is " + outputDirectory); 128 | 129 | final int errors; 130 | final int failures; 131 | 132 | try { 133 | DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 134 | Document xunitResult = documentBuilder.parse(makeAbsolute(outputDirectory, xunitFile)); 135 | 136 | errors = readIntAttribute(xunitResult, "/testsuite/@errors"); 137 | failures = readIntAttribute(xunitResult, "/testsuite/@failures"); 138 | int tests = readIntAttribute(xunitResult, "/testsuite/@tests"); 139 | 140 | System.out.println("\nTest Results :"); 141 | 142 | if (failures > 0 || errors > 0) { 143 | 144 | System.out.println("\nFailing acceptance tests:\n"); 145 | NodeList testCases = getFailuresAndErrors(xunitResult); 146 | for (int i = 0; i < testCases.getLength(); i++) { 147 | Node testCase = testCases.item(i); 148 | NamedNodeMap attributes = testCase.getAttributes(); 149 | System.out.println(" " 150 | + attributes.getNamedItem("name").getNodeValue() + "(" + attributes.getNamedItem("classname").getNodeValue() + ")"); 151 | } 152 | } 153 | 154 | System.out.println("\nTests run: " + tests + ", Failures: " + failures + ", Errors: " + errors + "\n"); 155 | } catch (Exception e) { 156 | throw new MojoExecutionException("failed to verify robotframework acceptance-test results", e); 157 | } 158 | if (errors > 0 || failures > 0) { 159 | String msg = 160 | "There are acceptance test failures.\n\nPlease refer to " + outputDirectory.getAbsolutePath() 161 | + " for the individual test results."; 162 | 163 | if (isTestFailureIgnore) { 164 | getLog().error(msg); 165 | } else { 166 | throw new MojoFailureException(msg); 167 | } 168 | } 169 | 170 | } 171 | 172 | private NodeList getFailuresAndErrors(Document xunitResult) 173 | throws XPathExpressionException { 174 | XPath xPath = XPathFactory.newInstance().newXPath(); 175 | String xPathExpression = "/testsuite/testcase[failure or error]"; 176 | NodeList testCases = (NodeList) xPath.evaluate(xPathExpression, xunitResult, XPathConstants.NODESET); 177 | return testCases; 178 | } 179 | 180 | private int readIntAttribute(Document xunitResult, String xPathExpression) 181 | throws XPathExpressionException { 182 | XPath xPath = XPathFactory.newInstance().newXPath(); 183 | return ((Number) xPath.evaluate(xPathExpression, xunitResult, XPathConstants.NUMBER)).intValue(); 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/AntPatternClassPredicate.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import java.io.File; 4 | 5 | import com.google.common.base.Predicate; 6 | import org.codehaus.plexus.util.DirectoryScanner; 7 | 8 | /** 9 | * Checks matching in an ant-like pattern. 10 | */ 11 | public class AntPatternClassPredicate implements Predicate { 12 | private final String pattern; 13 | 14 | public AntPatternClassPredicate(String aPattern) { 15 | pattern = aPattern.replace('.', File.separatorChar); 16 | } 17 | 18 | public boolean apply(String target) { 19 | String compatibleTarget; 20 | if (target.endsWith(".class")) { 21 | int classSuffixIndex = target.lastIndexOf(".class"); 22 | compatibleTarget = target.substring(0, classSuffixIndex); 23 | } else 24 | compatibleTarget = target; 25 | 26 | compatibleTarget = compatibleTarget.replace('.', File.separatorChar); 27 | return DirectoryScanner.match(pattern, compatibleTarget); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/ClassNameHarvester.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import com.google.common.reflect.ClassPath; 4 | 5 | import java.io.IOException; 6 | import java.util.LinkedHashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * Harvests resource (not class) names from the class path given an ant-like 11 | * pattern (considers '/' replaced with '.' though). 12 | */ 13 | public class ClassNameHarvester implements NameHarvester { 14 | 15 | public Set harvest(String antLikePattern) { 16 | int minPatternIndex = HarvestUtils.calculateMinimumPatternIndex(antLikePattern); 17 | 18 | LinkedHashSet result = new LinkedHashSet(); 19 | if (minPatternIndex >= 0) { 20 | try { 21 | AntPatternClassPredicate ap = new AntPatternClassPredicate(antLikePattern); 22 | ClassPath cp = ClassPath.from(this.getClass().getClassLoader()); 23 | for (ClassPath.ClassInfo ci : cp.getAllClasses()) { 24 | String t = ci.getName(); 25 | if (ap.apply(t)) 26 | result.add(t); 27 | } 28 | } catch (IOException e) { 29 | // Could not find any! 30 | } 31 | } else { 32 | // No pattern, add as direct resource to deal with later. 33 | result.add(antLikePattern); 34 | } 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/HarvestUtils.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Some utilities for processing harvested names. 7 | */ 8 | public class HarvestUtils { 9 | 10 | public static final String JAVA_FILE_EXT = ".java"; 11 | 12 | /** 13 | * Extracts the name component of a string representing a file name. 14 | * 15 | * @param harvestedName to get just name from 16 | * @return name part (without extension) 17 | */ 18 | public static String extractName(String harvestedName) { 19 | String result = ""; 20 | 21 | int indexOfSlash = harvestedName.lastIndexOf('/'); 22 | int indexOfBackSlash = harvestedName.lastIndexOf('\\'); 23 | if (indexOfSlash >= 0 || indexOfBackSlash >= 0) { 24 | // we deal with a file path 25 | int index = Math.max(indexOfSlash, indexOfBackSlash); 26 | if (index + 1 != harvestedName.length()) { 27 | if (harvestedName.endsWith(JAVA_FILE_EXT)) 28 | result = harvestedName.substring(index + 1, harvestedName.length() - JAVA_FILE_EXT.length()); 29 | else 30 | result = harvestedName.substring(index + 1); 31 | } 32 | } else { 33 | if (harvestedName.endsWith(JAVA_FILE_EXT)) 34 | result = harvestedName.substring(0, harvestedName.length() - JAVA_FILE_EXT.length()); 35 | else { 36 | // Dealing with a class, so use the name. 37 | int indexOfDot = harvestedName.lastIndexOf('.'); 38 | if (indexOfDot + 1 != harvestedName.length()) 39 | result = harvestedName.substring(indexOfDot + 1); 40 | } 41 | } 42 | return result; 43 | } 44 | 45 | public static int calculateMinimumPatternIndex(String antLikePattern) { 46 | int indexOfStar = antLikePattern.indexOf('*'); 47 | int indexOfQuestionMark = antLikePattern.indexOf('?'); 48 | int minPatternIndex; 49 | if (indexOfStar >= 0) { 50 | if (indexOfQuestionMark >= 0) 51 | minPatternIndex = Math.min(indexOfStar, indexOfQuestionMark); 52 | else 53 | minPatternIndex = indexOfStar; 54 | } else { 55 | if (indexOfQuestionMark >= 0) 56 | minPatternIndex = indexOfQuestionMark; 57 | else 58 | minPatternIndex = -1; 59 | } 60 | return minPatternIndex; 61 | } 62 | 63 | /** 64 | * Prepares an id name from a full path or fully qualified file, by 65 | * replacing various chars with '_'. 66 | * 67 | * @param harvestedName string to get ID from 68 | * @return id name for given harvestedName 69 | */ 70 | public static String generateIdName(String harvestedName) { 71 | return harvestedName.replaceAll("/|\\.|\\\\", "_"); 72 | } 73 | 74 | /** 75 | * Checks whether the given parameter seems to start with an absolute path 76 | * fragment according to the current file system. 77 | * 78 | * @param fragment fragment to check for absolute path 79 | * @return true is fragment is absolute path 80 | */ 81 | public static boolean isAbsolutePathFragment(String fragment) { 82 | // Need to find out whether we have a pattern/path that starts as 83 | // absolute path according to the current file system. 84 | return new File(fragment).isAbsolute(); 85 | } 86 | 87 | /** 88 | * Whether the fragment hints to a directory structure, supporting Windows 89 | * or *nix file systems. 90 | * 91 | * @param fragment to check 92 | * @return true if given fragment describes directory structure 93 | */ 94 | public static boolean hasDirectoryStructure(String fragment) { 95 | // occurrence of '/' or '\' hints at a directory structure, hence files, 96 | // so try that one. 97 | return fragment.indexOf('/') >= 0 || fragment.indexOf('\\') >= 0; 98 | } 99 | 100 | /** 101 | * Extracts from the filename what could serve as extension. 102 | * 103 | * @param filename filename to get extension from 104 | * @return extension from file, or empty if there's no extension. 105 | */ 106 | public static String extractExtension(String filename) { 107 | String result = ""; 108 | int indexOfDot = filename.lastIndexOf('.'); 109 | if (indexOfDot >= 0) { 110 | result = filename.substring(indexOfDot); 111 | } 112 | return result; 113 | } 114 | 115 | public static String removePrefixDirectory(File projectBaseDir, String fileArgument) { 116 | String result = fileArgument; 117 | String prefix = projectBaseDir.getAbsolutePath() + File.separator; 118 | if (fileArgument.startsWith(prefix)) { 119 | result = fileArgument.substring(prefix.length()); 120 | } 121 | return result; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/NameHarvester.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import java.util.Set; 4 | 5 | public interface NameHarvester { 6 | public Set harvest(String pattern); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/ResourceNameHarvester.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import java.io.IOException; 4 | import java.util.LinkedHashSet; 5 | import java.util.Set; 6 | 7 | import com.google.common.reflect.ClassPath; 8 | 9 | /** 10 | * Harvests resource (not class) names from the class path given an ant-like 11 | * pattern (considers '/' replaced with '.' though). 12 | */ 13 | public class ResourceNameHarvester implements NameHarvester { 14 | 15 | public Set harvest(String antLikePattern) { 16 | int minPatternIndex = HarvestUtils.calculateMinimumPatternIndex(antLikePattern); 17 | 18 | LinkedHashSet result = new LinkedHashSet(); 19 | if (minPatternIndex >= 0) { 20 | try { 21 | AntPatternClassPredicate ap = new AntPatternClassPredicate(antLikePattern); 22 | ClassPath cp = ClassPath.from(this.getClass().getClassLoader()); 23 | for (ClassPath.ResourceInfo ri : cp.getResources()) { 24 | String t = ri.getResourceName(); 25 | if (ap.apply(t)) 26 | result.add(t); 27 | } 28 | } catch (IOException e) { 29 | // Could not find any, so silence the exception! 30 | } 31 | } else 32 | // No pattern, add as direct resource to deal with later. 33 | result.add(antLikePattern); 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/robotframework/mavenplugin/harvesters/SourceFileNameHarvester.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import org.codehaus.plexus.util.DirectoryScanner; 4 | 5 | import java.io.File; 6 | import java.util.LinkedHashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * Harvests file names, supports ant-like patterns, the same understood by Maven 11 | * 'includes'. 12 | */ 13 | public class SourceFileNameHarvester implements NameHarvester { 14 | 15 | private final File baseDir; 16 | 17 | public SourceFileNameHarvester(File bDir) { 18 | baseDir = bDir; 19 | } 20 | 21 | public Set harvest(String antLikePattern) { 22 | int minPatternIndex = HarvestUtils.calculateMinimumPatternIndex(antLikePattern); 23 | 24 | int lastSlashBeforePatternSymbol = antLikePattern.lastIndexOf('/', minPatternIndex); 25 | int lastBackslashBeforePatternSymbol = antLikePattern.lastIndexOf('\\', minPatternIndex); 26 | 27 | int maxSlashIndex = Math.max(lastSlashBeforePatternSymbol, lastBackslashBeforePatternSymbol); 28 | 29 | String baseDirectory = ""; 30 | // Determine whether to provide the project base dir. 31 | if (!HarvestUtils.isAbsolutePathFragment(antLikePattern)) 32 | baseDirectory = baseDir.getAbsolutePath() + File.separator; 33 | 34 | // Parse out the additional directory and pattern parts. 35 | String patternString = ""; 36 | if (maxSlashIndex > 0) { 37 | baseDirectory += antLikePattern.substring(0, maxSlashIndex + 1); 38 | if (maxSlashIndex + 1 < antLikePattern.length()) 39 | patternString = antLikePattern.substring(maxSlashIndex + 1); 40 | } else 41 | patternString = antLikePattern; 42 | 43 | // pattern that we need to expand. 44 | DirectoryScanner scanner = new DirectoryScanner(); 45 | scanner.setBasedir(baseDirectory); 46 | scanner.setCaseSensitive(true); 47 | scanner.setIncludes(new String[] { patternString }); 48 | 49 | scanner.scan(); 50 | 51 | String[] includedFiles = scanner.getIncludedFiles(); 52 | LinkedHashSet result = new LinkedHashSet(); 53 | File bDir = scanner.getBasedir(); 54 | for (String iF : includedFiles) { 55 | File tmp = new File(bDir, iF); 56 | result.add(tmp.getAbsolutePath()); 57 | } 58 | return result; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/org/robotframework/mavenplugin/robotframework-report.properties: -------------------------------------------------------------------------------- 1 | report.robotframework.name=Robotframework Report 2 | report.robotframework.description=Robotframework Report of the Project. 3 | report.robotframework.header=Robotframework Report -------------------------------------------------------------------------------- /src/site/apt/examples/javalibraries.apt: -------------------------------------------------------------------------------- 1 | Using Java Libraries with the Robotframework Plugin 2 | 3 | * Java test libraries 4 | 5 | You can access Java test libraries by adding the jars to the extraPathDirectories parameter or importing those 6 | as Maven dependencies. 7 | Note that such tests will run with Jython only. 8 | 9 | +--- 10 | 11 | org.robotframework 12 | robotframework-maven-plugin 13 | 14 | 15 | src/test/pythonpath 16 | src/test/mytestlib.jar 18 | 19 | 20 | +--- 21 | 22 | * Python libraries with Java dependencies 23 | 24 | But there is a different use case. Python libraries can use Java libraries directly 25 | using JPype. For example, the Python based DatabaseLibrary can be 26 | used with jaydebeapi and JPype to access databases via Python and jdbc. 27 | 28 | Such a test runs within a pure Python environment with JPype installed, as well as with 29 | Jython. That way you can have database test cases that run within RIDE in Python mode, 30 | and within the Robotframework Maven Plugin. 31 | 32 | If you need Java libraries as dependencies to your test libraries, you can add them to the 33 | dependencies section of the maven plugin configuration in the pom. 34 | 35 | +--- 36 | 37 | org.robotframework 38 | robotframework-maven-plugin 39 | 2.1.0 40 | 41 | 42 | src/test/resources/python 43 | 44 | 45 | 46 | 47 | org.hsqldb 48 | hsqldb 49 | 1.8.0.10 50 | 51 | 52 | 53 | +--- 54 | 55 | The test cases access hsqldb, the python folder contains the DatabaseLibrary and the jaydebeapi. 56 | 57 | If you want to run such a test within RIDE, make sure DatabaseLibrary, JPype and jaydebeapi 58 | are installed in your Python runtime. 59 | 60 | An actual test case is shown below. 61 | 62 | +--- 63 | *** Settings *** 64 | Library OperatingSystem 65 | Library DatabaseLibrary 66 | 67 | *** Test Cases *** 68 | Connect 69 | Connect To Database Using Custom Params jaydebeapi org.hsqldb.jdbcDriver jdbc:hsqldb:mem:robot sa ${EMPTY} 70 | Execute SQL create table testtable (myid integer not null primary key, name varchar(25)) 71 | Execute SQL insert into testtable values (1, 'myname') 72 | Execute SQL insert into testtable values (2, 'yourname') 73 | @{result}= Execute Sql Select * from testtable 74 | Log Many @{result} 75 | Check If Exists In Database select * from testtable where myid=2 76 | Execute SQL drop table testtable 77 | Disconnect From Database 78 | +--- 79 | -------------------------------------------------------------------------------- /src/site/apt/examples/seleniumlibrary.apt: -------------------------------------------------------------------------------- 1 | Using Python-based SeleniumLibrary with the Robotframework Plugin 2 | 3 | ExtraPathDirectories parameter can be used to add extra test libraries to your build. 4 | 5 | By default, you should add them to $\{project.basedir}/src/test/resources/robotframework/libraries. 6 | 7 | * Configuration and Installation 8 | 9 | This is just and example how importing can be done, as there's also {{{https://github.com/Hi-Fi/robotframework-seleniumlibrary-java/}Java-based Selenium-library}} available that 10 | can be included just as Maven depednency 11 | 12 | Download the tarball from the Selenium Library releases page, 13 | e.g. {{{https://github.com/robotframework/SeleniumLibrary/archive/v3.3.1.tar.gz}robotframework-seleniumlibrary-3.3.1.tar.gz}} 14 | 15 | Extract the file and move the SeleniumLibrary directory from 16 | robotframework-seleniumLibrary/src to ${project.basedir}/src/test/resources/robotframework/libraries. 17 | 18 | So your project will have a folder 19 | $\{project.basedir}/src/test/resources/robotframework/libraries/SeleniumLibrary 20 | 21 | Make same thing for {{{https://github.com/robotframework/SeleniumLibrary/blob/master/requirements.txt}external dependencies of the library}}. 22 | Robot Framework doesn't need to be imported, as it comes from dependencies. 23 | 24 | * Example 25 | 26 | Now, you can import SeleniumLibrary and use its keywords in your tests. 27 | 28 | Below you see a test case that uses the Open Browser keyword. 29 | The Selenium server is started during suite setup. 30 | 31 | +--- 32 | *** Settings *** 33 | Library SeleniumLibrary 34 | Suite Set Up Start Selenium Server 35 | Suite Tear Down Stop Selenium Server 36 | 37 | *** Test Cases *** 38 | My Test 39 | Open Browser http://robotframework.org 40 | +--- -------------------------------------------------------------------------------- /src/site/apt/index.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Introduction 3 | ------ 4 | Dietrich Schulten & Robot Framework developement team 5 | ------ 6 | 2012-01-20 7 | ------ 8 | 9 | 10 | Robot Framework Maven Plugin 11 | 12 | {{{http://maven.apache.org}Maven}} plugin for using the 13 | {{{http://robotframework.googlecode.com/}Robot Framework}}. 14 | Goal of this plugin is to be able to use Robot Framework in a Maven project 15 | without the need to install anything extra (e.g. Robot Framework, Jython, etc). 16 | In short, it's a non-invasive way of introducing acceptance test driven development to your existing 17 | projects quickly. 18 | 19 | This project was forked from {{{http://code.google.com/p/robotframework-maven-plugin}http://code.google.com/p/robotframework-maven-plugin}}. 20 | See instructions for {{{./transitioning.html}transitioning from previous version}}. 21 | 22 | * Goals Overview 23 | 24 | Plugin provides the following goals: 25 | 26 | * {{{./run-mojo.html}robotframework:run}} - behaves like invoking the 27 | {{{http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html#starting-test-execution}jybot}} 28 | Robot Framework command for executing test cases 29 | 30 | * {{{./acceptance-test-mojo.html}robotframework:acceptance-test}} - Runs the tests, like the run-goal, but does not verify the test results. 31 | 32 | * {{{./verify-mojo.html}robotframework:verify}} - Verifies the results from acceptance-test goal. 33 | 34 | * {{{./libdoc-mojo.html}robotframework:libdoc}} invokes the 35 | {{{http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html#library-documentation-tool-libdoc}libdoc}} 36 | Robot Framework command for generating keyword documentation for test libraries and resource files 37 | 38 | * {{{./testdoc-mojo.html}robotframework:testdoc}} invokes the 39 | {{{http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html#test-data-documentation-tool-testdoc}testdoc}} 40 | Robot Framework command for generating high level overview of test suites 41 | 42 | * {{{./rebot-mojo.html}robotframework:rebot}} invokes the 43 | {{{http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#using-rebot}rebot}} 44 | Robot Framework command that separately allows creating custom reports and logs as well as combining and merging results. It can also be used 45 | to separate test execution and report generation to different maven profiles. 46 | 47 | 48 | 49 | 50 | 51 | * Getting started 52 | 53 | Add the plugin to your build: 54 | 55 | +--- 56 | 57 | 58 | 59 | .. 60 | .. 61 | 62 | .. 63 | .. 64 | 65 | 66 | org.robotframework 67 | robotframework-maven-plugin 68 | 2.1.0 69 | 70 | 71 | 72 | run 73 | 74 | 75 | 76 | 77 | 78 | .. 79 | .. 80 | 81 | 82 | 83 | 84 | +--- 85 | 86 | By default, you can add your test cases to $\{project.basedir\}/src/test/robotframework/acceptance 87 | 88 | Third party libraries (e.g. Selenium Library) can be added to $\{project.basedir}/src/test/resources/robotframework/libraries. 89 | Java dependencies can be expressed as dependencies to the Robotframework maven plugin configuration in pom.xml. 90 | 91 | During mvn install invocation, the run goal will by default be invoked during the integration-test phase. 92 | 93 | Some more specific use cases are described in the examples given below.. 94 | 95 | In case you still have questions regarding the plugin's usage feel free to contact the 96 | {{{./mail-lists.html}user mailing list}}. The posts to the mailing list are archived and could 97 | already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching 98 | the {{{./mail-lists.html}mail archive}}. 99 | 100 | If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our 101 | {{{./issue-tracking.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your 102 | concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, 103 | entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. 104 | Of course, patches are welcome, too. Contributors can check out the project from our 105 | {{{./source-repository.html}source repository}} and will find supplementary information in the 106 | {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. 107 | 108 | * About memory usage 109 | 110 | This plugin runs Robot Framework with Jython and in some cases parsing the 111 | Robot's own output.xml can cause Jython to use excessive amounts of memory. 112 | 113 | To avoid parsing the xml, you can disable log generation by the setting 114 | logFile config to value NONE. This still allows Robot to generate the html 115 | report, and the xunit output-file, which the plugin uses to verify the results 116 | of the test run. The log-file can be generated later from the output.xml using 117 | {{{./rebot-mojo.html}robotframework:rebot}}-goal if needed. 118 | 119 | * Updating Robot Framework dependency 120 | 121 | If you want to use a different Robot Framework version, you can override the dependency in your plugin declaration: 122 | 123 | +--- 124 | 125 | .. 126 | 127 | org.robotframework 128 | robotframework-maven-plugin 129 | 2.1.0 130 | 131 | 132 | 133 | run 134 | 135 | 136 | 137 | 138 | 139 | org.robotframework 140 | robotframework 141 | 2.8.7 142 | 143 | 144 | 145 | .. 146 | 147 | +--- 148 | 149 | * Examples 150 | 151 | To provide you with better understanding of some usages of the Robot Framework Maven Plugin, 152 | you can take a look into the following examples: 153 | 154 | * {{{./examples/seleniumlibrary.html}Using SeleniumLibrary}} 155 | 156 | * {{{./examples/javalibraries.html}Using Java libraries}} 157 | 158 | * Source and issue tracker 159 | 160 | {{{https://github.com/robotframework/MavenPlugin}Project github pages}} contain the source code and also the 161 | {{{https://github.com/robotframework/MavenPlugin/issues}issue tracker}}. 162 | 163 | -------------------------------------------------------------------------------- /src/site/apt/transitioning.apt: -------------------------------------------------------------------------------- 1 | ------ 2 | Transitioning from old version 3 | ------ 4 | Jussi Malinen 5 | ------ 6 | 2012-09-11 7 | ------ 8 | 9 | Trasitioning from old version of Robot Framework Maven Plugin 10 | 11 | * Introduction 12 | 13 | This plugin was forked from 14 | {{{http://code.google.com/p/robotframework-maven-plugin}http://code.google.com/p/robotframework-maven-plugin}}. 15 | For the most part this new plugin works as a drop in replacement for the old version, but there are a few changes 16 | needed to the configuration. This page describes the changes needed to move to this new version. 17 | 18 | * Executive summary 19 | 20 | Change the <<>> to and update the version number. Unless you use 21 | {{{./libdoc-mojo.html}libdoc}}, thats all you need. 22 | 23 | +--- 24 | 25 | org.robotframework 26 | robotframework-maven-plugin 27 | 2.1.0 28 | 29 | +--- 30 | 31 | Below the changes in more detail. 32 | 33 | * New groupId and version 34 | 35 | The original plugin was distributed with groupId <<>>. This has been changed 36 | to <<>>. The versioning starts in this new plugin from version 1.0.0 37 | (so version 1.0.0 of this plugin is newer than version 1.1.2 of the old version). 38 | 39 | 40 | * Configuration changes 41 | 42 | Configuration of the run target has not been changed, but {{{./libdoc-mojo.html}libdoc}} configuration is now given 43 | in a separate <<>> element. See example below. 44 | 45 | +--- 46 | 47 | org.robotframework 48 | robotframework-maven-plugin 49 | 2.1.0 50 | 51 | 52 | MyLib 53 | MyLib.html 54 | 55 | 56 | 57 | +--- 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/AbstractRFMojoTestCase.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.maven.plugin.Mojo; 6 | import org.apache.maven.plugin.MojoExecutionException; 7 | import org.apache.maven.plugin.MojoFailureException; 8 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 9 | 10 | /** 11 | * @author g.arora@iontrading.com 12 | * @version $Id$ 13 | * @since 0.7.6 14 | */ 15 | public abstract class AbstractRFMojoTestCase extends AbstractMojoTestCase { 16 | 17 | void executeLibdocWithPom(String goal, String pathToPom) throws Exception, MojoExecutionException, MojoFailureException { 18 | File pom = getTestFile(pathToPom); 19 | Mojo mojo = lookupMojo(goal, pom); 20 | mojo.execute(); 21 | } 22 | 23 | void deleteDocument(String documentation) throws Exception { 24 | File document = new File(documentation); 25 | if (document.exists()) { 26 | boolean deleted = document.delete(); 27 | if (!deleted) { 28 | throw new Exception("Cannot delete existing document."); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/AcceptanceTestAndVerifyMojoIT.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.containsString; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | import org.apache.maven.it.VerificationException; 13 | import org.apache.maven.it.Verifier; 14 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 15 | 16 | public class AcceptanceTestAndVerifyMojoIT 17 | extends AbstractMojoTestCase { 18 | 19 | private static final String PLUGIN = "org.robotframework:robotframework-maven-plugin"; 20 | private File testDir = getTestFile("src/test/projects/acceptance-and-verify"); 21 | private Verifier verifier; 22 | private List cliOptions; 23 | 24 | @Override 25 | protected void setUp() throws Exception { 26 | super.setUp(); 27 | verifier = new Verifier(testDir.getAbsolutePath()); 28 | cliOptions = new ArrayList(); 29 | } 30 | 31 | public void testAcceptanceTestMojos() 32 | throws Exception { 33 | executeFailingGoals(PLUGIN + ":acceptance-test", PLUGIN + ":verify"); 34 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 35 | } 36 | 37 | public void testLibdocMojo() throws IOException, VerificationException { 38 | executeGoals(PLUGIN + ":libdoc"); 39 | assertFilePresent("target/robotframework/libdoc/JustForIT.html"); 40 | } 41 | 42 | public void testOverrideFromCommandPrompt() throws IOException, VerificationException { 43 | cliOptions.add("-Dtests=successful*"); 44 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 45 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 46 | } 47 | 48 | public void testOverrideListsFromCommandPrompt() throws IOException, VerificationException { 49 | cliOptions.add("-Dtests=foo,successful*,bar"); 50 | cliOptions.add("-Dsuites=foo,successful*,bar"); 51 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 52 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 53 | } 54 | 55 | public void testPomWithTestsConfigured() throws IOException, VerificationException { 56 | cliOptions.add("-f"); 57 | cliOptions.add("pom_with_tests_configured.xml"); 58 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 59 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 60 | } 61 | 62 | public void testVerificationIgnoresNonCritical() throws IOException, VerificationException { 63 | cliOptions.add("-f"); 64 | cliOptions.add("pom_with_noncritical_failures.xml"); 65 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 66 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 67 | } 68 | 69 | public void testPomWithTestsConfiguredOverridden() throws IOException, VerificationException { 70 | cliOptions.add("-f"); 71 | cliOptions.add("pom_with_tests_configured.xml"); 72 | cliOptions.add("-Dtests=failing*"); 73 | executeFailingGoals(PLUGIN + ":acceptance-test", PLUGIN + ":verify"); 74 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 75 | } 76 | 77 | public void testOverrideVariable() throws IOException, VerificationException { 78 | cliOptions.add("-f"); 79 | cliOptions.add("pom_with_tests_configured.xml"); 80 | cliOptions.add("-Dtests=FailingBasedOnVariable"); 81 | cliOptions.add("-Dvariables=VariableThatShouldBeOverridden:permanent,ExtraVariableFromPrompt:overridden"); 82 | executeGoals(PLUGIN + ":acceptance-test", PLUGIN + ":verify"); 83 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 84 | } 85 | 86 | public void testClasspath() throws IOException, VerificationException { 87 | cliOptions.add("-f"); 88 | cliOptions.add("pom_with_classpaths.xml"); 89 | executeGoals(PLUGIN + ":acceptance-test", PLUGIN + ":verify"); 90 | assertFilePresent("target/robotframework-reports/TEST-classpath-acceptance.xml"); 91 | } 92 | 93 | public void testWithoutClasspath() throws IOException, VerificationException { 94 | cliOptions.add("-f"); 95 | cliOptions.add("pom_without_classpaths.xml"); 96 | executeGoals(PLUGIN + ":acceptance-test", PLUGIN + ":verify"); 97 | assertFilePresent("target/robotframework-reports/TEST-classpath-acceptance.xml"); 98 | } 99 | 100 | public void testPomWithExternalRunner() throws IOException, VerificationException { 101 | cliOptions.add("-f"); 102 | cliOptions.add("pom_with_external_runner.xml"); 103 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 104 | assertFilePresent("target/robotframework-reports/TEST-acceptance.xml"); 105 | } 106 | 107 | public void testVerificationIsSkippedIfTestsAre() throws IOException, VerificationException { 108 | cliOptions.add("-DskipATs"); 109 | executeGoals(PLUGIN + ":acceptance-test",PLUGIN + ":verify"); 110 | } 111 | 112 | private void assertFilePresent(String file) { 113 | verifier.assertFilePresent(new File(testDir, file).getAbsolutePath()); 114 | } 115 | 116 | private void executeGoals(String... goals) throws VerificationException, IOException { 117 | verifier.setCliOptions(cliOptions); 118 | verifier.deleteDirectory("target/robotframework-reports"); 119 | verifier.deleteDirectory("target/robotframework"); 120 | verifier.executeGoals(Arrays.asList(goals)); 121 | verifier.displayStreamBuffers(); 122 | verifier.resetStreams(); 123 | } 124 | 125 | private void executeFailingGoals(String... goals) throws IOException { 126 | verifier.setCliOptions(cliOptions); 127 | verifier.deleteDirectory("target/robotframework-reports"); 128 | verifier.deleteDirectory("target/robotframework"); 129 | try { 130 | verifier.executeGoals(Arrays.asList(goals)); 131 | fail("verify goal should fail the build"); 132 | } catch (VerificationException e) { 133 | String message = e.getMessage(); 134 | assertThat(message, containsString("There are acceptance test failures")); 135 | System.out.println(message); 136 | } 137 | verifier.displayStreamBuffers(); 138 | verifier.resetStreams(); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/AcceptanceTestMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.hasXPath; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import javax.xml.parsers.DocumentBuilder; 10 | import javax.xml.parsers.DocumentBuilderFactory; 11 | import javax.xml.parsers.ParserConfigurationException; 12 | 13 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 14 | import org.w3c.dom.Document; 15 | import org.xml.sax.SAXException; 16 | 17 | 18 | public class AcceptanceTestMojoTest 19 | extends AbstractMojoTestCase { 20 | 21 | public void setup() 22 | throws Exception { 23 | super.setUp(); 24 | } 25 | 26 | public void testShouldSucceed() 27 | throws Exception { 28 | File pom = getTestFile("src/test/resources/pom-success.xml"); 29 | AcceptanceTestMojo mojo = (AcceptanceTestMojo) lookupMojo("acceptance-test", pom); 30 | mojo.execute(); 31 | File xunitFile = getTestFile("target/robotframework-reports/TEST-robot-success.xml"); 32 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 33 | 34 | Document xunit = parseDocument(xunitFile); 35 | assertThat(xunit, hasXPath("/testsuite[@errors='0']")); 36 | assertThat(xunit, hasXPath("/testsuite[@failures='0']")); 37 | assertThat(xunit, hasXPath("/testsuite[@tests='2']")); 38 | } 39 | 40 | public void testShouldFail() 41 | throws Exception { 42 | File pom = getTestFile("src/test/resources/pom-fail.xml"); 43 | AcceptanceTestMojo mojo = (AcceptanceTestMojo) lookupMojo("acceptance-test", pom); 44 | 45 | mojo.execute(); 46 | 47 | // output.xml contains failure 48 | File xunitFile = getTestFile("target/robotframework-reports/TEST-robot-fail.xml"); 49 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 50 | 51 | Document xunit = parseDocument(xunitFile); 52 | 53 | assertThat(xunit, hasXPath("/testsuite[@failures='5']")); 54 | assertThat(xunit, hasXPath("/testsuite[@errors='0']")); 55 | assertThat(xunit, hasXPath("/testsuite[@tests='5']")); 56 | 57 | assertThat(xunit, hasXPath("//failure[@message = '1.0 != 2.0']")); 58 | assertThat(xunit, hasXPath("//failure[@message = '4.0 != 5.0']")); 59 | assertThat(xunit, hasXPath("//failure[@message = '5.0 != 6.0']")); 60 | assertThat(xunit, hasXPath("//failure[@message = '9.0 != 10.0']")); 61 | assertThat(xunit, hasXPath("//failure[@message = '11.0 != 12.0']")); 62 | 63 | } 64 | 65 | private Document parseDocument(File xunitFile) 66 | throws ParserConfigurationException, SAXException, IOException { 67 | DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 68 | DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); 69 | Document xunit = builder.parse(xunitFile); 70 | return xunit; 71 | } 72 | 73 | public void testHsqlShouldPass() 74 | throws Exception { 75 | File pom = getTestFile("src/test/resources/pom-hsqldb.xml"); 76 | AcceptanceTestMojo mojo = (AcceptanceTestMojo) lookupMojo("acceptance-test", pom); 77 | mojo.execute(); 78 | 79 | File xunitFile = getTestFile("target/robotframework-reports/TEST-robot-hsqldb.xml"); 80 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 81 | 82 | Document xunit = parseDocument(xunitFile); 83 | assertThat(xunit, hasXPath("/testsuite[@errors='0']")); 84 | assertThat(xunit, hasXPath("/testsuite[@failures='0']")); 85 | } 86 | 87 | public void testErrorSuiteNotFound() 88 | throws Exception { 89 | File pom = getTestFile("src/test/resources/pom-error.xml"); 90 | AcceptanceTestMojo mojo = (AcceptanceTestMojo) lookupMojo("acceptance-test", pom); 91 | mojo.execute(); 92 | File xunitFile = getTestFile("target/robotframework-reports/TEST-nothing-here.xml"); 93 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 94 | 95 | Document xunit = parseDocument(xunitFile); 96 | assertThat(xunit, hasXPath("/testsuite[@errors='1']")); 97 | assertThat(xunit, hasXPath("/testsuite/testcase/error[@message = 'Invalid test data or command line options (Returncode 252).']")); 98 | } 99 | 100 | public void testErrorInTestCase() { 101 | // TODO assert that xunitfile is not overwritten, if available 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/ArgumentsTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.File; 4 | 5 | import junit.framework.TestCase; 6 | 7 | 8 | public class ArgumentsTest 9 | extends TestCase { 10 | 11 | public void testNONEFilePathParsing() { 12 | Arguments args = new Arguments(); 13 | args.addFileToArguments(new File(new File("NONE").getAbsolutePath()), "-l"); 14 | assertEquals("NONE", args.toArray()[1]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/ExampleLib.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | /** 4 | * Library for demo purposes. This library is only used in an example and it does't do anything useful. 5 | */ 6 | public class ExampleLib { 7 | 8 | /** 9 | * Does nothing 10 | */ 11 | public void myKeyword() { 12 | } 13 | 14 | /** 15 | * Takes one argument and *does nothing* with it. Example: | Your Keyword | xxx | | Your Keyword | yyy | 16 | */ 17 | public void yourKeyword(String arg) { 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/LibDocMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.File; 4 | 5 | 6 | public class LibDocMojoTest 7 | extends AbstractRFMojoTestCase { 8 | 9 | private final String outputDirectory = "target/robotframework/libdoc/"; 10 | private final String htmlResourceLibDoc = outputDirectory + "html_resource.html"; 11 | private final String javalibLibDoc = outputDirectory + "ExampleLib.html"; 12 | private final String mylibLibDoc = outputDirectory + "mylib.html"; 13 | private final String mypackageMylibLibDoc = outputDirectory + "mypackage.mylib.html"; 14 | 15 | protected void setUp() 16 | throws Exception { 17 | super.setUp(); 18 | File outputDir = new File(outputDirectory); 19 | outputDir.mkdirs(); 20 | deleteDocument(htmlResourceLibDoc); 21 | deleteDocument(javalibLibDoc); 22 | deleteDocument(mylibLibDoc); 23 | deleteDocument(mypackageMylibLibDoc); 24 | } 25 | 26 | public void testLibDocForJavaResource() 27 | throws Exception { 28 | executeLibdocWithPom("libdoc", "src/test/resources/pom-libdoc.xml"); 29 | assertTrue(javalibLibDoc + " not found", new File(javalibLibDoc).exists()); 30 | } 31 | 32 | public void testLibDocForTxtResource() 33 | throws Exception { 34 | executeLibdocWithPom("libdoc", "src/test/resources/pom-libdoc-robotfile.xml"); 35 | assertTrue(htmlResourceLibDoc + " not found", new File(htmlResourceLibDoc).exists()); 36 | 37 | } 38 | 39 | public void testLibDocForLibraryNamePython() 40 | throws Exception { 41 | 42 | executeLibdocWithPom("libdoc", "src/test/resources/pom-libdoc-libraryname-python.xml"); 43 | assertTrue(mylibLibDoc + " not found", new File(mylibLibDoc).exists()); 44 | 45 | } 46 | 47 | public void testLibDocForLibraryNamePythonWithPackage() 48 | throws Exception { 49 | executeLibdocWithPom("libdoc", "src/test/resources/pom-libdoc-libraryname-python-subpackage.xml"); 50 | assertTrue(mypackageMylibLibDoc + " not found", new File(mypackageMylibLibDoc).exists()); 51 | 52 | } 53 | 54 | public void testLibDocForLibraryNameJava() 55 | throws Exception { 56 | executeLibdocWithPom("libdoc", "src/test/resources/pom-libdoc-libraryname-java.xml"); 57 | assertTrue(javalibLibDoc + " not found", new File(javalibLibDoc).exists()); 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/RebotMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.hasXPath; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import javax.xml.parsers.DocumentBuilder; 10 | import javax.xml.parsers.DocumentBuilderFactory; 11 | import javax.xml.parsers.ParserConfigurationException; 12 | 13 | import org.apache.commons.io.FileUtils; 14 | import org.apache.maven.plugin.MojoExecutionException; 15 | import org.apache.maven.plugin.MojoFailureException; 16 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 17 | import org.w3c.dom.Document; 18 | import org.xml.sax.SAXException; 19 | 20 | public class RebotMojoTest extends AbstractMojoTestCase { 21 | 22 | public void setup() throws Exception { 23 | super.setUp(); 24 | File outputDirectory = getTestFile("target/robotframework-report"); 25 | outputDirectory.delete(); 26 | } 27 | 28 | public void testReportSuccess() throws Exception { 29 | File pom = getTestFile("src/test/resources/pom-rebot.xml"); 30 | this.executeRebotMojo(pom); 31 | File xunitFile = getTestFile("target/robotframework-reports/rebot/TEST-robot-success.xml"); 32 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 33 | 34 | Document xunit = parseDocument(xunitFile); 35 | assertThat(xunit, hasXPath("/testsuite[@errors='0']")); 36 | assertThat(xunit, hasXPath("/testsuite[@failures='0']")); 37 | assertThat(xunit, hasXPath("/testsuite[@tests='4']")); 38 | } 39 | 40 | public void testReportSuccessMerged() throws Exception { 41 | File pom = getTestFile("src/test/resources/pom-rebot-merged.xml"); 42 | this.executeRebotMojo(pom); 43 | File xunitFile = getTestFile("target/robotframework-reports/rebot/TEST-robot-success-merged.xml"); 44 | assertTrue("missing xunit test report " + xunitFile, xunitFile.exists()); 45 | 46 | Document xunit = parseDocument(xunitFile); 47 | assertThat(xunit, hasXPath("/testsuite[@errors='0']")); 48 | assertThat(xunit, hasXPath("/testsuite[@failures='0']")); 49 | //As same suite is runned twice, merge shows only 2 runs. Rebot knows that the cases 50 | //area same, and includes results in the cases itself. 51 | assertThat(xunit, hasXPath("/testsuite[@tests='2']")); 52 | } 53 | 54 | private Document parseDocument(File xunitFile) throws ParserConfigurationException, SAXException, IOException { 55 | DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 56 | DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); 57 | Document xunit = builder.parse(xunitFile); 58 | return xunit; 59 | } 60 | 61 | private void executeRebotMojo(File pom) 62 | throws MojoExecutionException, MojoFailureException { 63 | RebotMojo mojo; 64 | try { 65 | mojo = (RebotMojo) lookupMojo("rebot", pom); 66 | File outputDirectory = getTestFile("src/test/resources/output-for-rebot/"); 67 | File targetDirectory = (File) getVariableValueFromObject(mojo, "outputDirectory"); 68 | File[] files = outputDirectory.listFiles(); 69 | for (int i = 0; i < files.length; i++) { 70 | FileUtils.copyFileToDirectory(files[i], targetDirectory); 71 | } 72 | } catch (Exception ex) { 73 | throw new RuntimeException("failed to prepare mojo execution", ex); 74 | } 75 | mojo.execute(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/RobotFrameworkMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import org.apache.maven.plugin.MojoExecutionException; 4 | import org.apache.maven.plugin.MojoFailureException; 5 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 6 | 7 | 8 | import java.io.File; 9 | 10 | public class RobotFrameworkMojoTest 11 | extends AbstractMojoTestCase { 12 | 13 | public void setup() 14 | throws Exception { 15 | super.setUp(); 16 | } 17 | 18 | public void testShouldSucceed() 19 | throws Exception { 20 | File pom = getTestFile("src/test/resources/pom-success.xml"); 21 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 22 | mojo.execute(); 23 | } 24 | 25 | public void testRunmodesShouldWork() 26 | throws Exception { 27 | File pom = getTestFile("src/test/resources/pom-runmodes.xml"); 28 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 29 | mojo.execute(); 30 | } 31 | 32 | 33 | public void testShouldSucceedWithExternalRunner() 34 | throws Exception { 35 | File pom = getTestFile("src/test/resources/pom-configure-runner.xml"); 36 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 37 | mojo.execute(); 38 | } 39 | 40 | public void testShouldFail() 41 | throws Exception { 42 | File pom = getTestFile("src/test/resources/pom-fail.xml"); 43 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 44 | try { 45 | mojo.execute(); 46 | fail("robot tests should have failed"); 47 | } catch (MojoFailureException e) { 48 | assertTrue(true); 49 | } 50 | } 51 | 52 | public void testHsqlShouldPass() 53 | throws Exception { 54 | File pom = getTestFile("src/test/resources/pom-hsqldb.xml"); 55 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 56 | mojo.execute(); 57 | } 58 | 59 | public void testShouldHaveErrors() 60 | throws Exception { 61 | 62 | File pom = getTestFile("src/test/resources/pom-error.xml"); 63 | RobotFrameworkMojo mojo = (RobotFrameworkMojo) lookupMojo("run", pom); 64 | try { 65 | mojo.execute(); 66 | fail("robot tests should have errors"); 67 | } catch (MojoExecutionException e) { 68 | assertTrue(true); 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/RobotFrameworkSkipTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.maven.plugin.MojoExecutionException; 6 | import org.apache.maven.plugin.MojoFailureException; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.powermock.api.mockito.PowerMockito; 11 | import org.powermock.core.classloader.annotations.PrepareForTest; 12 | import org.powermock.modules.junit4.PowerMockRunner; 13 | import org.powermock.reflect.Whitebox; 14 | import org.robotframework.RobotFramework; 15 | 16 | @RunWith(PowerMockRunner.class) 17 | @PrepareForTest(RobotFramework.class) 18 | public class RobotFrameworkSkipTest { 19 | 20 | private RobotFrameworkMojo robotFrameworkMojo; 21 | 22 | @Before 23 | public void setUp() { 24 | PowerMockito.mockStatic(RobotFramework.class); 25 | robotFrameworkMojo = new RobotFrameworkMojo(); 26 | } 27 | 28 | @Test 29 | public void testSkipTests() 30 | throws MojoExecutionException, MojoFailureException { 31 | Whitebox.setInternalState(robotFrameworkMojo, "skipTests", true); 32 | robotFrameworkMojo.execute(); 33 | } 34 | 35 | @Test 36 | public void testSkip() 37 | throws MojoExecutionException, MojoFailureException { 38 | Whitebox.setInternalState(robotFrameworkMojo, "skip", true); 39 | robotFrameworkMojo.execute(); 40 | } 41 | 42 | @Test 43 | public void testSkipATs() 44 | throws MojoExecutionException, MojoFailureException { 45 | Whitebox.setInternalState(robotFrameworkMojo, "skipATs", true); 46 | robotFrameworkMojo.execute(); 47 | } 48 | 49 | @Test 50 | public void testSkipITs() 51 | throws MojoExecutionException, MojoFailureException { 52 | Whitebox.setInternalState(robotFrameworkMojo, "skipITs", true); 53 | robotFrameworkMojo.execute(); 54 | } 55 | 56 | @Test 57 | public void testDontSkip() 58 | throws MojoExecutionException, MojoFailureException { 59 | String testsFolder = "tests"; 60 | Whitebox.setInternalState(robotFrameworkMojo, "testCasesDirectory", new File(testsFolder)); 61 | robotFrameworkMojo.execute(); 62 | 63 | PowerMockito.verifyStatic(RobotFramework.class); 64 | RobotFramework.run(new String[]{"-x", "TEST-tests.xml", "--xunitskipnoncritical", testsFolder}); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/TestDocMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import java.io.File; 4 | import java.nio.charset.Charset; 5 | 6 | import org.apache.commons.io.FileUtils; 7 | 8 | 9 | public class TestDocMojoTest 10 | extends AbstractRFMojoTestCase { 11 | 12 | private final String outputDirectory = "target/robotframework/testdoc/"; 13 | 14 | protected void setUp() 15 | throws Exception { 16 | super.setUp(); 17 | File outputDir = new File(outputDirectory); 18 | outputDir.mkdirs(); 19 | } 20 | 21 | public void testTestDocForTxtResource() 22 | throws Exception { 23 | executeLibdocWithPom("testdoc", "src/test/resources/pom-testdoc-robotfile.xml"); 24 | String txtResourceTestDoc = outputDirectory + "invalid.html"; 25 | assertTrue(txtResourceTestDoc + " not found", new File(txtResourceTestDoc).exists()); 26 | } 27 | 28 | public void testTestDocForTxtResourceWithTitle() 29 | throws Exception { 30 | executeLibdocWithPom("testdoc", "src/test/resources/pom-testdoc-robotfile-title.xml"); 31 | String txtResourceWithTitleTestDoc = outputDirectory + "invalid_login_title.html"; 32 | assertTrue(txtResourceWithTitleTestDoc + " not found", new File(txtResourceWithTitleTestDoc).exists()); 33 | String contents = FileUtils.readFileToString(new File(txtResourceWithTitleTestDoc), Charset.defaultCharset()); 34 | assertTrue(contents.contains("\"title\":\"Custom Title\"")); 35 | } 36 | 37 | public void testTestDocForTxtResourceWithName() 38 | throws Exception { 39 | executeLibdocWithPom("testdoc", "src/test/resources/pom-testdoc-robotfile-name.xml"); 40 | String txtResourceWithNameTestDoc = outputDirectory + "invalid_login_name.html"; 41 | assertTrue(txtResourceWithNameTestDoc + " not found", new File(txtResourceWithNameTestDoc).exists()); 42 | String contents = FileUtils.readFileToString(new File(txtResourceWithNameTestDoc), Charset.defaultCharset()); 43 | assertTrue(contents.contains("\"fullName\":\"Custom name\"")); 44 | } 45 | 46 | public void testTestDocForTxtResourceWithDoc() 47 | throws Exception { 48 | executeLibdocWithPom("testdoc", "src/test/resources/pom-testdoc-robotfile-doc.xml"); 49 | String txtResourceWithDocTestDoc = outputDirectory + "invalid_login_doc.html"; 50 | assertTrue(txtResourceWithDocTestDoc + " not found", new File(txtResourceWithDocTestDoc).exists()); 51 | String contents = FileUtils.readFileToString(new File(txtResourceWithDocTestDoc), Charset.defaultCharset()); 52 | assertTrue(contents.contains("\"doc\":\"

Custom documentation")); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/VerifyMojoTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.containsString; 5 | 6 | import java.io.File; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.OutputStream; 11 | 12 | import org.apache.maven.plugin.MojoExecutionException; 13 | import org.apache.maven.plugin.MojoFailureException; 14 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 15 | 16 | 17 | public class VerifyMojoTest 18 | extends AbstractMojoTestCase { 19 | 20 | public void setup() 21 | throws Exception { 22 | super.setUp(); 23 | File outputDirectory = getTestFile("target/robotframework-report"); 24 | outputDirectory.delete(); 25 | } 26 | 27 | public void testReportSuccess() 28 | throws Exception { 29 | File pom = getTestFile("src/test/resources/pom-success.xml"); 30 | String xunitResult = "/xunitresults/TEST-robot-success.xml"; 31 | executeVerifyMojo(pom, xunitResult); 32 | 33 | } 34 | 35 | public void testReportFgailure() 36 | throws Exception { 37 | File pom = getTestFile("src/test/resources/pom-fail.xml"); 38 | String xunitResult = "/xunitresults/TEST-robot-fail.xml"; 39 | try { 40 | executeVerifyMojo(pom, xunitResult); 41 | fail("MojoFailureException expected"); 42 | } catch (MojoFailureException ex) { 43 | assertThat(ex.getMessage(), containsString("failure")); 44 | } 45 | } 46 | 47 | public void testReportError() 48 | throws Exception { 49 | File pom = getTestFile("src/test/resources/pom-error.xml"); 50 | String xunitResult = "/xunitresults/TEST-nothing-here.xml"; 51 | try { 52 | executeVerifyMojo(pom, xunitResult); 53 | fail("MojoFailureException expected"); 54 | } catch (MojoFailureException ex) { 55 | assertThat(ex.getMessage(), containsString("There are acceptance test failures")); 56 | } 57 | } 58 | 59 | private void executeVerifyMojo(File pom, String xunitResult) 60 | throws MojoExecutionException, MojoFailureException { 61 | VerifyMojo mojo; 62 | try { 63 | mojo = (VerifyMojo) lookupMojo("verify", pom); 64 | 65 | File xunitFile = (File) getVariableValueFromObject(mojo, "xunitFile"); 66 | File outputDirectory = (File) getVariableValueFromObject(mojo, "outputDirectory"); 67 | 68 | // copy from resources: 69 | InputStream resultFileInputStream = this.getClass().getResourceAsStream(xunitResult); 70 | copyXunitReport(resultFileInputStream, outputDirectory, xunitFile); 71 | } catch (Exception ex) { 72 | throw new RuntimeException("failed to prepare mojo execution", ex); 73 | } 74 | mojo.execute(); 75 | } 76 | 77 | private void copyXunitReport(InputStream resultFileInput, File outputDirectory, File targetFile) 78 | throws IOException { 79 | File xunitOutput = getXunitOutput(outputDirectory, targetFile); 80 | 81 | OutputStream out = new FileOutputStream(xunitOutput); 82 | byte[] bytes = new byte[1024]; 83 | int len; 84 | while (-1 != (len = resultFileInput.read(bytes))) { 85 | out.write(bytes, 0, len); 86 | } 87 | 88 | } 89 | 90 | private File getXunitOutput(File outputDirectory, File xunitFile) { 91 | outputDirectory.mkdirs(); 92 | if (!xunitFile.isAbsolute()) 93 | return new File(outputDirectory, xunitFile.getName()); 94 | return xunitFile; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/A.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | public class A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/AntPatternClassPredicateTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class AntPatternClassPredicateTest { 9 | 10 | @Test 11 | public void testApplySimple() throws Exception { 12 | // test data 13 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("*.List"); 14 | 15 | // do the test 16 | assertTrue(predicate.apply("java.util.List")); 17 | assertFalse(predicate.apply("java.awt.Window")); 18 | } 19 | 20 | @Test 21 | public void testApplySimple1() throws Exception { 22 | // test data 23 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("java.**.A"); 24 | 25 | // do the test 26 | assertTrue(predicate.apply("java.util.butil.A")); 27 | assertFalse(predicate.apply("java.awt.Window")); 28 | } 29 | 30 | @Test 31 | public void testApplySimplePattern2() throws Exception { 32 | // test data 33 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("java.util.*List"); 34 | 35 | // do the test 36 | assertTrue(predicate.apply("java.util.ArrayList")); 37 | assertFalse(predicate.apply("java.awt.Window")); 38 | } 39 | 40 | @Test 41 | public void testApplyNoPattern() throws Exception { 42 | // test data 43 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("java.util.List"); 44 | 45 | // do the test 46 | assertTrue(predicate.apply("java.util.List")); 47 | assertFalse(predicate.apply("java.awt.Window")); 48 | } 49 | 50 | @Test 51 | public void testApplyRecursive() throws Exception { 52 | // test data 53 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("java.**.List"); 54 | 55 | // do the test 56 | assertTrue(predicate.apply("java.util.List")); 57 | assertTrue(predicate.apply("java.bla.bla.bla.List")); 58 | } 59 | 60 | @Test 61 | public void testAppliesIgnoresSuffixed() throws Exception { 62 | // test data 63 | AntPatternClassPredicate predicate = new AntPatternClassPredicate("java.**.List"); 64 | 65 | // do the test 66 | assertTrue(predicate.apply("java.util.List.class")); 67 | assertFalse(predicate.apply("java.bla.bla.bla.List.classs")); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/B.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | public class B extends A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/ClassNameHarvesterTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Set; 6 | 7 | import org.junit.Test; 8 | 9 | public class ClassNameHarvesterTest { 10 | 11 | public static class A { 12 | 13 | } 14 | 15 | public static class B extends A { 16 | 17 | } 18 | 19 | @Test 20 | public void testHarvestSimple() throws Exception { 21 | // prepare data 22 | String pattern = "java.util.List"; 23 | 24 | // do the test 25 | NameHarvester harv = new ClassNameHarvester(); 26 | Set result = harv.harvest(pattern); 27 | 28 | // checks 29 | assertEquals(1, result.size()); 30 | String r = result.iterator().next(); 31 | assertEquals(pattern, r); 32 | } 33 | 34 | @Test 35 | public void testHarvestSimplePattern() throws Exception { 36 | // prepare data 37 | String pattern = "org.**.*ClassNameHarvester"; 38 | 39 | // do the test 40 | NameHarvester harv = new ClassNameHarvester(); 41 | Set result = harv.harvest(pattern); 42 | 43 | // checks 44 | assertEquals(1, result.size()); 45 | String r = result.iterator().next(); 46 | assertEquals("org.robotframework.mavenplugin.harvesters.ClassNameHarvester", r); 47 | } 48 | 49 | @Test 50 | public void testHarvestSimplePattern1() throws Exception { 51 | // prepare data 52 | String pattern = "org.**.B"; 53 | 54 | // do the test 55 | NameHarvester harv = new ClassNameHarvester(); 56 | Set result = harv.harvest(pattern); 57 | 58 | // checks 59 | assertEquals(1, result.size()); 60 | String r = result.iterator().next(); 61 | assertEquals("org.robotframework.mavenplugin.harvesters.B", r); 62 | } 63 | 64 | @Test 65 | public void testHarvestSimplePattern2() throws Exception { 66 | // prepare data. 67 | // There's Class A from other package, too, so has to be more specific 68 | String pattern = "org.robotframework.**.A"; 69 | 70 | // do the test 71 | NameHarvester harv = new ClassNameHarvester(); 72 | Set result = harv.harvest(pattern); 73 | 74 | // checks 75 | assertEquals(1, result.size()); 76 | String r = result.iterator().next(); 77 | assertEquals("org.robotframework.mavenplugin.harvesters.A", r); 78 | } 79 | 80 | @Test 81 | public void testHarvestSimplePatternWithInners() throws Exception { 82 | // prepare data 83 | String pattern = "org.**.ClassNameHarvesterTest$A"; 84 | 85 | // do the test 86 | NameHarvester harv = new ClassNameHarvester(); 87 | Set result = harv.harvest(pattern); 88 | 89 | // checks 90 | assertEquals(1, result.size()); 91 | String r = result.iterator().next(); 92 | assertEquals("org.robotframework.mavenplugin.harvesters.ClassNameHarvesterTest$A", r); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/HarvestUtilsTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.io.File; 7 | 8 | import org.junit.Test; 9 | 10 | public class HarvestUtilsTest { 11 | 12 | @Test 13 | public void testExtractName() throws Exception { 14 | 15 | assertEquals("Blabla", HarvestUtils.extractName("com.xxx.Blabla")); 16 | assertEquals("Blabla", HarvestUtils.extractName("Blabla.java")); 17 | assertEquals("Blabla", HarvestUtils.extractName("c:\\xxx\\Blabla.java")); 18 | assertEquals("Blabla", HarvestUtils.extractName("/xxx/Blabla.java")); 19 | } 20 | 21 | @Test 22 | public void testGenerateIdName() throws Exception { 23 | assertEquals("b_c_d_e", HarvestUtils.generateIdName("b/c\\d.e")); 24 | } 25 | 26 | @Test 27 | public void testExtractExtension() throws Exception { 28 | assertEquals(".java", HarvestUtils.extractExtension("Blabla.java")); 29 | assertEquals("", HarvestUtils.extractExtension("Blabla")); 30 | assertEquals(".java", HarvestUtils.extractExtension(".java")); 31 | assertEquals(".java", HarvestUtils.extractExtension("*.java")); 32 | 33 | assertEquals(".java", HarvestUtils.extractExtension(new File(".java").getName())); 34 | assertEquals(".java", HarvestUtils.extractExtension(new File("*.java").getName())); 35 | 36 | } 37 | 38 | @Test 39 | public void testIsAbsolutePathFragment() throws Exception { 40 | // Supports Linux and Windows only, on local file systems, so no UNC, 41 | // etc. 42 | 43 | if (File.separatorChar == '\\') { 44 | assertTrue(HarvestUtils.isAbsolutePathFragment("c:\\bla\\*.java")); 45 | } else { 46 | assertTrue(HarvestUtils.isAbsolutePathFragment("/bla/*.java")); 47 | } 48 | } 49 | 50 | @Test 51 | public void testRemovePrefixDirectory() throws Exception { 52 | if (File.separatorChar == '\\') { 53 | assertEquals("bla.java", HarvestUtils.removePrefixDirectory(new File("c:\\bla"), "c:\\bla\\bla.java")); 54 | assertEquals("bla.java", HarvestUtils.removePrefixDirectory(new File("c:\\bla\\"), "c:\\bla\\bla.java")); 55 | } else { 56 | assertEquals("bla.java", HarvestUtils.removePrefixDirectory(new File("/bla"), "/bla/bla.java")); 57 | assertEquals("bla.java", HarvestUtils.removePrefixDirectory(new File("/bla/"), "/bla/bla.java")); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/ResourceNameHarvesterTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.util.Set; 7 | 8 | import org.junit.Test; 9 | 10 | public class ResourceNameHarvesterTest { 11 | 12 | @Test 13 | public void testHarvestResourcesSimpleNonMatching() throws Exception { 14 | // prepare data 15 | String pattern = "xxx.py"; 16 | 17 | // do the test 18 | NameHarvester harv = new ResourceNameHarvester(); 19 | Set result = harv.harvest(pattern); 20 | 21 | // checks 22 | assertEquals(1, result.size()); 23 | String r = result.iterator().next(); 24 | assertEquals(pattern, r); 25 | } 26 | 27 | @Test 28 | public void testHarvestPythonResourcesLargeMatch() throws Exception { 29 | // prepare data 30 | String pattern = "*.py"; 31 | 32 | // do the test 33 | NameHarvester harv = new ResourceNameHarvester(); 34 | Set result = harv.harvest(pattern); 35 | 36 | // checks 37 | assertTrue(result.size() > 1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/robotframework/mavenplugin/harvesters/SourceFileNameHarvesterTest.java: -------------------------------------------------------------------------------- 1 | package org.robotframework.mavenplugin.harvesters; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | 12 | import org.apache.commons.io.FileUtils; 13 | import org.junit.After; 14 | import org.junit.Before; 15 | import org.junit.Test; 16 | 17 | public class SourceFileNameHarvesterTest { 18 | 19 | public volatile File workingDirectory = new File(new File(System.getProperty("user.dir")), 20 | SourceFileNameHarvesterTest.class.getCanonicalName()); 21 | 22 | @Before 23 | public void setup() throws IOException { 24 | if (workingDirectory.isDirectory()) { 25 | FileUtils.deleteDirectory(workingDirectory); 26 | } else { 27 | if (workingDirectory.isFile()) 28 | assertTrue(workingDirectory.delete()); 29 | else 30 | assertTrue(workingDirectory.mkdir()); 31 | } 32 | } 33 | 34 | @After 35 | public void teardown() throws IOException { 36 | if (workingDirectory.isDirectory()) { 37 | FileUtils.deleteDirectory(workingDirectory); 38 | } else { 39 | if (workingDirectory.isFile()) 40 | workingDirectory.delete(); 41 | } 42 | } 43 | 44 | @Test 45 | public void testHarvestFilesSimple() throws Exception { 46 | // create some files 47 | File testFile1 = new File(workingDirectory, "bla.java"); 48 | assertTrue(testFile1.createNewFile()); 49 | String pattern = workingDirectory.getAbsolutePath() + File.separator + "*.java"; 50 | 51 | // do the test 52 | NameHarvester h = new SourceFileNameHarvester(workingDirectory); 53 | Set result = h.harvest(pattern); 54 | 55 | // Checks 56 | assertEquals(1, result.size()); 57 | String t = result.iterator().next(); 58 | assertEquals(testFile1.getAbsolutePath(), t); 59 | } 60 | 61 | @Test 62 | public void testHarvestFilesSeveralButStillSimplerPattern() throws Exception { 63 | // create some files 64 | File testFile1 = new File(workingDirectory, "bla.java"); 65 | assertTrue(testFile1.createNewFile()); 66 | File testFile2 = new File(workingDirectory, "deeper" + File.separator + "bla.java"); 67 | assertTrue(testFile2.getParentFile().mkdirs()); 68 | assertTrue(testFile2.createNewFile()); 69 | 70 | String pattern = workingDirectory.getAbsolutePath() + File.separator + "*.java"; 71 | 72 | // do the test 73 | NameHarvester h = new SourceFileNameHarvester(workingDirectory); 74 | Set result = h.harvest(pattern); 75 | 76 | // Checks 77 | assertEquals(1, result.size()); 78 | String t = result.iterator().next(); 79 | assertEquals(testFile1.getAbsolutePath(), t); 80 | } 81 | 82 | @Test 83 | public void testHarvestFilesSeveralRecursivePattern() throws Exception { 84 | // create some files 85 | File testFile1 = new File(workingDirectory, "bla.java"); 86 | assertTrue(testFile1.createNewFile()); 87 | File testFile2 = new File(workingDirectory, 88 | "deeper" + File.separator + "deeper_still" + File.separator + "bla.java"); 89 | assertTrue(testFile2.getParentFile().mkdirs()); 90 | assertTrue(testFile2.createNewFile()); 91 | 92 | String pattern = workingDirectory.getAbsolutePath() + File.separator + "**" + File.separator + "*.java"; 93 | 94 | // do the test 95 | NameHarvester h = new SourceFileNameHarvester(workingDirectory); 96 | Set result = h.harvest(pattern); 97 | 98 | // Checks 99 | assertEquals(2, result.size()); 100 | 101 | HashSet tr = new HashSet(result); 102 | assertTrue(tr.contains(testFile1.getAbsolutePath())); 103 | assertTrue(tr.contains(testFile2.getAbsolutePath())); 104 | 105 | } 106 | 107 | @Test 108 | public void testHarvestFilesSeveralRecursivePatternSlash() throws Exception { 109 | // create some files 110 | File testFile1 = new File(workingDirectory, "bla.java"); 111 | assertTrue(testFile1.createNewFile()); 112 | File testFile2 = new File(workingDirectory, 113 | "deeper" + File.separator + "deeper_still" + File.separator + "bla.java"); 114 | assertTrue(testFile2.getParentFile().mkdirs()); 115 | assertTrue(testFile2.createNewFile()); 116 | 117 | String pattern = workingDirectory.getAbsolutePath() + File.separator + "**" + File.separator + "*.java"; 118 | 119 | // do the test 120 | NameHarvester h = new SourceFileNameHarvester(workingDirectory); 121 | Set result = h.harvest(pattern); 122 | 123 | // Checks 124 | assertEquals(2, result.size()); 125 | 126 | HashSet tr = new HashSet(result); 127 | assertTrue(tr.contains(testFile1.getAbsolutePath())); 128 | assertTrue(tr.contains(testFile2.getAbsolutePath())); 129 | 130 | } 131 | 132 | @Test 133 | public void testHarvestFilesSeveralRecursivePatternSlashRelativePattern() throws Exception { 134 | 135 | // create some files 136 | File testFile1 = new File(workingDirectory, "bla.java"); 137 | assertTrue(testFile1.createNewFile()); 138 | File testFile2 = new File(workingDirectory, 139 | "deeper" + File.separator + "deeper_still" + File.separator + "bla.java"); 140 | assertTrue(testFile2.getParentFile().mkdirs()); 141 | assertTrue(testFile2.createNewFile()); 142 | 143 | String pattern = "deeper" + File.separator + "**" + File.separator + "*.java"; 144 | 145 | // do the test 146 | NameHarvester h = new SourceFileNameHarvester(workingDirectory); 147 | Set result = h.harvest(pattern); 148 | 149 | // Checks 150 | assertEquals(1, result.size()); 151 | 152 | HashSet tr = new HashSet(result); 153 | assertTrue(tr.contains(testFile2.getAbsolutePath())); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | com.github.hi-fi 15 | robotframework-httprequestlibrary 16 | 0.0.11 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | ${env.MAVEN_LIBRARY_VERSION} 27 | 28 | 29 | 30 | acceptance-test 31 | verify 32 | 33 | 34 | 35 | 36 | 37 | src/test/robotframework/acceptance/lib.py 38 | JustForIT.html 39 | 40 | dotted 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom_with_classpaths.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | 15 | com.github.hi-fi 16 | robotframework-httprequestlibrary 17 | 0.0.11 18 | test 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.robotframework 26 | robotframework-maven-plugin 27 | ${env.MAVEN_LIBRARY_VERSION} 28 | 29 | 30 | 31 | acceptance-test 32 | verify 33 | 34 | 35 | 36 | 37 | 38 | Dependencies should be in classpath 39 | 40 | 41 | ${project.basedir}/src/test/robotframework/classpath-acceptance 42 | 43 | 44 | false 45 | 46 | dotted 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom_with_external_runner.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | com.github.hi-fi 15 | robotframework-httprequestlibrary 16 | 0.0.11 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | ${env.MAVEN_LIBRARY_VERSION} 27 | 28 | 29 | 30 | acceptance-test 31 | verify 32 | 33 | 34 | 35 | 36 | 37 | 38 | magic is this? 39 | 40 | 41 | 42 | Successful_Test 43 | 44 | dotted 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom_with_noncritical_failures.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | com.github.hi-fi 15 | robotframework-httprequestlibrary 16 | 0.0.11 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | ${env.MAVEN_LIBRARY_VERSION} 27 | 28 | 29 | 30 | acceptance-test 31 | verify 32 | 33 | 34 | 35 | 36 | 37 | success 38 | 39 | dotted 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom_with_tests_configured.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | com.github.hi-fi 15 | robotframework-httprequestlibrary 16 | 0.0.11 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | ${env.MAVEN_LIBRARY_VERSION} 27 | 28 | 29 | 30 | acceptance-test 31 | verify 32 | 33 | 34 | 35 | 36 | 37 | *TestNegatives 38 | Successful_Test 39 | 40 | 41 | VariableThatShouldNotBeOverridden:permanent 42 | VariableThatShouldBeOverridden:temp 43 | 44 | dotted 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/pom_without_classpaths.xml: -------------------------------------------------------------------------------- 1 | 5 | 4.0.0 6 | 7 | org.robotframework 8 | robotframework-maven-plugin-test 9 | 1.0-SNAPSHOT 10 | pom 11 | Test Mojo 12 | 13 | 14 | 15 | com.github.hi-fi 16 | robotframework-httprequestlibrary 17 | 0.0.11 18 | test 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.robotframework 26 | robotframework-maven-plugin 27 | ${env.MAVEN_LIBRARY_VERSION} 28 | 29 | 30 | 31 | acceptance-test 32 | verify 33 | 34 | 35 | 36 | 37 | 38 | Dependencies should not be in classpath 39 | 40 | 41 | ${project.basedir}/src/test/robotframework/classpath-acceptance 42 | 43 | 44 | true 45 | 46 | this-should-be-seen-by-external-process.jar 47 | 48 | 49 | dotted 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/acceptance/anotherSuccessfulTest.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Default Tags success 3 | 4 | *** Test Cases *** 5 | Successful Test Negatives 6 | Should Be Equal As Numbers -1 -1 7 | Should Be Equal As Numbers -4 -4 -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/acceptance/failingTest.robot: -------------------------------------------------------------------------------- 1 | *** Variables *** 2 | ${VariableThatShouldNotBeOverridden} This defined in pom_with_test_configured.xml 3 | ${VariableThatShouldBeOverridden} This defined in pom_with_test_configured.xml but should be overridden on prompt 4 | ${extra variable from prompt} This also should be overridden from prompt 5 | 6 | *** Test Cases *** 7 | Failing Test Case 8 | Should Be Equal As Numbers 1 2 9 | Should Be Equal As Numbers 2 3 10 | Failing based on variable 11 | Should Be Equal ${VariableThatShouldNotBeOverridden} ${VariableThatShouldBeOverridden} 12 | Should Be Equal ${extra variable from prompt} overridden 13 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/acceptance/lib.py: -------------------------------------------------------------------------------- 1 | def example(hello): 2 | print hello -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/acceptance/secondFailingTest.robot: -------------------------------------------------------------------------------- 1 | *** Test Cases *** 2 | Second Failing Test Case 3 | Should Be Equal As Numbers 5 6 4 | Should Be Equal As Numbers 7 8 5 | Second Other Failing Test Case 6 | Should Be Equal As Numbers 9 10 7 | Second Yet Another Failing Test Case 8 | Should Be Equal As Numbers 11 12 -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/acceptance/successfulTest.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library HttpRequestLibrary 3 | Default Tags success 4 | 5 | *** Test Cases *** 6 | Successful Test 7 | Should Be Equal As Numbers 1 1 8 | Should Be Equal As Numbers 4 4 9 | Pretty Print Json { "testJson": { "key": "value" }} 10 | -------------------------------------------------------------------------------- /src/test/projects/acceptance-and-verify/src/test/robotframework/classpath-acceptance/classpathTests.robot: -------------------------------------------------------------------------------- 1 | *** Test cases *** 2 | Dependencies should be in classpath 3 | Should contain %{java.class.path} httprequestlibrary 4 | Dependencies should not be in classpath 5 | Should not contain %{java.class.path} httprequestlibrary 6 | Should contain %{java.class.path} this-should-be-seen-by-external-process.jar -------------------------------------------------------------------------------- /src/test/resources/files/embed1/resourcesA.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/files/embed1/resourcesA.txt -------------------------------------------------------------------------------- /src/test/resources/files/embed1/test.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/files/embed1/test.java -------------------------------------------------------------------------------- /src/test/resources/files/embed2/test2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/files/embed2/test2.txt -------------------------------------------------------------------------------- /src/test/resources/files/resources.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/files/resources.txt -------------------------------------------------------------------------------- /src/test/resources/files/test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/files/test.txt -------------------------------------------------------------------------------- /src/test/resources/output-for-rebot/output-rebot-20181115-081427.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Fails if objects are unequal after converting them to real numbers. 8 | 9 | -1 10 | -1 11 | 12 | 13 | 14 | 15 | Fails if objects are unequal after converting them to real numbers. 16 | 17 | -4 18 | -4 19 | 20 | 21 | 22 | 23 | success 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Fails if objects are unequal after converting them to real numbers. 33 | 34 | 1 35 | 1 36 | 37 | 38 | 39 | 40 | Fails if objects are unequal after converting them to real numbers. 41 | 42 | 4 43 | 4 44 | 45 | 46 | 47 | 48 | success 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Critical Tests 59 | All Tests 60 | 61 | 62 | success 63 | 64 | 65 | Robot-Success 66 | Robot-Success.anotherSuccessfulTest 67 | Robot-Success.successfulTest 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/test/resources/output-for-rebot/output-rebot-20181115-081428.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Fails if objects are unequal after converting them to real numbers. 8 | 9 | -1 10 | -1 11 | 12 | 13 | 14 | 15 | Fails if objects are unequal after converting them to real numbers. 16 | 17 | -4 18 | -4 19 | 20 | 21 | 22 | 23 | success 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Fails if objects are unequal after converting them to real numbers. 33 | 34 | 1 35 | 1 36 | 37 | 38 | 39 | 40 | Fails if objects are unequal after converting them to real numbers. 41 | 42 | 4 43 | 4 44 | 45 | 46 | 47 | 48 | success 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Critical Tests 59 | All Tests 60 | 61 | 62 | success 63 | 64 | 65 | Robot-Success 66 | Robot-Success.anotherSuccessfulTest 67 | Robot-Success.successfulTest 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/test/resources/pom-configure-runner.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | src/test/resources/robot-external 19 | target/robotframework-reports 20 | TEST-robot-configure-runner.xml 21 | 22 | 23 | bar 24 | Something else 25 | 26 | 27 | dotted 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/test/resources/pom-error.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | junit 15 | junit 16 | 4.10 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | 27 | src/test/resources/nothing-here 28 | target/robotframework-reports 29 | TEST-nothing-here.xml 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test/resources/pom-fail.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | junit 15 | junit 16 | 4.10 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | 27 | src/test/resources/robot-fail 28 | target/robotframework-reports 29 | TEST-robot-fail.xml 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test/resources/pom-hsqldb.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | junit 15 | junit 16 | 4.10 17 | test 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.robotframework 25 | robotframework-maven-plugin 26 | 27 | src/test/resources/robot-hsqldb 28 | target/robotframework-reports 29 | 30 | src/test/resources/python 31 | 32 | dotted 33 | 34 | 35 | 36 | org.hsqldb 37 | hsqldb 38 | 1.8.0.10 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/test/resources/pom-libdoc-libraryname-java.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | org.robotframework.mavenplugin.ExampleLib 20 | ExampleLib.html 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/resources/pom-libdoc-libraryname-python-subpackage.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | mypackage.mylib 20 | 21 | src/test/resources/robot-libdoc-libraryname 22 | 23 | mypackage.mylib.html 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/pom-libdoc-libraryname-python.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | mylib 20 | 21 | src/test/resources/robot-libdoc-libraryname 22 | 23 | mylib.html 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test/resources/pom-libdoc-robotfile.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/resources/robot-libdoc/html_resource.robot 20 | html_resource.html 21 | src/test/resources/robotframework/libraries 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/resources/pom-libdoc.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/java/org/robotframework/mavenplugin/ExampleLib.java 20 | ExampleLib.html 21 | src/test/resources/robotframework/libraries 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/pom-rebot-merged.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | target/robotframework-reports/rebot 19 | TEST-robot-success-merged.xml 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/pom-rebot.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | target/robotframework-reports/rebot 19 | TEST-robot-success.xml 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/resources/pom-runmodes.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | src/test/resources/robot-fail 19 | target/robotframework-reports 20 | TEST-robot-runmodes.xml 21 | true 22 | true 23 | true 24 | all 25 | dotted 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/test/resources/pom-success.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | src/test/resources/robot-success 19 | target/robotframework-reports 20 | TEST-robot-success.xml 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/pom-testdoc-robotfile-doc.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/resources/robot-testdoc/invalid_login.robot 20 | invalid_login_doc.html 21 | Custom documentation 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/resources/pom-testdoc-robotfile-name.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/resources/robot-testdoc/invalid_login.robot 20 | invalid_login_name.html 21 | Custom name 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/resources/pom-testdoc-robotfile-title.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/resources/robot-testdoc/invalid_login.robot 20 | invalid_login_title.html 21 | Custom Title 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/resources/pom-testdoc-robotfile.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | org.robotframework 7 | robotframework-maven-plugin-test 8 | 1.0-SNAPSHOT 9 | jar 10 | Test Mojo 11 | 12 | 13 | 14 | 15 | org.robotframework 16 | robotframework-maven-plugin 17 | 18 | 19 | src/test/resources/robot-testdoc/invalid_login.robot 20 | invalid.html 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/resources/python/DatabaseLibrary/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Franz Allan Valencia See 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from connection_manager import ConnectionManager 16 | from query import Query 17 | from manipulation import Manipulation 18 | from assertion import Assertion 19 | 20 | __version__ = '0.3' 21 | 22 | class DatabaseLibrary(ConnectionManager, Query, Assertion, Manipulation): 23 | """ 24 | Database Library contains utilities meant for Robot Framework's usage. 25 | 26 | This can allow you to query your database after an action has been made to verify the results. 27 | 28 | This is `compatible*` with any Database API Specification 2.0 module. 29 | 30 | 31 | 32 | References: 33 | 34 | + Database API Specification 2.0 - http://www.python.org/dev/peps/pep-0249/ 35 | 36 | + Lists of DB API 2.0 - http://wiki.python.org/moin/DatabaseInterfaces 37 | 38 | + Python Database Programming - http://wiki.python.org/moin/DatabaseProgramming/ 39 | 40 | Notes: 41 | 42 | 43 | 44 | `compatible* - or at least theoretically it should be compatible. Currently tested only with postgresql 45 | (using psycopg2).` 46 | 47 | Example Usage: 48 | | # Setup | 49 | | Connect to Database | 50 | | # Guard assertion (verify that test started in expected state). | 51 | | Check if not exists in database | select id from person where first_name = 'Franz Allan' and last_name = 'See' | 52 | | # Drive UI to do some action | 53 | | Go To | http://localhost/person/form.html | | # From selenium library | 54 | | Input Text | name=first_name | Franz Allan | # From selenium library | 55 | | Input Text | name=last_name | See | # From selenium library | 56 | | Click Button | Save | | # From selenium library | 57 | | # Log results | 58 | | @{queryResults} | Query | select * from person | 59 | | Log Many | @{queryResults} | 60 | | # Verify if persisted in the database | 61 | | Check if exists in database | select id from person where first_name = 'Franz Allan' and last_name = 'See' | 62 | | # Teardown | 63 | | Disconnect from Database | 64 | """ 65 | 66 | ROBOT_LIBRARY_SCOPE = 'GLOBAL' 67 | 68 | -------------------------------------------------------------------------------- /src/test/resources/python/DatabaseLibrary/assertion.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Franz Allan Valencia See 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class Assertion(object): 16 | """ 17 | Assertion handles all the assertions of Database Library. 18 | """ 19 | 20 | def check_if_exists_in_database(self,selectStatement): 21 | """ 22 | Check if any row would be returned by given the input 23 | `selectStatement`. If there are no results, then this will 24 | throw an AssertionError. 25 | 26 | For example, given we have a table `person` with the following data: 27 | | id | first_name | last_name | 28 | | 1 | Franz Allan | See | 29 | 30 | When you have the following assertions in your robot 31 | | Check If Exists In Database | select id from person where first_name = 'Franz Allan' | 32 | | Check If Exists In Database | select id from person where first_name = 'John' | 33 | 34 | Then you will get the following: 35 | | Check If Exists In Database | select id from person where first_name = 'Franz Allan' | # PASS | 36 | | Check If Exists In Database | select id from person where first_name = 'John' | # FAIL | 37 | """ 38 | if not self.query(selectStatement): 39 | raise AssertionError("Expected to have have at least one row from '%s' " 40 | "but got 0 rows." % selectStatement) 41 | 42 | def check_if_not_exists_in_database(self,selectStatement): 43 | """ 44 | This is the negation of `check_if_exists_in_database`. 45 | 46 | Check if no rows would be returned by given the input 47 | `selectStatement`. If there are any results, then this will 48 | throw an AssertionError. 49 | 50 | For example, given we have a table `person` with the following data: 51 | | id | first_name | last_name | 52 | | 1 | Franz Allan | See | 53 | 54 | When you have the following assertions in your robot 55 | | Check If Not Exists In Database | select id from person where first_name = 'John' | 56 | | Check If Not Exists In Database | select id from person where first_name = 'Franz Allan' | 57 | 58 | Then you will get the following: 59 | | Check If Not Exists In Database | select id from person where first_name = 'John' | # PASS | 60 | | Check If Not Exists In Database | select id from person where first_name = 'Franz Allan' | # FAIL | 61 | """ 62 | queryResults = self.query(selectStatement) 63 | if queryResults: 64 | raise AssertionError("Expected to have have no rows from '%s' " 65 | "but got some rows : %s." % (selectStatement, queryResults)) 66 | -------------------------------------------------------------------------------- /src/test/resources/python/DatabaseLibrary/connection_manager.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Franz Allan Valencia See 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import ConfigParser 16 | 17 | class ConnectionManager (object): 18 | """ 19 | Connection Manager handles the connection & disconnection to the database. 20 | """ 21 | 22 | def __init__(self): 23 | """ 24 | Initializes _dbconnection to None. 25 | """ 26 | self._dbconnection = None 27 | 28 | 29 | def connect_to_dbapi2(self, dbapiModuleName, *args): 30 | """ 31 | Loads the DB API 2.0 module with the given `dbapiModuleName`, then uses 32 | it to connect to the database using `args`. The arguments depend on the 33 | dbapiModule which is used for the connection. 34 | 35 | Example usage: 36 | | # Using psycopg2, specify postgres database name, user and password | 37 | | Connect To Dbapi2 | psycopg2 | my_db | user | s3cr3t | 38 | 39 | | # Using pymysql, specify mysql database host, user, password, db and port | 40 | | Connect To Dbapi2 | pymysql | localhost | user | s3cr3t | my_db | 3306 | 41 | 42 | | # Using jaydebeapi, set classpath, connect via Oracle jdbc driver in Python or Jython | 43 | | Set Environment Variable | CLASSPATH | ${CURDIR}/../libraries/ojdbc14-10.2.0.3.0.jar | 44 | | Connect To Dbapi2 | jaydebeapi | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:@host:port | user | s3cr3t | 45 | 46 | | # Using jaydebeapi, set classpath, connect via Firebird jdbc driver in Python or Jython | 47 | | Set Environment Variable | CLASSPATH | ${CURDIR}/../libraries/jaybird-full-2.1.6.jar 48 | | Connect To Dbapi2 | jaydebeapi | org.firebirdsql.jdbc.FBDriver | jdbc:firebirdsql:localhost/3050:c:/data/test.fdb | SYSDBA | masterkey | 49 | 50 | """ 51 | db_api_2 = __import__(dbapiModuleName); 52 | # TODO: pass configfile as second arg dbConfigFile="./resources/db.cfg"? 53 | # maybe use ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'}) 54 | # seems to be recommended by Python reference 55 | # don't know how to handle config.items so that it can be passed as args 56 | self._dbconnection = db_api_2.connect (*args); 57 | 58 | def connect_to_database(self, dbapiModuleName=None, dbName=None, dbUsername=None, dbPassword=None, dbConfigFile="./resources/db.cfg"): 59 | """ 60 | Loads the DB API 2.0 module given `dbapiModuleName` then uses it to 61 | connect to the database using `dbName`, `dbUsername`, and `dbPassword`. 62 | 63 | Optionally, you can specify a `dbConfigFile` wherein it will load the 64 | default property values for `dbapiModuleName`, `dbName` `dbUsername` 65 | and `dbPassword` (note: specifying `dbapiModuleName`, `dbName` 66 | `dbUsername` or `dbPassword` directly will override the properties of 67 | the same key in `dbConfigFile`). If no `dbConfigFile` is specified, it 68 | defaults to `./resources/db.cfg`. 69 | 70 | The `dbConfigFile` is useful if you don't want to check into your SCM 71 | your database credentials. 72 | 73 | Example usage: 74 | | # explicitly specifies all db property values | 75 | | Connect To Database | psycopg2 | my_db | postgres | s3cr3t | 76 | 77 | | # loads all property values from default.cfg | 78 | | Connect To Database | dbConfigFile=default.cfg | 79 | 80 | | # loads all property values from ./resources/db.cfg | 81 | | Connect To Database | 82 | 83 | | # uses explicit `dbapiModuleName` and `dbName` but uses the `dbUsername` and `dbPassword` in 'default.cfg' | 84 | | Connect To Database | psycopg2 | my_db_test | dbConfigFile=default.cfg | 85 | 86 | | # uses explicit `dbapiModuleName` and `dbName` but uses the `dbUsername` and `dbPassword` in './resources/db.cfg' | 87 | | Connect To Database | psycopg2 | my_db_test | 88 | """ 89 | 90 | config = ConfigParser.ConfigParser() 91 | config.read([dbConfigFile]) 92 | 93 | dbapiModuleName = dbapiModuleName or config.get('default', 'dbapiModuleName') 94 | dbName = dbName or config.get('default', 'dbName') 95 | dbUsername = dbUsername or config.get('default', 'dbUsername') 96 | dbPassword = dbPassword or config.get('default', 'dbPassword') 97 | 98 | db_api_2 = __import__(dbapiModuleName); 99 | self._dbconnection = db_api_2.connect (database=dbName, user=dbUsername, password=dbPassword) 100 | 101 | def disconnect_from_database(self): 102 | """ 103 | Disconnects from the database. 104 | 105 | For example: 106 | | Disconnect From Database | # disconnects from current connection to the database | 107 | """ 108 | self._dbconnection.close() 109 | 110 | -------------------------------------------------------------------------------- /src/test/resources/python/DatabaseLibrary/manipulation.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Franz Allan Valencia See 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class Manipulation(object): 16 | """ 17 | Manipulation handles data manipulation. 18 | """ 19 | 20 | def execute_sql(self, operation, *parameters): 21 | """ 22 | Executes the SQL statement given in `operation`, passing in the given 23 | parameters, which could be used by prepared statements. If the statement 24 | yields a result, it is returned. 25 | 26 | Example: 27 | Simple update statement with parameters as part of the operation string. 28 | | Execute Sql | UPDATE MYTABLE set FLAG = ${accepted} WHERE ID=${id} | 29 | 30 | The syntax for parameterized statements is database dependent. Search 31 | Google for "dbapi2 cheat sheet" if you want to pass parameters. 32 | """ 33 | cur = None 34 | try: 35 | cur = self._dbconnection.cursor() 36 | cur.execute (operation); 37 | if(cur.description is not None): 38 | allRows = cur.fetchall() 39 | return allRows 40 | finally : 41 | if cur : 42 | cur.close() 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/test/resources/python/DatabaseLibrary/query.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Franz Allan Valencia See 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class Query(object): 16 | """ 17 | Query handles all the querying done by the Database Library. 18 | """ 19 | 20 | 21 | def query(self, selectStatement): 22 | """ 23 | Uses the input `selectStatement` to query for the values that 24 | will be returned as a list of tuples. 25 | 26 | Tip: Unless you want to log all column values of the specified rows, 27 | try specifying the column names in your select statements 28 | as much as possible to prevent any unnecessary surprises with schema 29 | changes and to easily see what your [] indexing is trying to retrieve 30 | (i.e. instead of `"select * from my_table"`, try 31 | `"select id, col_1, col_2 from my_table"`). 32 | 33 | For example, given we have a table `person` with the following data: 34 | | id | first_name | last_name | 35 | | 1 | Franz Allan | See | 36 | 37 | When you do the following: 38 | | @{queryResults} | Query | select * from person | 39 | | Log Many | @{queryResults} | 40 | 41 | You will get the following: 42 | [1, 'Franz Allan', 'See'] 43 | 44 | Also, you can do something like this: 45 | | ${queryResults} | Query | select first_name, last_name from person | 46 | | Log | ${queryResults[0][1]}, ${queryResults[0][0]} | 47 | 48 | And get the following 49 | See, Franz Allan 50 | """ 51 | cur = None 52 | try: 53 | cur = self._dbconnection.cursor() 54 | cur.execute (selectStatement); 55 | allRows = cur.fetchall() 56 | return allRows 57 | finally : 58 | if cur : 59 | cur.close() 60 | 61 | def execute_sql_script(self, sqlScriptFileName): 62 | """ 63 | Executes the content of the `sqlScriptFileName` as SQL commands. 64 | Useful for setting the database to a known state before running 65 | your tests, or clearing out your test data after running each a 66 | test. 67 | 68 | SQL commands are expected to be delimited by a semi-colon (';'). 69 | 70 | For example: 71 | delete from person_employee_table; 72 | delete from person_table; 73 | delete from employee_table; 74 | 75 | Also, the last SQL command can optionally omit its trailing semi-colon. 76 | 77 | For example: 78 | delete from person_employee_table; 79 | delete from person_table; 80 | delete from employee_table 81 | 82 | Given this, that means you can create spread your SQL commands in several 83 | lines. 84 | 85 | For example: 86 | delete 87 | from person_employee_table; 88 | delete 89 | from person_table; 90 | delete 91 | from employee_table 92 | 93 | However, lines that starts with a number sign (`#`) are treated as a 94 | commented line. Thus, none of the contents of that line will be executed. 95 | 96 | For example: 97 | # Delete the bridging table first... 98 | delete 99 | from person_employee_table; 100 | # ...and then the bridged tables. 101 | delete 102 | from person_table; 103 | delete 104 | from employee_table 105 | """ 106 | sqlScriptFile = open(sqlScriptFileName) 107 | 108 | cur = None 109 | try: 110 | cur = self._dbconnection.cursor() 111 | sqlStatement = '' 112 | for line in sqlScriptFile: 113 | line = line.strip() 114 | if line.startswith('#'): 115 | continue 116 | 117 | sqlFragments = line.split(';') 118 | if len(sqlFragments) == 1: 119 | sqlStatement += line + ' '; 120 | else: 121 | for sqlFragment in sqlFragments: 122 | sqlFragment = sqlFragment.strip() 123 | if len(sqlFragment) == 0: 124 | continue 125 | 126 | sqlStatement += sqlFragment + ' '; 127 | 128 | cur.execute(sqlStatement) 129 | sqlStatement = '' 130 | 131 | sqlStatement = sqlStatement.strip() 132 | if len(sqlStatement) != 0: 133 | cur.execute(sqlStatement) 134 | 135 | self._dbconnection.commit() 136 | except: 137 | self._dbconnection.rollback() 138 | finally: 139 | if cur : 140 | cur.close() -------------------------------------------------------------------------------- /src/test/resources/python/jaydebeapi/__init__.py: -------------------------------------------------------------------------------- 1 | from dbapi2 import * 2 | -------------------------------------------------------------------------------- /src/test/resources/robot-external/successfulTest.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Default Tags success 3 | 4 | *** Test Cases *** 5 | Verify environment variable 6 | Should Be Equal %{FOO} bar 7 | Should Be Equal %{FAA} Something else -------------------------------------------------------------------------------- /src/test/resources/robot-fail/failingTest.robot: -------------------------------------------------------------------------------- 1 | *** Test Cases *** 2 | Failing Test Case 3 | Should Be Equal As Numbers 1 2 4 | Should Be Equal As Numbers 2 3 5 | Other Failing Test Case 6 | Should Be Equal As Numbers 4 5 -------------------------------------------------------------------------------- /src/test/resources/robot-fail/secondFailingTest.robot: -------------------------------------------------------------------------------- 1 | *** Test Cases *** 2 | Second Failing Test Case 3 | Should Be Equal As Numbers 5 6 4 | Should Be Equal As Numbers 7 8 5 | Second Other Failing Test Case 6 | Should Be Equal As Numbers 9 10 7 | Second Yet Another Failing Test Case 8 | Should Be Equal As Numbers 11 12 -------------------------------------------------------------------------------- /src/test/resources/robot-hsqldb/hsqldb.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library OperatingSystem 3 | Library DatabaseLibrary 4 | 5 | *** Test Cases *** 6 | Connect 7 | Connect To Dbapi2 jaydebeapi org.hsqldb.jdbcDriver jdbc:hsqldb:mem:robot sa ${EMPTY} 8 | Execute SQL create table testtable (myid integer not null primary key, name varchar(25)) 9 | Execute SQL insert into testtable values (1, 'myname') 10 | Execute SQL insert into testtable values (2, 'yourname') 11 | @{result}= Execute Sql Select * from testtable 12 | Log Many @{result} 13 | Check If Exists In Database select * from testtable where myid=2 14 | Execute SQL drop table testtable 15 | Disconnect From Database 16 | 17 | -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc-folder-only/html_resource.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation A resource file containing the application specific keywords that create our own domain specific language. This resource implements keywords for testing HTML version of the test application. Keywords for Flex version are in flex_resource.txt and common_resource.txt is used to select which one to use. 3 | Library SeleniumLibrary 4 | 5 | *** Variables *** 6 | ${LOGIN URL} http://${SERVER}/html/ 7 | ${WELCOME URL} http://${SERVER}/html/welcome.html 8 | ${ERROR URL} http://${SERVER}/html/error.html 9 | 10 | *** Keywords *** 11 | Open Browser To Login Page 12 | Open Browser ${LOGIN URL} ${BROWSER} 13 | Maximize Browser Window 14 | Set Selenium Speed ${DELAY} 15 | Title Should Be Login Page 16 | 17 | Go To Login Page 18 | Go To ${LOGIN URL} 19 | Title Should Be Login Page 20 | 21 | Input Username 22 | [Arguments] ${username} 23 | Input Text username_field ${username} 24 | 25 | Input Password 26 | [Arguments] ${password} 27 | Input Text password_field ${password} 28 | 29 | Submit Credentials 30 | Click Button login_button 31 | 32 | Welcome Page Should Be Open 33 | Location Should Be ${WELCOME URL} 34 | Title Should Be Welcome Page 35 | 36 | Login Should Have Failed 37 | Location Should Be ${ERROR URL} 38 | Title Should Be Error Page 39 | 40 | -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc-libraryname/mylib.py: -------------------------------------------------------------------------------- 1 | class mylib: 2 | """ 3 | Support routines to handle tan operations 4 | """ 5 | 6 | 7 | def __init__(self): 8 | """ 9 | Constructor 10 | """ 11 | 12 | def say_hello(self): 13 | """ 14 | Says hello 15 | """ 16 | print("hello") -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc-libraryname/mypackage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotframework/MavenPlugin/0402a407b275b39ca3e5be2180a69db82b2033f7/src/test/resources/robot-libdoc-libraryname/mypackage/__init__.py -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc-libraryname/mypackage/mylib.py: -------------------------------------------------------------------------------- 1 | class mylib: 2 | """ 3 | Support routines to handle tan operations 4 | """ 5 | 6 | 7 | def __init__(self): 8 | """ 9 | Constructor 10 | """ 11 | 12 | def say_hello(self): 13 | """ 14 | Says hello 15 | """ 16 | print("hello") -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc/html_resource.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation A resource file containing the application specific keywords that create our own domain specific language. This resource implements keywords for testing HTML version of the test application. Keywords for Flex version are in flex_resource.txt and common_resource.txt is used to select which one to use. 3 | Library SeleniumLibrary 4 | 5 | *** Variables *** 6 | ${LOGIN URL} http://${SERVER}/html/ 7 | ${WELCOME URL} http://${SERVER}/html/welcome.html 8 | ${ERROR URL} http://${SERVER}/html/error.html 9 | 10 | *** Keywords *** 11 | Open Browser To Login Page 12 | Open Browser ${LOGIN URL} ${BROWSER} 13 | Maximize Browser Window 14 | Set Selenium Speed ${DELAY} 15 | Title Should Be Login Page 16 | 17 | Go To Login Page 18 | Go To ${LOGIN URL} 19 | Title Should Be Login Page 20 | 21 | Input Username 22 | [Arguments] ${username} 23 | Input Text username_field ${username} 24 | 25 | Input Password 26 | [Arguments] ${password} 27 | Input Text password_field ${password} 28 | 29 | Submit Credentials 30 | Click Button login_button 31 | 32 | Welcome Page Should Be Open 33 | Location Should Be ${WELCOME URL} 34 | Title Should Be Welcome Page 35 | 36 | Login Should Have Failed 37 | Location Should Be ${ERROR URL} 38 | Title Should Be Error Page 39 | 40 | -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc/invalid_login.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | 3 | Documentation A test suite containing tests related to invalid login. These 4 | ... tests are data-driven by they nature. They use a single 5 | ... keyword, specified with Test Template setting, that is called 6 | ... with different arguments to cover different scenarios. 7 | Suite Setup Open Browser To Login Page 8 | Test Setup Go To Login Page 9 | Test Template Login With Invalid Credentials Should Fail 10 | Suite Teardown Close Browser 11 | Resource common_resource.txt 12 | 13 | 14 | *** Test Cases *** User Name Password 15 | 16 | Invalid Username invalid ${VALID PASSWD} 17 | Invalid Password ${VALID USER} invalid 18 | Invalid Username And Password invalid whatever 19 | Empty Username ${EMPTY} ${VALID PASSWD} 20 | Empty Password ${VALID USER} ${EMPTY} 21 | Empty Username And Password ${EMPTY} ${EMPTY} 22 | 23 | 24 | *** Keywords *** 25 | 26 | Login With Invalid Credentials Should Fail 27 | [Arguments] ${username} ${password} 28 | Input Username ${username} 29 | Input Password ${password} 30 | Submit Credentials 31 | Login Should Have Failed 32 | -------------------------------------------------------------------------------- /src/test/resources/robot-libdoc/valid_login.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | 3 | Documentation A test suite with a single test for valid login. This test has 4 | ... a workflow that is created using keywords from the resource file. 5 | Resource common_resource.txt 6 | 7 | 8 | *** Test Cases *** 9 | 10 | Valid Login 11 | Open Browser To Login Page 12 | Input Username demo 13 | Input Password mode 14 | Submit Credentials 15 | Welcome Page Should Be Open 16 | [Teardown] Close Browser 17 | -------------------------------------------------------------------------------- /src/test/resources/robot-success/anotherSuccessfulTest.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Default Tags success 3 | 4 | *** Test Cases *** 5 | Successful Test Negatives 6 | Should Be Equal As Numbers -1 -1 7 | Should Be Equal As Numbers -4 -4 -------------------------------------------------------------------------------- /src/test/resources/robot-success/successfulTest.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Default Tags success 3 | 4 | *** Test Cases *** 5 | Successful Test 6 | Should Be Equal As Numbers 1 1 7 | Should Be Equal As Numbers 4 4 -------------------------------------------------------------------------------- /src/test/resources/robot-testdoc/invalid_login.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | 3 | Documentation A test suite containing tests related to invalid login. These 4 | ... tests are data-driven by they nature. They use a single 5 | ... keyword, specified with Test Template setting, that is called 6 | ... with different arguments to cover different scenarios. 7 | Suite Setup Open Browser To Login Page 8 | Test Setup Go To Login Page 9 | Test Template Login With Invalid Credentials Should Fail 10 | Suite Teardown Close Browser 11 | Resource common_resource.txt 12 | 13 | 14 | *** Test Cases *** User Name Password 15 | 16 | Invalid Username invalid ${VALID PASSWD} 17 | Invalid Password ${VALID USER} invalid 18 | Invalid Username And Password invalid whatever 19 | Empty Username ${EMPTY} ${VALID PASSWD} 20 | Empty Password ${VALID USER} ${EMPTY} 21 | Empty Username And Password ${EMPTY} ${EMPTY} 22 | 23 | 24 | *** Keywords *** 25 | 26 | Login With Invalid Credentials Should Fail 27 | [Arguments] ${username} ${password} 28 | Input Username ${username} 29 | Input Password ${password} 30 | Submit Credentials 31 | Login Should Have Failed 32 | -------------------------------------------------------------------------------- /src/test/resources/xunitresults/TEST-nothing-here.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/xunitresults/TEST-robot-fail.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/xunitresults/TEST-robot-success.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | --------------------------------------------------------------------------------