├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── ci.yml │ ├── promote.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_TEMPLATE.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── epam │ │ └── reportportal │ │ └── cucumber │ │ ├── AbstractReporter.java │ │ ├── RunningContext.java │ │ ├── ScenarioReporter.java │ │ ├── StepReporter.java │ │ ├── Utils.java │ │ └── util │ │ └── ItemTreeUtils.java └── resources │ ├── META-INF │ └── aop-ajc.xml │ └── agent.properties └── test ├── java └── com │ └── epam │ └── reportportal │ └── cucumber │ ├── AmbiguousScenarioTest.java │ ├── AttributeReportingTest.java │ ├── CallbackReportingIntegrationTest.java │ ├── CodeRefTest.java │ ├── DuplicateStepTest.java │ ├── EmbeddingTest.java │ ├── FailedTest.java │ ├── FeatureDescriptionTest.java │ ├── HooksTest.java │ ├── ItemTimeOrderTest.java │ ├── LaunchLoggingContextTest.java │ ├── LaunchSystemAttributesTest.java │ ├── ManualStepReporterTest.java │ ├── NestedStepsScenarioReporterTest.java │ ├── NestedStepsStepReporterTest.java │ ├── ParameterScenarioReporterTest.java │ ├── ParameterStepReporterTest.java │ ├── ScenarioOutlineStepReporterTest.java │ ├── SimpleVerificationTest.java │ ├── SystemAttributesTest.java │ ├── TestCaseIdTest.java │ └── integration │ ├── TestScenarioReporter.java │ ├── TestScenarioReporterWithPause.java │ ├── TestStepReporter.java │ ├── TestStepReporterWithPause.java │ ├── callback │ ├── TestScenarioReporter.java │ ├── TestStepReporter.java │ ├── scenario │ │ └── CallbackReportingSteps.java │ └── step │ │ └── CallbackReportingSteps.java │ ├── duplicate │ ├── DuplicateStep.java │ └── OriginalSteps.java │ ├── embed │ ├── image │ │ └── EmbeddingStepdefs.java │ ├── pdf │ │ └── EmbeddingStepdefs.java │ ├── text │ │ └── EmbeddingStepdefs.java │ └── zip │ │ └── EmbeddingStepdefs.java │ ├── feature │ ├── AmbiguousSteps.java │ ├── BellyStepdefs.java │ ├── DummyHooks.java │ ├── EmptySteps.java │ ├── FailedSteps.java │ ├── ManualStepReporterSteps.java │ ├── NestedSteps.java │ ├── ParametersTest.java │ ├── ReportsTestWithParameters.java │ └── TestCaseIdOnMethodSteps.java │ ├── hooks │ └── EmptySteps.java │ ├── nohooks │ └── EmptySteps.java │ ├── service │ └── Belly.java │ └── util │ └── TestUtils.java └── resources ├── META-INF └── services │ └── org.junit.jupiter.api.extension.Extension ├── agent.properties ├── features ├── AmbiguousTest.feature ├── BackgroundScenario.feature ├── BasicInlineParameters.feature ├── BasicScenarioOutlineParameters.feature ├── CallbackReportingScenario.feature ├── DataTableParameter.feature ├── DocStringParameters.feature ├── DummyScenario.feature ├── DuplicateStep.feature ├── DynamicScenarioOutlineNames.feature ├── FailedScenario.feature ├── ManualStepReporter.feature ├── NestedStepsFeature.feature ├── OneSimpleAndOneScenarioOutline.feature ├── TestCaseIdOnAMethod.feature ├── TwoScenarioInOne.feature ├── TwoScenarioOutlineParameters.feature ├── belly.feature └── embedding │ ├── ArchiveEmbeddingFeature.feature │ ├── ImageEmbeddingFeature.feature │ ├── PdfEmbeddingFeature.feature │ └── TextEmbeddingFeature.feature ├── files ├── demo.zip ├── plain.txt ├── test.pdf └── unlucky.jpg ├── junit-platform.properties └── logback-test.xml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Steps to Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. ... 16 | 2. ... 17 | 18 | **Expected behavior** 19 | A clear and concise description of what you expected to happen. 20 | 21 | **Actual behavior** 22 | What actually happened. 23 | 24 | **Dependency versions** 25 | Include version info of the following libraries: client-java, agent-java-cucumber 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the issue is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 EPAM Systems 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # https://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | name: CI Build 15 | 16 | on: 17 | push: 18 | branches: 19 | - '*' 20 | - '!master' 21 | - '!v4-hotfix' 22 | paths-ignore: 23 | - README.md 24 | - README_TEMPLATE.md 25 | - CHANGELOG.md 26 | 27 | pull_request: 28 | branches: 29 | - master 30 | - v4-hotfix 31 | 32 | jobs: 33 | build: 34 | runs-on: ubuntu-latest 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v4 39 | 40 | - name: Set up JDK 1.8 41 | uses: actions/setup-java@v4 42 | with: 43 | distribution: 'temurin' 44 | java-version: '8' 45 | 46 | - name: Build with Gradle 47 | run: ./gradlew build 48 | 49 | - name: Codecov upload 50 | uses: codecov/codecov-action@v4 51 | with: 52 | token: ${{ secrets.CODECOV_TOKEN }} 53 | -------------------------------------------------------------------------------- /.github/workflows/promote.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 EPAM Systems 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | name: Promote 15 | 16 | on: 17 | workflow_dispatch: 18 | inputs: 19 | version: 20 | description: 'Release version' 21 | required: true 22 | 23 | env: 24 | REPOSITORY_URL: 'https://maven.pkg.github.com' 25 | UPSTREAM_REPOSITORY_URL: 'https://oss.sonatype.org' 26 | PACKAGE_SUFFIXES: '-javadoc.jar,-javadoc.jar.asc,-sources.jar,-sources.jar.asc,.jar,.jar.asc,.pom,.pom.asc' 27 | PACKAGE: 'com.epam.reportportal' 28 | 29 | 30 | jobs: 31 | build: 32 | runs-on: ubuntu-latest 33 | 34 | steps: 35 | - name: Get variables 36 | run: | 37 | echo "ARTIFACT=`echo ${{ github.repository }} | cut -d/ -f2- | awk '{print tolower($0)}'`" >> $GITHUB_ENV 38 | echo "PACKAGE_PATH=`echo ${{ env.PACKAGE }} | sed 's/\./\//g'`" >> $GITHUB_ENV 39 | 40 | - name: Upload package 41 | run: | 42 | IFS=',' read -a files <<< '${{ env.PACKAGE_SUFFIXES }}' 43 | for f in ${files[@]}; do 44 | export URL="${{ env.REPOSITORY_URL }}/${{ github.repository }}/${PACKAGE_PATH}/${ARTIFACT}/${{ github.event.inputs.version }}/${ARTIFACT}-${{ github.event.inputs.version }}${f}" 45 | echo "Downloading artifact: ${URL}" 46 | curl -f -u ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} -s -O -L "${URL}" 47 | done 48 | files=($(ls)) 49 | echo 'Files downloaded:' 50 | echo "${files[@]}" 51 | 52 | echo 'Bundle generation' 53 | export BUNDLE_FILE="bundle.jar" 54 | jar -cvf ${BUNDLE_FILE} "${files[@]}" 55 | 56 | echo 'Bundle upload' 57 | curl -f -u ${{ secrets.SONATYPE_USER }}:${{ secrets.SONATYPE_PASSWORD }} -L \ 58 | --request POST '${{ env.UPSTREAM_REPOSITORY_URL }}/service/local/staging/bundle_upload' \ 59 | --form "file=@${BUNDLE_FILE}" >response.json 60 | 61 | response_type=`jq type response.json || echo ''` 62 | if [ -z "$response_type" ]; then 63 | echo 'ERROR: Response is not JSON!' 1>&2 64 | cat response.json 1>&2 65 | exit 1 66 | fi 67 | 68 | repo=`jq -r '.repositoryUris[0]' response.json` 69 | if [ -z "$repo" ]; then 70 | echo 'Unable to upload bundle' 1>&2 71 | cat response.json 1>&2 72 | exit 1 73 | fi 74 | 75 | echo "NEXUS_REPOSITORY=${repo}" >> $GITHUB_ENV 76 | 77 | - name: Get repository variables 78 | run: | 79 | echo "NEXUS_REPOSITORY_NAME=`echo ${NEXUS_REPOSITORY} | sed -E 's/(.+)\/([^\/]+)$/\2/'`" >> $GITHUB_ENV 80 | 81 | - name: Promote package 82 | env: 83 | ATTEMPTS: 60 84 | SLEEP_TIME: 10 85 | run: | 86 | verified=false 87 | for i in `seq 0 ${ATTEMPTS}`; do 88 | sleep $SLEEP_TIME 89 | curl -f -s -u ${{ secrets.SONATYPE_USER }}:${{ secrets.SONATYPE_PASSWORD }} -L \ 90 | --header 'Accept: application/json' \ 91 | ${{ env.UPSTREAM_REPOSITORY_URL }}/service/local/staging/repository/${NEXUS_REPOSITORY_NAME} >result.json 92 | 93 | is_closed=`jq -r '.type' result.json` 94 | is_transitioning=`jq -r '.transitioning' result.json` 95 | echo "Current repository status: $is_closed; transitioning: $is_transitioning" 96 | 97 | if [[ "$is_closed" == "closed" && "$is_transitioning" == "false" ]]; then 98 | verified=true 99 | break 100 | fi 101 | done 102 | if $verified; then 103 | echo "A bundle was verified, releasing" 104 | curl -f -u ${{ secrets.SONATYPE_USER }}:${{ secrets.SONATYPE_PASSWORD }} -L \ 105 | --header 'Content-Type: application/json' \ 106 | --data-raw "{\"data\":{\"stagedRepositoryIds\":[\"${NEXUS_REPOSITORY_NAME}\"], \"description\":\"Releasing ${{ github.event.inputs.version }}\"}}" \ 107 | --request POST ${{ env.UPSTREAM_REPOSITORY_URL }}/service/local/staging/bulk/promote 108 | else 109 | echo 'Verification failed, please check the bundle' 1>&2 110 | exit 1 111 | fi 112 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 EPAM Systems 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # https://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | name: Release 15 | 16 | on: 17 | push: 18 | branches: 19 | - master 20 | - v4-hotfix 21 | 22 | paths-ignore: 23 | - '.github/**' 24 | - README.md 25 | - README_TEMPLATE.md 26 | - CHANGELOG.md 27 | 28 | env: 29 | VERSION_FILE: gradle.properties 30 | VERSION_EXTRACT_PATTERN: '(?<=version=).+' 31 | CHANGE_LOG_FILE: CHANGELOG.md 32 | CHANGE_LOG_TMP_FILE: CHANGELOG_updated.md 33 | REPOSITORY_URL: 'https://maven.pkg.github.com/' 34 | README_FILE: README.md 35 | README_TEMPLATE_FILE: README_TEMPLATE.md 36 | README_VERSION_PLACEHOLDER: $LATEST_VERSION 37 | 38 | jobs: 39 | release: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Checkout repository 43 | uses: actions/checkout@v4 44 | 45 | - name: Generate versions 46 | uses: HardNorth/github-version-generate@v1 47 | with: 48 | version-source: file 49 | version-file: ${{ env.VERSION_FILE }} 50 | version-file-extraction-pattern: ${{ env.VERSION_EXTRACT_PATTERN }} 51 | 52 | - name: Set up JDK 1.8 53 | uses: actions/setup-java@v4 54 | with: 55 | distribution: 'temurin' 56 | java-version: '8' 57 | 58 | - name: Setup git credentials 59 | uses: oleksiyrudenko/gha-git-credentials@v2-latest 60 | with: 61 | name: 'reportportal.io' 62 | email: 'support@reportportal.io' 63 | token: ${{ secrets.GITHUB_TOKEN }} 64 | 65 | - name: Release with Gradle 66 | id: release 67 | run: | 68 | ./gradlew release -Prelease.useAutomaticVersion=true -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} \ 69 | -Prelease.newVersion=${{ env.NEXT_VERSION }} -PpublishRepo=${{ env.REPOSITORY_URL }}${{ github.repository }} \ 70 | -PgithubUserName=${{ github.actor }} -PgithubToken=${{ secrets.GITHUB_TOKEN }} \ 71 | -PgpgPassphrase=${{ secrets.GPG_PASSPHRASE }} -PgpgPrivateKey="${{ secrets.GPG_PRIVATE_KEY }}" 72 | 73 | - name: Update README.md 74 | id: readmeUpdate 75 | run: | 76 | sed 's/${{ env.README_VERSION_PLACEHOLDER }}/${{ env.RELEASE_VERSION }}/g' ${{ env.README_TEMPLATE_FILE }} > ${{ env.README_FILE }} 77 | git add ${{ env.README_FILE }} 78 | git commit -m "Readme update" 79 | 80 | - name: Update CHANGELOG.md 81 | id: changelogUpdate 82 | run: | 83 | sed '/\[Unreleased\]/q' ${{ env.CHANGE_LOG_FILE }} >> ${{ env.CHANGE_LOG_TMP_FILE }} 84 | sed -E '1,/#?#\s*\[Unreleased\]/d' ${{ env.CHANGE_LOG_FILE }} | sed -E '/#?#\s*\[/q' | \ 85 | { echo -e '\n## [${{env.RELEASE_VERSION}}]'; sed '$d'; } >> ${{ env.CHANGE_LOG_TMP_FILE }} 86 | grep -E '#?#\s*\[[0-9]' ${{ env.CHANGE_LOG_FILE }} | head -n1 >> ${{ env.CHANGE_LOG_TMP_FILE }} 87 | sed -E '1,/#?#\s*\[[0-9]/d' ${{ env.CHANGE_LOG_FILE }} >> ${{ env.CHANGE_LOG_TMP_FILE }} 88 | rm ${{ env.CHANGE_LOG_FILE }} 89 | mv ${{ env.CHANGE_LOG_TMP_FILE }} ${{ env.CHANGE_LOG_FILE }} 90 | git add ${{ env.CHANGE_LOG_FILE }} 91 | git commit -m "Changelog update" 92 | git push 93 | 94 | - name: Read changelog Entry 95 | id: readChangelogEntry 96 | uses: mindsers/changelog-reader-action@v2 97 | with: 98 | version: ${{ env.RELEASE_VERSION }} 99 | path: ./${{ env.CHANGE_LOG_FILE }} 100 | 101 | - name: Create Release 102 | id: createRelease 103 | uses: ncipollo/release-action@v1 104 | with: 105 | tag: ${{ env.RELEASE_VERSION }} 106 | name: Release ${{ env.RELEASE_VERSION }} 107 | body: ${{ steps.readChangelogEntry.outputs.changes }} 108 | 109 | - name: Checkout develop branch 110 | if: ${{ github.ref }} == 'master' 111 | uses: actions/checkout@v4 112 | with: 113 | ref: 'develop' 114 | fetch-depth: 0 115 | 116 | - name: Merge release branch into develop 117 | id: mergeIntoDevelop 118 | if: ${{ github.ref }} == 'master' 119 | run: | 120 | git merge -m 'Merge master branch into develop after a release' origin/master 121 | git status | (! grep -Fq 'both modified:') || git status | grep -F 'both modified:' \ 122 | | { echo -e 'Unable to merge master into develop, merge conflicts:'; (! grep -Eo '[^ ]+$') } 123 | git push origin develop 124 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | !gradle/wrapper/** 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | .DS_Store 16 | 17 | .gradle/ 18 | build/ 19 | .idea/ 20 | out/ 21 | test-output/ 22 | *iml -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased] 4 | 5 | ## [5.3.0] 6 | ### Changed 7 | - Client version updated on [5.3.4](https://github.com/reportportal/client-java/releases/tag/5.3.4), by @HardNorth 8 | 9 | ## [5.2.5] 10 | ### Changed 11 | - Client version updated on [5.2.25](https://github.com/reportportal/client-java/releases/tag/5.2.25), by @HardNorth 12 | 13 | ## [5.2.4] 14 | ### Added 15 | - Common Stack Trace frames skip in description and logs, by @HardNorth 16 | - Reporting of Last Error Log in Item description, by @HardNorth and @ArtemOAS 17 | ### Changed 18 | - Client version updated on [5.2.21](https://github.com/reportportal/client-java/releases/tag/5.2.21), by @HardNorth 19 | 20 | ## [5.2.3] 21 | ### Changed 22 | - Client version updated on [5.2.13](https://github.com/reportportal/client-java/releases/tag/5.2.13), by @HardNorth 23 | 24 | ## [5.2.2] 25 | ### Changed 26 | - Client version updated on [5.2.11](https://github.com/reportportal/client-java/releases/tag/5.2.11), by @HardNorth 27 | ### Removed 28 | - `OkHttp` dependency, by @HardNorth 29 | 30 | ## [5.2.1] 31 | ### Changed 32 | - Client version updated on [5.2.4](https://github.com/reportportal/client-java/releases/tag/5.2.4), by @HardNorth 33 | ### Removed 34 | - `commons-model` dependency to rely on `clinet-java` exclusions in security fixes, by @HardNorth 35 | 36 | ## [5.2.0] 37 | ### Changed 38 | - Client version updated on [5.2.0](https://github.com/reportportal/client-java/releases/tag/5.2.0), by @HardNorth 39 | 40 | ## [5.1.4] 41 | ### Changed 42 | - Client version updated on [5.1.22](https://github.com/reportportal/client-java/releases/tag/5.1.22), by @HardNorth 43 | 44 | ## [5.1.3] 45 | ### Changed 46 | - Client version updated on [5.1.16](https://github.com/reportportal/client-java/releases/tag/5.1.16), by @HardNorth 47 | 48 | ## [5.1.2] 49 | ### Added 50 | - Test Case ID templating, by @HardNorth 51 | ### Changed 52 | - Client version updated on [5.1.9](https://github.com/reportportal/client-java/releases/tag/5.1.9), by @HardNorth 53 | - Slf4j version updated on 1.7.36, by @HardNorth 54 | 55 | ## [5.1.1] 56 | ### Fixed 57 | - Invalid Data Tables format for some Report Portal versions 58 | ### Changed 59 | - Client version updated on [5.1.4](https://github.com/reportportal/client-java/releases/tag/5.1.4) 60 | - Slf4j version updated on 1.7.32 to support newer versions of Logback with security fixes 61 | 62 | ## [5.1.0] 63 | ### Added 64 | - `startHook` method 65 | ### Changed 66 | - Version promoted to stable release 67 | - Client version updated on [5.1.0](https://github.com/reportportal/client-java/releases/tag/5.1.0) 68 | 69 | ## [5.1.0-RC-5] 70 | ### Added 71 | - Feature / Scenario / Step start methods which are overridable 72 | - JSR-305 annotations 73 | - `buildFinishTestItemRequest` overridable method 74 | 75 | ## [5.1.0-RC-4] 76 | ### Changed 77 | - Client version updated on [5.1.0-RC-12](https://github.com/reportportal/client-java/releases/tag/5.1.0-RC-12) 78 | 79 | ## [5.1.0-RC-3] 80 | ### Fixed 81 | - Cucumber-groovy crash 82 | 83 | ## [5.1.0-RC-2] 84 | ### Changed 85 | - Client version updated on [5.1.0-RC-6](https://github.com/reportportal/client-java/releases/tag/5.1.0-RC-6) 86 | 87 | ## [5.1.0-RC-1] 88 | ### Changed 89 | - Client version updated on [5.1.0-RC-4](https://github.com/reportportal/client-java/releases/tag/5.1.0-RC-4) 90 | - Version changed on 5.1.0 91 | 92 | ## [5.0.2] 93 | ### Changed 94 | - Client version updated on [5.0.21](https://github.com/reportportal/client-java/releases/tag/5.0.21) 95 | ### Fixed 96 | - Empty interrupted suite in case of duplicate step 97 | - Table parameter handling for different reporters 98 | 99 | ## [5.0.1] 100 | ### Changed 101 | - Some code refactoring to unify style between all cucumber agents 102 | - Client version updated on [5.0.15](https://github.com/reportportal/client-java/releases/tag/5.0.15) 103 | ### Fixed 104 | - Double error message reporting 105 | 106 | ## [5.0.0] 107 | ### Changed 108 | - Many static methods from Util class were moved to AbstractReporter class and made protected to ease extension 109 | 110 | ## [5.0.0-RC-1] 111 | ### Added 112 | - Callback reporting 113 | ### Changed 114 | - Test step parameters handling 115 | - Mime type processing for data embedding was improved 116 | ### Fixed 117 | - Manually-reported nested steps now correctly fail all parents 118 | ### Removed 119 | - Scenario Outline iteration number in item names, to not break re-runs 120 | 121 | ## [5.0.0-BETA-13] 122 | ### Fixed 123 | - A bug whe ambiguous item cases a Null Pointer Exception 124 | - Incorrect item type settings 125 | ### Added 126 | - Nested steps support 127 | 128 | ## [5.0.0-BETA-12] 129 | ### Added 130 | - multi-thread execution support 131 | - Test Case ID support 132 | ### Fixed 133 | - codeRef reporting was added for every item in an item tree 134 | 135 | ## [3.0.0] 136 | ### New Features 137 | - Migrate to 3x client generation 138 | - Asynchronous reporting 139 | 140 | ## [2.6.1] 141 | ### Changed 142 | - access modifier to 'protected' for rootSuiteId in ScenarioReporter to allow inherit this reporter without unnecessary code duplication. 143 | 144 | ## [2.6.0] 145 | ### Released: 20 November 2016 146 | ### New Features 147 | - Initial release to Public Maven Repositories 148 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | apply plugin: 'java-library' 17 | 18 | apply from: "${project.scripts_url}/${project.scripts_branch}/build-quality.gradle" 19 | apply from: "${project.scripts_url}/${project.scripts_branch}/release-commons.gradle" 20 | apply from: "${project.scripts_url}/${project.scripts_branch}/signing.gradle" 21 | apply from: "${project.scripts_url}/${project.scripts_branch}/jacoco.gradle" 22 | 23 | project.ext.limits = [ 24 | 'instruction': 70, 25 | 'branch' : 53, 26 | 'line' : 75, 27 | 'complexity' : 60, 28 | 'method' : 65, 29 | 'class' : 87 30 | ] 31 | 32 | sourceCompatibility = JavaVersion.VERSION_1_8 33 | targetCompatibility = JavaVersion.VERSION_1_8 34 | 35 | repositories { 36 | mavenCentral() 37 | } 38 | 39 | dependencies { 40 | api 'com.epam.reportportal:client-java:5.3.4' 41 | api 'info.cukes:gherkin:2.12.2' 42 | 43 | implementation 'org.slf4j:slf4j-api:2.0.7' 44 | implementation 'org.apache.commons:commons-text:1.10.0' 45 | 46 | testImplementation 'com.epam.reportportal:agent-java-test-utils:0.0.7' 47 | 48 | testImplementation 'com.squareup.okhttp3:okhttp:4.12.0' 49 | testImplementation 'org.aspectj:aspectjweaver:1.9.19' 50 | testImplementation "io.cucumber:cucumber-java:${project.cucumber_version}" 51 | testImplementation "io.cucumber:cucumber-testng:${project.cucumber_version}" 52 | testImplementation 'org.hamcrest:hamcrest-core:2.2' 53 | testImplementation 'org.mockito:mockito-core:3.3.3' 54 | testImplementation 'org.mockito:mockito-junit-jupiter:3.3.3' 55 | testImplementation 'ch.qos.logback:logback-classic:1.3.15' 56 | testImplementation 'com.epam.reportportal:logger-java-logback:5.2.3' 57 | 58 | testImplementation ("org.junit.platform:junit-platform-runner:${project.junit_runner_version}") { 59 | exclude module: 'junit' 60 | } 61 | testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junit_version}" 62 | testImplementation "org.junit.jupiter:junit-jupiter-params:${project.junit_version}" 63 | testImplementation "org.junit.jupiter:junit-jupiter-engine:${project.junit_version}" 64 | testImplementation 'commons-io:commons-io:2.16.1' 65 | } 66 | 67 | test { 68 | outputs.upToDateWhen { return false } 69 | useJUnitPlatform() 70 | maxParallelForks(5) // it's forks - separate JVMs, should not interfere each other 71 | doFirst { 72 | def weaver = configurations.testRuntimeClasspath.find { it.name.contains("aspectjweaver") } 73 | jvmArgs += "-javaagent:$weaver" 74 | } 75 | environment "AGENT_NO_ANALYTICS", "1" 76 | testLogging { 77 | events "failed" 78 | exceptionFormat "full" 79 | } 80 | } 81 | 82 | wrapper { 83 | gradleVersion = '5.4.1' 84 | } 85 | 86 | processResources { 87 | filesMatching('agent.properties') { 88 | expand(project.properties) 89 | } 90 | } 91 | 92 | build.dependsOn jacocoTestReport 93 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=5.3.1-SNAPSHOT 2 | description=EPAM Report portal. Cucumber JVM version [1.0.0; 2.0.0) adapter 3 | cucumber_version=1.2.6 4 | junit_version=5.6.3 5 | junit_runner_version=1.6.3 6 | scripts_url=https://raw.githubusercontent.com/reportportal/gradle-scripts 7 | scripts_branch=master 8 | excludeTests= 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reportportal/agent-java-cucumber/5efd14cc70556d62c68a7cd54872ffc30b3f0c6a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin, switch paths to Windows format before running java 129 | if $cygwin ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'agent-java-cucumber' -------------------------------------------------------------------------------- /src/main/java/com/epam/reportportal/cucumber/RunningContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.listeners.ItemStatus; 4 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 5 | import gherkin.formatter.model.Step; 6 | import io.reactivex.Maybe; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.ArrayDeque; 10 | import java.util.Queue; 11 | 12 | /** 13 | * Running context that contains mostly manipulations with Gherkin objects. 14 | * Keeps necessary information regarding current Feature, Scenario and Step 15 | * 16 | * @author Vadzim Hushchanskou 17 | */ 18 | public class RunningContext { 19 | 20 | private RunningContext() { 21 | throw new AssertionError("No instances should exist for the class!"); 22 | } 23 | 24 | public static class FeatureContext { 25 | private final String uri; 26 | private Maybe id; 27 | private StartTestItemRQ itemRq; 28 | 29 | public FeatureContext(String featureUri) { 30 | uri = featureUri; 31 | } 32 | 33 | public void setId(Maybe newId) { 34 | id = newId; 35 | } 36 | 37 | public Maybe getId() { 38 | return id; 39 | } 40 | 41 | public StartTestItemRQ getItemRq() { 42 | return itemRq; 43 | } 44 | 45 | public void setItemRq(StartTestItemRQ startRq) { 46 | itemRq = startRq; 47 | } 48 | 49 | public String getUri() { 50 | return uri; 51 | } 52 | } 53 | 54 | public static class ScenarioContext { 55 | 56 | private boolean inBackground; 57 | private String stepPrefix; 58 | private Maybe currentStepId; 59 | private Maybe hookStepId; 60 | private ItemStatus hookStatus; 61 | 62 | private final Queue steps; 63 | private final Queue outlineIterations; 64 | 65 | private Maybe id; 66 | private ItemStatus status; 67 | private Integer line; 68 | private String featureUri; 69 | 70 | public ScenarioContext() { 71 | stepPrefix = ""; 72 | steps = new ArrayDeque<>(); 73 | outlineIterations = new ArrayDeque<>(); 74 | status = ItemStatus.PASSED; 75 | } 76 | 77 | @Nonnull 78 | public Queue getOutlineIterations() { 79 | return outlineIterations; 80 | } 81 | 82 | public void setId(Maybe id) { 83 | this.id = id; 84 | } 85 | 86 | public boolean isInBackground() { 87 | return inBackground; 88 | } 89 | 90 | public void setInBackground(boolean inBackground) { 91 | this.inBackground = inBackground; 92 | } 93 | 94 | public String getStepPrefix() { 95 | return stepPrefix; 96 | } 97 | 98 | public void setStepPrefix(String prefix) { 99 | stepPrefix = prefix; 100 | } 101 | 102 | public Maybe getCurrentStepId() { 103 | return currentStepId; 104 | } 105 | 106 | public void setCurrentStepId(Maybe currentStepId) { 107 | this.currentStepId = currentStepId; 108 | } 109 | 110 | public Maybe getHookStepId() { 111 | return hookStepId; 112 | } 113 | 114 | public void setHookStepId(Maybe hookStepId) { 115 | this.hookStepId = hookStepId; 116 | } 117 | 118 | public ItemStatus getHookStatus() { 119 | return hookStatus; 120 | } 121 | 122 | public void setHookStatus(ItemStatus hookStatus) { 123 | this.hookStatus = hookStatus; 124 | } 125 | 126 | public Maybe getId() { 127 | return id; 128 | } 129 | 130 | public void addStep(Step step) { 131 | steps.add(step); 132 | } 133 | 134 | public Step getNextStep() { 135 | return steps.poll(); 136 | } 137 | 138 | public boolean noMoreSteps() { 139 | return steps.isEmpty(); 140 | } 141 | 142 | public void updateStatus(ItemStatus newStatus) { 143 | if (status != newStatus) { 144 | if (ItemStatus.FAILED != status) { 145 | status = newStatus; 146 | } 147 | } 148 | } 149 | 150 | public ItemStatus getStatus() { 151 | return status; 152 | } 153 | 154 | public Integer getLine() { 155 | return line; 156 | } 157 | 158 | public void setLine(Integer scenarioLine) { 159 | line = scenarioLine; 160 | } 161 | 162 | public void setFeatureUri(String featureUri) { 163 | this.featureUri = featureUri; 164 | } 165 | 166 | public String getFeatureUri() { 167 | return featureUri; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/epam/reportportal/cucumber/ScenarioReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.epam.reportportal.cucumber; 17 | 18 | import com.epam.reportportal.utils.MemoizingSupplier; 19 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 20 | import gherkin.formatter.model.Match; 21 | import gherkin.formatter.model.Step; 22 | import io.reactivex.Maybe; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import javax.annotation.Nonnull; 27 | import javax.annotation.Nullable; 28 | import java.util.Calendar; 29 | import java.util.Optional; 30 | 31 | /** 32 | * Cucumber reporter for ReportPortal that reports scenarios as test methods. 33 | *

34 | * Mapping between Cucumber and ReportPortal is as follows: 35 | *

    36 | *
  • feature - TEST
  • 37 | *
  • scenario - STEP
  • 38 | *
  • step - log item
  • 39 | *
40 | *

41 | * Dummy "Root Test Suite" is created because in current implementation of RP 42 | * test items cannot be immediate children of a launch 43 | *

44 | * Background steps and hooks are reported as part of corresponding scenarios. 45 | * Outline example rows are reported as individual scenarios with [ROW NUMBER] 46 | * after the name. 47 | * 48 | * @author Sergey_Gvozdyukevich 49 | */ 50 | public class ScenarioReporter extends AbstractReporter { 51 | private static final String RP_STORY_TYPE = "SUITE"; 52 | private static final String RP_TEST_TYPE = "STORY"; 53 | private static final String RP_STEP_TYPE = "STEP"; 54 | 55 | private static final Logger LOGGER = LoggerFactory.getLogger(ScenarioReporter.class); 56 | 57 | protected MemoizingSupplier> rootSuiteId = new MemoizingSupplier<>(() -> { 58 | StartTestItemRQ rq = new StartTestItemRQ(); 59 | rq.setName("Root User Story"); 60 | rq.setStartTime(Calendar.getInstance().getTime()); 61 | rq.setType(RP_STORY_TYPE); 62 | return launch.get().startTestItem(rq); 63 | }); 64 | 65 | @Override 66 | @Nonnull 67 | protected StartTestItemRQ buildStartStepRequest(@Nonnull Step step, @Nullable String stepPrefix, @Nonnull Match match) { 68 | StartTestItemRQ rq = super.buildStartStepRequest(step, stepPrefix, match); 69 | rq.setHasStats(false); 70 | return rq; 71 | } 72 | 73 | @Override 74 | protected void beforeStep(Step step, Match match) { 75 | super.beforeStep(step, match); 76 | String description = buildMultilineArgument(step).trim(); 77 | if (!description.isEmpty()) { 78 | sendLog(description); 79 | } 80 | } 81 | 82 | @Override 83 | protected StartTestItemRQ buildStartHookRequest(boolean isBefore) { 84 | StartTestItemRQ rq = super.buildStartHookRequest(isBefore); 85 | rq.setHasStats(false); 86 | return rq; 87 | } 88 | 89 | @Override 90 | @Nonnull 91 | protected String getFeatureTestItemType() { 92 | return RP_TEST_TYPE; 93 | } 94 | 95 | @Override 96 | @Nonnull 97 | protected String getScenarioTestItemType() { 98 | return RP_STEP_TYPE; 99 | } 100 | 101 | @Override 102 | @Nonnull 103 | protected Optional> getRootItemId() { 104 | return Optional.of(rootSuiteId.get()); 105 | } 106 | 107 | /** 108 | * Finish root suite 109 | */ 110 | protected void finishRootItem() { 111 | if(rootSuiteId.isInitialized()) { 112 | finishTestItem(rootSuiteId.get()); 113 | rootSuiteId = null; 114 | } 115 | } 116 | 117 | @Override 118 | protected void afterLaunch() { 119 | if (currentFeatureContext.get() == null || currentFeatureContext.get().getId() == null) { 120 | LOGGER.debug("There is no scenarios in the launch"); 121 | return; 122 | } 123 | finishRootItem(); 124 | super.afterLaunch(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/epam/reportportal/cucumber/StepReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.epam.reportportal.cucumber; 17 | 18 | import io.reactivex.Maybe; 19 | 20 | import javax.annotation.Nonnull; 21 | import java.util.Optional; 22 | 23 | /** 24 | * Cucumber reporter for ReportPortal that reports individual steps as test 25 | * methods. 26 | *

27 | * Mapping between Cucumber and ReportPortal is as follows: 28 | *

    29 | *
  • feature - SUITE
  • 30 | *
  • scenario - TEST
  • 31 | *
  • step - STEP
  • 32 | *
33 | * Background steps are reported as part of corresponding scenarios. Outline 34 | * example rows are reported as individual scenarios with [ROW NUMBER] after the 35 | * name. Hooks are reported as BEFORE/AFTER_METHOD items (NOTE: all screenshots 36 | * created in hooks will be attached to these, and not to the actual failing 37 | * steps!) 38 | * 39 | * @deprecated Use {@link ScenarioReporter}, since the semantic of this class is completely broken and will be removed 40 | */ 41 | @Deprecated 42 | public class StepReporter extends AbstractReporter { 43 | private static final String RP_STORY_TYPE = "STORY"; 44 | private static final String RP_TEST_TYPE = "SCENARIO"; 45 | 46 | public StepReporter() { 47 | super(); 48 | } 49 | 50 | @Override 51 | @Nonnull 52 | protected Optional> getRootItemId() { 53 | return Optional.empty(); 54 | } 55 | 56 | @Override 57 | @Nonnull 58 | protected String getFeatureTestItemType() { 59 | return RP_STORY_TYPE; 60 | } 61 | 62 | @Override 63 | @Nonnull 64 | protected String getScenarioTestItemType() { 65 | return RP_TEST_TYPE; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/epam/reportportal/cucumber/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.epam.reportportal.cucumber; 17 | 18 | import com.epam.reportportal.listeners.ItemStatus; 19 | import gherkin.formatter.Argument; 20 | import gherkin.formatter.model.Match; 21 | 22 | import javax.annotation.Nonnull; 23 | import javax.annotation.Nullable; 24 | import java.lang.reflect.Field; 25 | import java.lang.reflect.Method; 26 | import java.util.Collections; 27 | import java.util.HashMap; 28 | import java.util.List; 29 | import java.util.Map; 30 | import java.util.function.Function; 31 | import java.util.stream.Collectors; 32 | 33 | import static java.util.Optional.ofNullable; 34 | 35 | public class Utils { 36 | private static final String STEP_DEFINITION_FIELD_NAME = "stepDefinition"; 37 | private static final String METHOD_FIELD_NAME = "method"; 38 | 39 | public static final Map STATUS_MAPPING = Collections.unmodifiableMap(new HashMap() {{ 40 | put("passed", ItemStatus.PASSED); 41 | put("failed", ItemStatus.FAILED); 42 | put("skipped", ItemStatus.SKIPPED); 43 | put("pending", ItemStatus.SKIPPED); 44 | put("undefined", ItemStatus.SKIPPED); 45 | }}); 46 | 47 | public static final Map LOG_LEVEL_MAPPING = Collections.unmodifiableMap(new HashMap() {{ 48 | put("passed", "INFO"); 49 | put("failed", "ERROR"); 50 | put("skipped", "WARN"); 51 | put("pending", "WARN"); 52 | put("undefined", "WARN"); 53 | }}); 54 | 55 | private Utils() { 56 | } 57 | 58 | /** 59 | * Generate name representation 60 | * 61 | * @param prefix - substring to be prepended at the beginning (optional) 62 | * @param infix - substring to be inserted between keyword and name 63 | * @param argument - main text to process 64 | * @return transformed string 65 | */ 66 | @Nonnull 67 | public static String buildName(@Nullable String prefix, @Nullable String infix, @Nullable String argument) { 68 | return (prefix == null ? "" : prefix) + infix + argument; 69 | } 70 | 71 | @Nullable 72 | public static Method retrieveMethod(@Nonnull Match match) throws NoSuchFieldException, IllegalAccessException { 73 | Field stepDefinitionField = match.getClass().getDeclaredField(STEP_DEFINITION_FIELD_NAME); 74 | stepDefinitionField.setAccessible(true); 75 | Object javaStepDefinition = stepDefinitionField.get(match); 76 | Field methodField = javaStepDefinition.getClass().getDeclaredField(METHOD_FIELD_NAME); 77 | methodField.setAccessible(true); 78 | return (Method) methodField.get(javaStepDefinition); 79 | } 80 | 81 | public static final Function, List> ARGUMENTS_TRANSFORM = arguments -> ofNullable(arguments).map(args -> args.stream() 82 | .map(Argument::getVal) 83 | .collect(Collectors.toList())).orElse(null); 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/epam/reportportal/cucumber/util/ItemTreeUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.util; 18 | 19 | import com.epam.reportportal.service.tree.TestItemTree; 20 | 21 | import java.util.Optional; 22 | 23 | import static java.util.Optional.ofNullable; 24 | 25 | /** 26 | * @author Vadzim Hushchanskou 27 | */ 28 | public class ItemTreeUtils { 29 | 30 | private ItemTreeUtils() { 31 | //static only 32 | } 33 | 34 | public static TestItemTree.ItemTreeKey createKey(String key) { 35 | return TestItemTree.ItemTreeKey.of(key); 36 | } 37 | 38 | public static TestItemTree.ItemTreeKey createKey(int lineNumber) { 39 | return TestItemTree.ItemTreeKey.of(String.valueOf(lineNumber)); 40 | } 41 | 42 | public static Optional retrieveLeaf(String featureUri, TestItemTree testItemTree) { 43 | return ofNullable(testItemTree.getTestItems().get(createKey(featureUri))); 44 | } 45 | 46 | public static Optional retrieveLeaf(String featureUri, int lineNumber, TestItemTree testItemTree) { 47 | Optional suiteLeaf = retrieveLeaf(featureUri, testItemTree); 48 | return suiteLeaf.map(leaf -> leaf.getChildItems().get(createKey(lineNumber))); 49 | } 50 | 51 | public static Optional retrieveLeaf(String featureUri, int lineNumber, String text, 52 | TestItemTree testItemTree) { 53 | Optional testClassLeaf = retrieveLeaf(featureUri, lineNumber, testItemTree); 54 | return testClassLeaf.map(leaf -> leaf.getChildItems().get(createKey(text))); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/aop-ajc.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/agent.properties: -------------------------------------------------------------------------------- 1 | agent.name=${name} 2 | agent.version=${version} -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/AmbiguousScenarioTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; 11 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 12 | import cucumber.api.CucumberOptions; 13 | import cucumber.api.testng.AbstractTestNGCucumberTests; 14 | import org.apache.commons.lang3.tuple.Pair; 15 | import org.junit.jupiter.api.BeforeEach; 16 | import org.junit.jupiter.api.Test; 17 | import org.mockito.ArgumentCaptor; 18 | 19 | import java.util.List; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.concurrent.Executors; 22 | import java.util.stream.Collectors; 23 | import java.util.stream.IntStream; 24 | import java.util.stream.Stream; 25 | 26 | import static org.hamcrest.MatcherAssert.assertThat; 27 | import static org.hamcrest.Matchers.equalTo; 28 | import static org.hamcrest.Matchers.hasSize; 29 | import static org.mockito.ArgumentMatchers.same; 30 | import static org.mockito.Mockito.*; 31 | 32 | public class AmbiguousScenarioTest { 33 | @CucumberOptions(features = "src/test/resources/features/AmbiguousTest.feature", glue = { 34 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 35 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 36 | public static class SimpleTestStepReporter extends AbstractTestNGCucumberTests { 37 | 38 | } 39 | 40 | @CucumberOptions(features = "src/test/resources/features/AmbiguousTest.feature", glue = { 41 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 42 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 43 | public static class SimpleTestScenarioReporter extends AbstractTestNGCucumberTests { 44 | 45 | } 46 | 47 | private final String launchId = CommonUtils.namedId("launch_"); 48 | private final String suiteId = CommonUtils.namedId("suite_"); 49 | private final String testId = CommonUtils.namedId("test_"); 50 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 51 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 52 | private final List> nestedSteps = nestedStepIds.stream() 53 | .map(s -> Pair.of(stepIds.get(0), s)) 54 | .collect(Collectors.toList()); 55 | 56 | private final ListenerParameters params = TestUtils.standardParameters(); 57 | private final ReportPortalClient client = mock(ReportPortalClient.class); 58 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 59 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 60 | 61 | @BeforeEach 62 | public void setup() { 63 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 64 | TestScenarioReporter.RP.set(reportPortal); 65 | TestStepReporter.RP.set(reportPortal); 66 | } 67 | 68 | @Test 69 | public void verify_step_reporter_ambiguous_item() { 70 | TestUtils.runTests(SimpleTestStepReporter.class); 71 | 72 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 73 | verify(client, times(3)).startTestItem(same(testId), stepCaptor.capture()); 74 | 75 | List rqs = stepCaptor.getAllValues(); 76 | List stepIdxs = IntStream.range(0, rqs.size()) 77 | .filter(i -> "STEP".equals(rqs.get(i).getType())) 78 | .boxed() 79 | .collect(Collectors.toList()); 80 | assertThat(stepIdxs, hasSize(1)); 81 | 82 | ArgumentCaptor finishIdCaptor = ArgumentCaptor.forClass(String.class); 83 | ArgumentCaptor finishRqCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); 84 | verify(client, times(5)).finishTestItem(finishIdCaptor.capture(), finishRqCaptor.capture()); 85 | 86 | List finishIds = finishIdCaptor.getAllValues(); 87 | List finishIdxs = IntStream.range(0, finishIds.size()) 88 | .filter(i -> finishIds.get(i).equals(stepIds.get(stepIdxs.get(0)))) 89 | .boxed() 90 | .collect(Collectors.toList()); 91 | assertThat(finishIdxs, hasSize(1)); 92 | 93 | List finishRqs = finishRqCaptor.getAllValues(); 94 | FinishTestItemRQ finishRq = finishRqs.get(finishIdxs.get(0)); 95 | assertThat(finishRq.getStatus(), equalTo("FAILED")); 96 | 97 | finishIdxs = IntStream.range(0, finishIds.size()).filter(i -> finishIds.get(i).equals(testId)).boxed().collect(Collectors.toList()); 98 | assertThat(finishIdxs, hasSize(1)); 99 | 100 | finishRq = finishRqs.get(finishIdxs.get(0)); 101 | assertThat(finishRq.getStatus(), equalTo("FAILED")); 102 | } 103 | 104 | @Test 105 | public void verify_scenario_reporter_ambiguous_item() { 106 | TestUtils.mockNestedSteps(client, nestedSteps); 107 | TestUtils.runTests(SimpleTestScenarioReporter.class); 108 | 109 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 110 | verify(client, times(3)).startTestItem(same(stepIds.get(0)), stepCaptor.capture()); 111 | 112 | List rqs = stepCaptor.getAllValues(); 113 | List stepIdxs = IntStream.range(0, rqs.size()) 114 | .filter(i -> "STEP".equals(rqs.get(i).getType())) 115 | .boxed() 116 | .collect(Collectors.toList()); 117 | assertThat(stepIdxs, hasSize(1)); 118 | 119 | ArgumentCaptor finishIdCaptor = ArgumentCaptor.forClass(String.class); 120 | ArgumentCaptor finishRqCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); 121 | verify(client, times(6)).finishTestItem(finishIdCaptor.capture(), finishRqCaptor.capture()); 122 | 123 | List finishIds = finishIdCaptor.getAllValues(); 124 | List finishIdxs = IntStream.range(0, finishIds.size()) 125 | .filter(i -> finishIds.get(i).equals(nestedStepIds.get(stepIdxs.get(0)))) 126 | .boxed() 127 | .collect(Collectors.toList()); 128 | assertThat(finishIdxs, hasSize(1)); 129 | 130 | List finishRqs = finishRqCaptor.getAllValues(); 131 | FinishTestItemRQ finishRq = finishRqs.get(finishIdxs.get(0)); 132 | assertThat(finishRq.getStatus(), equalTo("FAILED")); 133 | 134 | finishIdxs = IntStream.range(0, finishIds.size()) 135 | .filter(i -> finishIds.get(i).equals(stepIds.get(0))) 136 | .boxed() 137 | .collect(Collectors.toList()); 138 | assertThat(finishIdxs, hasSize(1)); 139 | 140 | finishRq = finishRqs.get(finishIdxs.get(0)); 141 | assertThat(finishRq.getStatus(), equalTo("FAILED")); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/AttributeReportingTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; 12 | import cucumber.api.CucumberOptions; 13 | import cucumber.api.testng.AbstractTestNGCucumberTests; 14 | import org.apache.commons.lang3.tuple.Pair; 15 | import org.junit.jupiter.api.BeforeEach; 16 | import org.junit.jupiter.api.Test; 17 | import org.mockito.ArgumentCaptor; 18 | 19 | import java.util.*; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.concurrent.Executors; 22 | import java.util.stream.Collectors; 23 | import java.util.stream.Stream; 24 | 25 | import static org.hamcrest.MatcherAssert.assertThat; 26 | import static org.hamcrest.Matchers.*; 27 | import static org.mockito.ArgumentMatchers.same; 28 | import static org.mockito.Mockito.*; 29 | 30 | public class AttributeReportingTest { 31 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 32 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 33 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 34 | public static class SimpleTestStepReporter extends AbstractTestNGCucumberTests { 35 | 36 | } 37 | 38 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 39 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 40 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 41 | public static class SimpleTestScenarioReporter extends AbstractTestNGCucumberTests { 42 | 43 | } 44 | 45 | private final String launchId = CommonUtils.namedId("launch_"); 46 | private final String suiteId = CommonUtils.namedId("suite_"); 47 | private final String testId = CommonUtils.namedId("test_"); 48 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 49 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 50 | private final List> nestedSteps = nestedStepIds.stream() 51 | .map(s -> Pair.of(stepIds.get(0), s)) 52 | .collect(Collectors.toList()); 53 | 54 | private final ListenerParameters params = TestUtils.standardParameters(); 55 | private final ReportPortalClient client = mock(ReportPortalClient.class); 56 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 57 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 58 | 59 | @BeforeEach 60 | public void setup() { 61 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 62 | TestScenarioReporter.RP.set(reportPortal); 63 | TestStepReporter.RP.set(reportPortal); 64 | } 65 | 66 | private static void verifyAttributes(Collection attributes, Collection> values) { 67 | assertThat(attributes, hasSize(values.size())); 68 | Set> attributePairs = attributes.stream() 69 | .map(a -> Pair.of(a.getKey(), a.getValue())) 70 | .collect(Collectors.toSet()); 71 | values.forEach(v -> assertThat(attributePairs, hasItem(v))); 72 | } 73 | 74 | private static void verifyAnnotationAttributes(List testSteps) { 75 | Set stepAttributes = testSteps.get(0).getAttributes(); 76 | verifyAttributes(stepAttributes, Collections.singleton(Pair.of("key", "value"))); 77 | 78 | stepAttributes = testSteps.get(1).getAttributes(); 79 | verifyAttributes( 80 | stepAttributes, 81 | new HashSet<>(Arrays.asList(Pair.of("key1", "value1"), Pair.of("key2", "value2"), Pair.of("k1", "v"), Pair.of("k2", "v"))) 82 | ); 83 | 84 | stepAttributes = testSteps.get(2).getAttributes(); 85 | verifyAttributes(stepAttributes, new HashSet<>(Arrays.asList(Pair.of(null, "v1"), Pair.of(null, "v2")))); 86 | } 87 | 88 | @Test 89 | public void verify_step_reporter_attributes() { 90 | TestUtils.runTests(SimpleTestStepReporter.class); 91 | 92 | ArgumentCaptor suiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 93 | verify(client, times(1)).startTestItem(suiteCaptor.capture()); 94 | 95 | assertThat(suiteCaptor.getValue().getAttributes(), anyOf(emptyIterable(), nullValue())); 96 | 97 | ArgumentCaptor testCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 98 | verify(client, times(1)).startTestItem(same(suiteId), testCaptor.capture()); 99 | verifyAttributes(testCaptor.getValue().getAttributes(), Collections.singleton(Pair.of(null, "@ok"))); 100 | 101 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 102 | verify(client, times(5)).startTestItem(same(testId), stepCaptor.capture()); 103 | 104 | List allSteps = stepCaptor.getAllValues(); 105 | List testSteps = allSteps.stream() 106 | .filter(s -> !(s.getName().startsWith("Before") || s.getName().startsWith("After"))).collect(Collectors.toList()); 107 | verifyAnnotationAttributes(testSteps); 108 | ArrayList beforeAfter = new ArrayList<>(allSteps); 109 | beforeAfter.removeAll(testSteps); 110 | beforeAfter.forEach(s->assertThat(s.getAttributes(), anyOf(emptyIterable(), nullValue()))); 111 | } 112 | 113 | @Test 114 | public void verify_scenario_reporter_attributes() { 115 | TestUtils.mockNestedSteps(client, nestedSteps); 116 | TestUtils.runTests(SimpleTestScenarioReporter.class); 117 | 118 | ArgumentCaptor mainSuiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 119 | verify(client, times(1)).startTestItem(mainSuiteCaptor.capture()); 120 | assertThat(mainSuiteCaptor.getValue().getAttributes(), anyOf(emptyIterable(), nullValue())); 121 | 122 | ArgumentCaptor suiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 123 | verify(client, times(1)).startTestItem(same(suiteId), suiteCaptor.capture()); 124 | assertThat(mainSuiteCaptor.getValue().getAttributes(), anyOf(emptyIterable(), nullValue())); 125 | 126 | ArgumentCaptor testCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 127 | verify(client, times(1)).startTestItem(same(testId), testCaptor.capture()); 128 | verifyAttributes(testCaptor.getValue().getAttributes(), Collections.singleton(Pair.of(null, "@ok"))); 129 | 130 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 131 | verify(client, times(5)).startTestItem(same(stepIds.get(0)), stepCaptor.capture()); 132 | 133 | List allSteps = stepCaptor.getAllValues(); 134 | List testSteps = allSteps.stream() 135 | .filter(s -> !(s.getName().startsWith("Before") || s.getName().startsWith("After"))).collect(Collectors.toList()); 136 | verifyAnnotationAttributes(testSteps); 137 | ArrayList beforeAfter = new ArrayList<>(allSteps); 138 | beforeAfter.removeAll(testSteps); 139 | beforeAfter.forEach(s->assertThat(s.getAttributes(), anyOf(emptyIterable(), nullValue()))); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/CallbackReportingIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.callback.TestScenarioReporter; 20 | import com.epam.reportportal.cucumber.integration.callback.TestStepReporter; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS; 27 | import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; 28 | import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; 29 | import cucumber.api.CucumberOptions; 30 | import cucumber.api.testng.AbstractTestNGCucumberTests; 31 | import io.reactivex.Maybe; 32 | import org.apache.commons.lang3.tuple.Pair; 33 | import org.junit.jupiter.api.BeforeEach; 34 | import org.junit.jupiter.api.Test; 35 | import org.mockito.ArgumentCaptor; 36 | 37 | import java.util.Arrays; 38 | import java.util.List; 39 | import java.util.concurrent.ExecutorService; 40 | import java.util.concurrent.Executors; 41 | import java.util.function.Supplier; 42 | import java.util.stream.Collectors; 43 | import java.util.stream.IntStream; 44 | import java.util.stream.Stream; 45 | 46 | import static org.hamcrest.MatcherAssert.assertThat; 47 | import static org.hamcrest.Matchers.equalTo; 48 | import static org.hamcrest.Matchers.hasSize; 49 | import static org.mockito.Mockito.*; 50 | 51 | /** 52 | * @author Ivan Budayeu 53 | */ 54 | public class CallbackReportingIntegrationTest { 55 | 56 | @CucumberOptions(features = "src/test/resources/features/CallbackReportingScenario.feature", glue = { 57 | "com.epam.reportportal.cucumber.integration.callback.scenario" }, plugin = { "pretty", 58 | "com.epam.reportportal.cucumber.integration.callback.TestScenarioReporter" }) 59 | public static class TestScenarioReporterRunner extends AbstractTestNGCucumberTests { 60 | 61 | } 62 | 63 | @CucumberOptions(features = "src/test/resources/features/CallbackReportingScenario.feature", glue = { 64 | "com.epam.reportportal.cucumber.integration.callback.step" }, plugin = { "pretty", 65 | "com.epam.reportportal.cucumber.integration.callback.TestStepReporter" }) 66 | public static class TestStepReporterRunner extends AbstractTestNGCucumberTests { 67 | 68 | } 69 | 70 | private final String launchId = CommonUtils.namedId("launch_"); 71 | private final String suiteId = CommonUtils.namedId("suite_"); 72 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(2).collect(Collectors.toList()); 73 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(6).collect(Collectors.toList()); 74 | 75 | private final List>> tests = Arrays.asList(Pair.of(testIds.get(0), stepIds.subList(0, 3)), 76 | Pair.of(testIds.get(1), stepIds.subList(3, 6)) 77 | ); 78 | 79 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("nested_step_")) 80 | .limit(6) 81 | .collect(Collectors.toList()); 82 | private final List> nestedSteps = Stream.concat(nestedStepIds.stream() 83 | .map(s -> Pair.of(stepIds.get(0), s)) 84 | .limit(3), nestedStepIds.stream().skip(3).map(s -> Pair.of(stepIds.get(1), s))).collect(Collectors.toList()); 85 | 86 | private final Supplier params = () -> { 87 | ListenerParameters p = TestUtils.standardParameters(); 88 | p.setCallbackReportingEnabled(true); 89 | return p; 90 | }; 91 | private final ReportPortalClient client = mock(ReportPortalClient.class); 92 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 93 | private final ReportPortal reportPortal = ReportPortal.create(client, params.get(), executorService); 94 | 95 | @BeforeEach 96 | public void setup() { 97 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 98 | TestScenarioReporter.addReportPortal(reportPortal); 99 | TestScenarioReporter.RP.set(reportPortal); 100 | TestStepReporter.addReportPortal(reportPortal); 101 | TestStepReporter.RP.set(reportPortal); 102 | when(client.log(any(SaveLogRQ.class))).thenReturn(Maybe.just(new EntryCreatedAsyncRS())); 103 | } 104 | 105 | @Test 106 | public void callback_reporting_test_scenario_reporter() { 107 | TestUtils.mockNestedSteps(client, nestedSteps); 108 | 109 | TestUtils.runTests(TestScenarioReporterRunner.class); 110 | 111 | ArgumentCaptor idCaptor = ArgumentCaptor.forClass(String.class); 112 | ArgumentCaptor rqCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); 113 | verify(client, times(12)).finishTestItem(idCaptor.capture(), rqCaptor.capture()); // Start test class and test method 114 | 115 | ArgumentCaptor saveLogRQArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class); 116 | verify(client, times(1)).log(saveLogRQArgumentCaptor.capture()); 117 | 118 | List finishIds = idCaptor.getAllValues(); 119 | List finishRqs = rqCaptor.getAllValues(); 120 | 121 | List> idRqs = IntStream.range(0, finishIds.size()) 122 | .mapToObj(i -> Pair.of(finishIds.get(i), finishRqs.get(i))) 123 | .collect(Collectors.toList()); 124 | 125 | List> firstScenarioIds = idRqs.stream() 126 | .filter(e -> nestedStepIds.subList(0, 3).contains(e.getKey())) 127 | .collect(Collectors.toList()); 128 | 129 | List> secondScenarioIds = idRqs.stream() 130 | .filter(e -> nestedStepIds.subList(3, 6).contains(e.getKey())) 131 | .collect(Collectors.toList()); 132 | 133 | assertThat(firstScenarioIds, hasSize(4)); 134 | assertThat(secondScenarioIds, hasSize(4)); 135 | 136 | List> failureUpdates = firstScenarioIds.stream() 137 | .filter(r -> "FAILED".equals(r.getValue().getStatus())) 138 | .collect(Collectors.toList()); 139 | assertThat(failureUpdates, hasSize(1)); 140 | 141 | SaveLogRQ logRq = saveLogRQArgumentCaptor.getValue(); 142 | assertThat(logRq.getItemUuid(), equalTo(failureUpdates.get(0).getKey())); 143 | 144 | secondScenarioIds.forEach(e -> assertThat(e.getValue().getStatus(), equalTo("PASSED"))); 145 | } 146 | 147 | @Test 148 | public void callback_reporting_test_step_reporter() { 149 | TestUtils.runTests(TestStepReporterRunner.class); 150 | 151 | ArgumentCaptor idCaptor = ArgumentCaptor.forClass(String.class); 152 | ArgumentCaptor rqCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); 153 | verify(client, times(11)).finishTestItem(idCaptor.capture(), rqCaptor.capture()); // Start test class and test method 154 | 155 | ArgumentCaptor saveLogRQArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class); 156 | verify(client, times(1)).log(saveLogRQArgumentCaptor.capture()); 157 | 158 | List finishIds = idCaptor.getAllValues(); 159 | List finishRqs = rqCaptor.getAllValues(); 160 | 161 | List> idRqs = IntStream.range(0, finishIds.size()) 162 | .mapToObj(i -> Pair.of(finishIds.get(i), finishRqs.get(i))) 163 | .collect(Collectors.toList()); 164 | 165 | List> firstScenarioIds = idRqs.stream() 166 | .filter(e -> stepIds.subList(0, 3).contains(e.getKey())) 167 | .collect(Collectors.toList()); 168 | 169 | List> secondScenarioIds = idRqs.stream() 170 | .filter(e -> stepIds.subList(3, 6).contains(e.getKey())) 171 | .collect(Collectors.toList()); 172 | 173 | assertThat(firstScenarioIds, hasSize(4)); 174 | assertThat(secondScenarioIds, hasSize(4)); 175 | 176 | List> failureUpdates = firstScenarioIds.stream() 177 | .filter(r -> "FAILED".equals(r.getValue().getStatus())) 178 | .collect(Collectors.toList()); 179 | assertThat(failureUpdates, hasSize(1)); 180 | 181 | SaveLogRQ logRq = saveLogRQArgumentCaptor.getValue(); 182 | assertThat(logRq.getItemUuid(), equalTo(failureUpdates.get(0).getKey())); 183 | 184 | secondScenarioIds.forEach(e -> assertThat(e.getValue().getStatus(), equalTo("PASSED"))); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/CodeRefTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import cucumber.api.CucumberOptions; 12 | import cucumber.api.testng.AbstractTestNGCucumberTests; 13 | import org.apache.commons.lang3.tuple.Pair; 14 | import org.junit.jupiter.api.BeforeEach; 15 | import org.junit.jupiter.api.Test; 16 | import org.mockito.ArgumentCaptor; 17 | 18 | import java.util.Arrays; 19 | import java.util.List; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.concurrent.Executors; 22 | import java.util.stream.Collectors; 23 | import java.util.stream.IntStream; 24 | import java.util.stream.Stream; 25 | 26 | import static org.hamcrest.MatcherAssert.assertThat; 27 | import static org.hamcrest.Matchers.*; 28 | import static org.mockito.Mockito.any; 29 | import static org.mockito.Mockito.*; 30 | 31 | public class CodeRefTest { 32 | 33 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 34 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 35 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 36 | public static class BellyScenarioReporter extends AbstractTestNGCucumberTests { 37 | 38 | } 39 | 40 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 41 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 42 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 43 | public static class BellyStepReporter extends AbstractTestNGCucumberTests { 44 | 45 | } 46 | 47 | @CucumberOptions(features = "src/test/resources/features/TwoScenarioInOne.feature", glue = { 48 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 49 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 50 | public static class TwoFeaturesStepReporter extends AbstractTestNGCucumberTests { 51 | 52 | } 53 | 54 | private final String launchId = CommonUtils.namedId("launch_"); 55 | private final String suiteId = CommonUtils.namedId("suite_"); 56 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(2).collect(Collectors.toList()); 57 | private final List>> tests = testIds.stream() 58 | .map(id -> Pair.of(id, Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()))) 59 | .collect(Collectors.toList()); 60 | 61 | private final ListenerParameters parameters = TestUtils.standardParameters(); 62 | private final ReportPortalClient client = mock(ReportPortalClient.class); 63 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 64 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 65 | 66 | @BeforeEach 67 | public void initLaunch() { 68 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 69 | TestScenarioReporter.RP.set(reportPortal); 70 | TestStepReporter.RP.set(reportPortal); 71 | } 72 | 73 | private static final String FEATURE_CODE_REFERENCES = "src/test/resources/features/belly.feature:0"; 74 | 75 | private static final String SCENARIO_CODE_REFERENCES = "src/test/resources/features/belly.feature:4"; 76 | 77 | @Test 78 | public void verify_code_reference_scenario_reporter() { 79 | TestUtils.runTests(BellyScenarioReporter.class); 80 | 81 | verify(client, times(1)).startTestItem(any()); 82 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 83 | verify(client, times(1)).startTestItem(same(suiteId), captor.capture()); 84 | verify(client, times(1)).startTestItem(same(testIds.get(0)), captor.capture()); 85 | 86 | List items = captor.getAllValues(); 87 | 88 | StartTestItemRQ feature = items.get(0); 89 | StartTestItemRQ scenario = items.get(1); 90 | 91 | assertThat(feature.getCodeRef(), allOf(notNullValue(), equalTo(FEATURE_CODE_REFERENCES))); 92 | assertThat(scenario.getCodeRef(), allOf(notNullValue(), equalTo(SCENARIO_CODE_REFERENCES))); 93 | } 94 | 95 | private static final List STEP_CODE_REFERENCE = Arrays.asList( 96 | "com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.I_have_cukes_in_my_belly", 97 | "com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.I_wait", 98 | "com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.my_belly_should_growl" 99 | ); 100 | 101 | @Test 102 | public void verify_code_reference_step_reporter() { 103 | TestUtils.runTests(BellyStepReporter.class); 104 | 105 | verify(client, times(1)).startTestItem(any()); 106 | ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 107 | ArgumentCaptor testCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 108 | verify(client, times(1)).startTestItem(same(suiteId), scenarioCaptor.capture()); 109 | verify(client, times(5)).startTestItem(same(testIds.get(0)), testCaptor.capture()); 110 | 111 | StartTestItemRQ scenario = scenarioCaptor.getValue(); 112 | assertThat(scenario.getCodeRef(), allOf(notNullValue(), equalTo(SCENARIO_CODE_REFERENCES))); 113 | 114 | List allSteps = testCaptor.getAllValues(); 115 | List testSteps = allSteps.stream() 116 | .filter(s -> !(s.getName().startsWith("Before") || s.getName().startsWith("After"))) 117 | .collect(Collectors.toList()); 118 | List codeReferences = testSteps.stream().map(StartTestItemRQ::getCodeRef).collect(Collectors.toList()); 119 | assertThat(codeReferences, hasSize(STEP_CODE_REFERENCE.size())); 120 | 121 | STEP_CODE_REFERENCE.forEach(r -> assertThat(codeReferences, hasItem(r))); 122 | } 123 | 124 | private static final List TWO_FEATURES_CODE_REFERENCES = Arrays.asList("src/test/resources/features/TwoScenarioInOne.feature:3", 125 | "src/test/resources/features/TwoScenarioInOne.feature:7" 126 | ); 127 | 128 | private static final List TWO_STEPS_CODE_REFERENCE = Arrays.asList( 129 | "com.epam.reportportal.cucumber.integration.feature.EmptySteps.i_have_empty_step", 130 | "com.epam.reportportal.cucumber.integration.feature.EmptySteps.i_have_another_empty_step" 131 | ); 132 | 133 | @Test 134 | public void verify_code_reference_two_features_step_reporter() { 135 | TestUtils.runTests(TwoFeaturesStepReporter.class); 136 | 137 | verify(client, times(1)).startTestItem(any()); 138 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 139 | verify(client, times(2)).startTestItem(same(suiteId), captor.capture()); 140 | verify(client, times(4)).startTestItem(same(testIds.get(0)), captor.capture()); 141 | verify(client, times(4)).startTestItem(same(testIds.get(1)), captor.capture()); 142 | 143 | List items = captor.getAllValues(); 144 | List suites = items.subList(0, 2); 145 | List steps = items.subList(2, items.size()); 146 | 147 | IntStream.range(1, TWO_FEATURES_CODE_REFERENCES.size()) 148 | .forEach(i -> assertThat(suites.get(i).getCodeRef(), allOf(notNullValue(), equalTo(TWO_FEATURES_CODE_REFERENCES.get(i))))); 149 | 150 | IntStream.range(1, TWO_STEPS_CODE_REFERENCE.size() - 1) 151 | .forEach(i -> assertThat(steps.get(i).getCodeRef(), allOf(notNullValue(), equalTo(TWO_STEPS_CODE_REFERENCE.get(i))))); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/DuplicateStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 20 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.FinishExecutionRQ; 27 | import cucumber.api.CucumberOptions; 28 | import cucumber.api.testng.AbstractTestNGCucumberTests; 29 | import org.apache.commons.lang3.tuple.Pair; 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | import org.mockito.ArgumentCaptor; 33 | 34 | import java.util.List; 35 | import java.util.concurrent.ExecutorService; 36 | import java.util.concurrent.Executors; 37 | import java.util.stream.Collectors; 38 | import java.util.stream.Stream; 39 | 40 | import static org.hamcrest.MatcherAssert.assertThat; 41 | import static org.hamcrest.Matchers.notNullValue; 42 | import static org.mockito.Mockito.*; 43 | 44 | public class DuplicateStepTest { 45 | 46 | @CucumberOptions(features = "src/test/resources/features/DuplicateStep.feature", glue = { 47 | "com.epam.reportportal.cucumber.integration.duplicate" }, plugin = { "pretty", 48 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 49 | public static class DuplicateStepReporter extends AbstractTestNGCucumberTests { 50 | 51 | } 52 | 53 | @CucumberOptions(features = "src/test/resources/features/DuplicateStep.feature", glue = { 54 | "com.epam.reportportal.cucumber.integration.duplicate" }, plugin = { "pretty", 55 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 56 | public static class DuplicateScenarioReporter extends AbstractTestNGCucumberTests { 57 | 58 | } 59 | 60 | private final String launchId = CommonUtils.namedId("launch_"); 61 | private final String suiteId = CommonUtils.namedId("suite_"); 62 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(2).collect(Collectors.toList()); 63 | private final List>> tests = testIds.stream() 64 | .map(id -> Pair.of(id, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) 65 | .collect(Collectors.toList()); 66 | 67 | private final ListenerParameters parameters = TestUtils.standardParameters(); 68 | private final ReportPortalClient client = mock(ReportPortalClient.class); 69 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 70 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 71 | 72 | @BeforeEach 73 | public void initLaunch() { 74 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 75 | TestUtils.mockLogging(client); 76 | TestScenarioReporter.RP.set(reportPortal); 77 | TestStepReporter.RP.set(reportPortal); 78 | } 79 | 80 | @Test 81 | public void verify_duplicate_step_scenario_reporter() { 82 | TestUtils.runTests(DuplicateScenarioReporter.class); 83 | 84 | verify(client, times(0)).startLaunch(any()); 85 | verify(client, times(0)).startTestItem(any()); 86 | verify(client, times(0)).startTestItem(same(suiteId), any()); 87 | verify(client, times(0)).startTestItem(same(testIds.get(0)), any()); 88 | verify(client, times(0)).finishLaunch(any(), any()); 89 | } 90 | 91 | @Test 92 | public void verify_duplicate_step_step_reporter() { 93 | TestUtils.runTests(DuplicateStepReporter.class); 94 | 95 | verify(client, times(0)).startLaunch(any()); 96 | verify(client, times(0)).startTestItem(any()); 97 | verify(client, times(0)).startTestItem(same(suiteId), any()); 98 | verify(client, times(0)).startTestItem(same(testIds.get(0)), any()); 99 | verify(client, times(0)).finishLaunch(any(), any()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/EmbeddingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 20 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.Constants; 27 | import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; 28 | import cucumber.api.CucumberOptions; 29 | import cucumber.api.testng.AbstractTestNGCucumberTests; 30 | import okhttp3.MediaType; 31 | import okhttp3.MultipartBody; 32 | import org.apache.commons.lang3.tuple.Pair; 33 | import org.junit.jupiter.api.BeforeEach; 34 | import org.junit.jupiter.api.Test; 35 | import org.mockito.ArgumentCaptor; 36 | 37 | import java.util.Collection; 38 | import java.util.List; 39 | import java.util.Objects; 40 | import java.util.concurrent.ExecutorService; 41 | import java.util.concurrent.Executors; 42 | import java.util.stream.Collectors; 43 | import java.util.stream.Stream; 44 | 45 | import static com.epam.reportportal.cucumber.integration.util.TestUtils.filterLogs; 46 | import static java.util.Optional.ofNullable; 47 | import static org.hamcrest.MatcherAssert.assertThat; 48 | import static org.hamcrest.Matchers.containsInAnyOrder; 49 | import static org.hamcrest.Matchers.hasSize; 50 | import static org.mockito.Mockito.*; 51 | 52 | @SuppressWarnings("unchecked") 53 | public class EmbeddingTest { 54 | @CucumberOptions(features = "src/test/resources/features/embedding/ImageEmbeddingFeature.feature", glue = { 55 | "com.epam.reportportal.cucumber.integration.embed.image" }, plugin = { "pretty", 56 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 57 | public static class ImageStepReporterTest extends AbstractTestNGCucumberTests { 58 | 59 | } 60 | 61 | @CucumberOptions(features = "src/test/resources/features/embedding/TextEmbeddingFeature.feature", glue = { 62 | "com.epam.reportportal.cucumber.integration.embed.text" }, plugin = { "pretty", 63 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 64 | public static class TextStepReporterTest extends AbstractTestNGCucumberTests { 65 | 66 | } 67 | 68 | @CucumberOptions(features = "src/test/resources/features/embedding/PdfEmbeddingFeature.feature", glue = { 69 | "com.epam.reportportal.cucumber.integration.embed.pdf" }, plugin = { "pretty", 70 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 71 | public static class PdfStepReporterTest extends AbstractTestNGCucumberTests { 72 | 73 | } 74 | 75 | @CucumberOptions(features = "src/test/resources/features/embedding/ArchiveEmbeddingFeature.feature", glue = { 76 | "com.epam.reportportal.cucumber.integration.embed.zip" }, plugin = { "pretty", 77 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 78 | public static class ZipStepReporterTest extends AbstractTestNGCucumberTests { 79 | 80 | } 81 | 82 | private final String launchId = CommonUtils.namedId("launch_"); 83 | private final String suiteId = CommonUtils.namedId("suite_"); 84 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()); 85 | private final List>> tests = testIds.stream() 86 | .map(id -> Pair.of(id, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) 87 | .collect(Collectors.toList()); 88 | 89 | private final ListenerParameters params = TestUtils.standardParameters(); 90 | private final ReportPortalClient client = mock(ReportPortalClient.class); 91 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 92 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 93 | 94 | private static List getLogFiles(String name, ArgumentCaptor> logCaptor) { 95 | return logCaptor.getAllValues() 96 | .stream() 97 | .flatMap(Collection::stream) 98 | .filter(p -> ofNullable(p.headers()).map(headers -> headers.get("Content-Disposition")) 99 | .map(h -> h.contains(Constants.LOG_REQUEST_BINARY_PART) && h.contains(name)) 100 | .orElse(false)) 101 | .collect(Collectors.toList()); 102 | } 103 | 104 | private static List getTypes(ArgumentCaptor> logCaptor, List logs) { 105 | return logs.stream() 106 | .flatMap(l -> getLogFiles(l.getFile().getName(), logCaptor).stream()) 107 | .flatMap(f -> ofNullable(f.body().contentType()).map(MediaType::toString).map(Stream::of).orElse(Stream.empty())) 108 | .collect(Collectors.toList()); 109 | } 110 | 111 | @BeforeEach 112 | public void setup() { 113 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 114 | TestUtils.mockLogging(client); 115 | TestScenarioReporter.RP.set(reportPortal); 116 | TestStepReporter.RP.set(reportPortal); 117 | } 118 | 119 | @Test 120 | public void verify_image_embedding() { 121 | TestUtils.runTests(ImageStepReporterTest.class); 122 | 123 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 124 | verify(client, atLeastOnce()).log(logCaptor.capture()); 125 | List logs = filterLogs(logCaptor, l -> Objects.nonNull(l.getFile())); 126 | 127 | List types = getTypes(logCaptor, logs); 128 | 129 | assertThat(types, hasSize(3)); 130 | assertThat(types, containsInAnyOrder("image/jpeg", "image/png", "image/jpeg")); 131 | } 132 | 133 | @Test 134 | public void verify_text_embedding() { 135 | TestUtils.runTests(TextStepReporterTest.class); 136 | 137 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 138 | verify(client, atLeastOnce()).log(logCaptor.capture()); 139 | List logs = filterLogs(logCaptor, l -> Objects.nonNull(l.getFile())); 140 | 141 | List types = getTypes(logCaptor, logs); 142 | 143 | assertThat(types, hasSize(3)); 144 | assertThat(types, containsInAnyOrder("text/plain", "image/png", "text/plain")); 145 | } 146 | 147 | @Test 148 | public void verify_pdf_embedding() { 149 | TestUtils.runTests(PdfStepReporterTest.class); 150 | 151 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 152 | verify(client, atLeastOnce()).log(logCaptor.capture()); 153 | List logs = filterLogs(logCaptor, l -> Objects.nonNull(l.getFile())); 154 | 155 | List types = getTypes(logCaptor, logs); 156 | 157 | assertThat(types, hasSize(3)); 158 | assertThat(types, containsInAnyOrder("application/pdf", "image/png", "application/pdf")); 159 | } 160 | 161 | @Test 162 | public void verify_archive_embedding() { 163 | TestUtils.runTests(ZipStepReporterTest.class); 164 | 165 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 166 | verify(client, atLeastOnce()).log(logCaptor.capture()); 167 | List logs = filterLogs(logCaptor, l -> Objects.nonNull(l.getFile())); 168 | 169 | List types = getTypes(logCaptor, logs); 170 | assertThat(types, hasSize(3)); 171 | assertThat(types, containsInAnyOrder("application/zip", "image/png", "application/zip")); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/FeatureDescriptionTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import cucumber.api.CucumberOptions; 12 | import cucumber.api.testng.AbstractTestNGCucumberTests; 13 | import org.apache.commons.lang3.tuple.Pair; 14 | import org.junit.jupiter.api.BeforeEach; 15 | import org.junit.jupiter.api.Test; 16 | import org.mockito.ArgumentCaptor; 17 | 18 | import java.util.List; 19 | import java.util.concurrent.ExecutorService; 20 | import java.util.concurrent.Executors; 21 | import java.util.stream.Collectors; 22 | import java.util.stream.Stream; 23 | 24 | import static org.hamcrest.MatcherAssert.assertThat; 25 | import static org.hamcrest.Matchers.*; 26 | import static org.mockito.Mockito.any; 27 | import static org.mockito.Mockito.*; 28 | 29 | public class FeatureDescriptionTest { 30 | 31 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 32 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 33 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 34 | public static class BellyScenarioReporter extends AbstractTestNGCucumberTests { 35 | 36 | } 37 | 38 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 39 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 40 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 41 | public static class BellyStepReporter extends AbstractTestNGCucumberTests { 42 | 43 | } 44 | 45 | private final String launchId = CommonUtils.namedId("launch_"); 46 | private final String suiteId = CommonUtils.namedId("suite_"); 47 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(3).collect(Collectors.toList()); 48 | private final List>> tests = testIds.stream() 49 | .map(id -> Pair.of(id, Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()))) 50 | .collect(Collectors.toList()); 51 | 52 | private final ListenerParameters parameters = TestUtils.standardParameters(); 53 | private final ReportPortalClient client = mock(ReportPortalClient.class); 54 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 55 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 56 | 57 | @BeforeEach 58 | public void initLaunch() { 59 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 60 | TestScenarioReporter.RP.set(reportPortal); 61 | TestStepReporter.RP.set(reportPortal); 62 | } 63 | 64 | private static final String FEATURE_CODE_REFERENCES = "src/test/resources/features/belly.feature"; 65 | 66 | private static final String SCENARIO_CODE_REFERENCES = "src/test/resources/features/belly.feature"; 67 | 68 | @Test 69 | public void verify_code_reference_scenario_reporter() { 70 | TestUtils.runTests(BellyScenarioReporter.class); 71 | 72 | verify(client, times(1)).startTestItem(any()); 73 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 74 | verify(client, times(1)).startTestItem(same(suiteId), captor.capture()); 75 | verify(client, times(1)).startTestItem(same(testIds.get(0)), captor.capture()); 76 | 77 | List items = captor.getAllValues(); 78 | 79 | StartTestItemRQ feature = items.get(0); 80 | StartTestItemRQ scenario = items.get(1); 81 | 82 | assertThat(feature.getDescription(), allOf(notNullValue(), equalTo(FEATURE_CODE_REFERENCES))); 83 | assertThat(scenario.getDescription(), allOf(notNullValue(), equalTo(SCENARIO_CODE_REFERENCES))); 84 | } 85 | 86 | @Test 87 | public void verify_code_reference_step_reporter() { 88 | TestUtils.runTests(BellyStepReporter.class); 89 | 90 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 91 | verify(client, times(1)).startTestItem(captor.capture()); 92 | verify(client, times(1)).startTestItem(same(suiteId), captor.capture()); 93 | verify(client, times(5)).startTestItem(same(testIds.get(0)), any()); 94 | 95 | List items = captor.getAllValues(); 96 | StartTestItemRQ feature = items.get(0); 97 | StartTestItemRQ scenario = items.get(1); 98 | 99 | assertThat(feature.getDescription(), allOf(notNullValue(), equalTo(FEATURE_CODE_REFERENCES))); 100 | assertThat(scenario.getDescription(), allOf(notNullValue(), equalTo(SCENARIO_CODE_REFERENCES))); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/HooksTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import cucumber.api.CucumberOptions; 11 | import cucumber.api.testng.AbstractTestNGCucumberTests; 12 | import org.junit.jupiter.api.AfterEach; 13 | import org.junit.jupiter.api.BeforeEach; 14 | import org.junit.jupiter.api.Test; 15 | 16 | import java.util.List; 17 | import java.util.concurrent.ExecutorService; 18 | import java.util.concurrent.Executors; 19 | import java.util.stream.Collectors; 20 | import java.util.stream.Stream; 21 | 22 | import static org.mockito.Mockito.*; 23 | 24 | /** 25 | * TODO: finish the test 26 | */ 27 | public class HooksTest { 28 | 29 | @CucumberOptions(features = "src/test/resources/features/DummyScenario.feature", glue = { 30 | "com.epam.reportportal.cucumber.integration.hooks" }, plugin = { "pretty", 31 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 32 | public static class MyStepReporter extends AbstractTestNGCucumberTests { 33 | 34 | } 35 | 36 | @CucumberOptions(features = "src/test/resources/features/DummyScenario.feature", glue = { 37 | "com.epam.reportportal.cucumber.integration.nohooks" }, plugin = { "pretty", 38 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 39 | public static class MyStepReporter2 extends AbstractTestNGCucumberTests { 40 | 41 | } 42 | 43 | private final String launchId = CommonUtils.namedId("launch_"); 44 | private final String suiteId = CommonUtils.namedId("suite_"); 45 | private final String testId = CommonUtils.namedId("test_"); 46 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 47 | 48 | private final ListenerParameters params = TestUtils.standardParameters(); 49 | private final ReportPortalClient client = mock(ReportPortalClient.class); 50 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 51 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 52 | 53 | @BeforeEach 54 | public void setup() { 55 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 56 | TestUtils.mockLogging(client); 57 | TestScenarioReporter.RP.set(reportPortal); 58 | TestStepReporter.RP.set(reportPortal); 59 | } 60 | 61 | @AfterEach 62 | public void tearDown() { 63 | CommonUtils.shutdownExecutorService(executorService); 64 | } 65 | 66 | @Test 67 | @SuppressWarnings("unchecked") 68 | public void verify_before_after_reported_in_steps() { 69 | TestUtils.runTests(MyStepReporter.class); 70 | 71 | verify(client, times(1)).startTestItem(any()); 72 | verify(client, times(1)).startTestItem(same(suiteId), any()); 73 | verify(client, times(4)).startTestItem(same(testId), any()); 74 | verify(client, times(6)).log(any(List.class)); 75 | } 76 | 77 | @Test 78 | @SuppressWarnings("unchecked") 79 | public void verify_before_after_not_reported_in_steps() { 80 | TestUtils.runTests(MyStepReporter2.class); 81 | 82 | verify(client, times(1)).startTestItem(any()); 83 | verify(client, times(1)).startTestItem(same(suiteId), any()); 84 | verify(client, times(4)).startTestItem(same(testId), any()); 85 | verify(client, times(2)).log(any(List.class)); 86 | 87 | } 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/ItemTimeOrderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.TestScenarioReporterWithPause; 20 | import com.epam.reportportal.cucumber.integration.TestStepReporterWithPause; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 27 | import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; 28 | import cucumber.api.CucumberOptions; 29 | import cucumber.api.testng.AbstractTestNGCucumberTests; 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | import org.mockito.ArgumentCaptor; 33 | 34 | import java.util.Date; 35 | import java.util.List; 36 | import java.util.concurrent.ExecutorService; 37 | import java.util.concurrent.Executors; 38 | import java.util.stream.Collectors; 39 | import java.util.stream.Stream; 40 | 41 | import static org.hamcrest.MatcherAssert.assertThat; 42 | import static org.hamcrest.Matchers.*; 43 | import static org.mockito.ArgumentMatchers.same; 44 | import static org.mockito.Mockito.*; 45 | 46 | public class ItemTimeOrderTest { 47 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 48 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 49 | "com.epam.reportportal.cucumber.integration.TestScenarioReporterWithPause" }) 50 | public static class BellyScenarioReporter extends AbstractTestNGCucumberTests { 51 | 52 | } 53 | 54 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 55 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 56 | "com.epam.reportportal.cucumber.integration.TestStepReporterWithPause" }) 57 | public static class BellyStepReporter extends AbstractTestNGCucumberTests { 58 | 59 | } 60 | 61 | private final String launchId = CommonUtils.namedId("launch_"); 62 | private final String suiteId = CommonUtils.namedId("suite_"); 63 | private final String testId = CommonUtils.namedId("test_"); 64 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 65 | 66 | private final ListenerParameters parameters = TestUtils.standardParameters(); 67 | private final ReportPortalClient client = mock(ReportPortalClient.class); 68 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 69 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 70 | 71 | @BeforeEach 72 | public void initLaunch() { 73 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 74 | TestScenarioReporterWithPause.RP.set(reportPortal); 75 | TestStepReporterWithPause.RP.set(reportPortal); 76 | } 77 | 78 | @Test 79 | public void verify_time_order_scenario_reporter() { 80 | TestUtils.runTests(BellyScenarioReporter.class); 81 | 82 | ArgumentCaptor launchCaptor = ArgumentCaptor.forClass(StartLaunchRQ.class); 83 | verify(client).startLaunch(launchCaptor.capture()); 84 | ArgumentCaptor itemCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 85 | verify(client).startTestItem(itemCaptor.capture()); 86 | verify(client).startTestItem(same(suiteId), itemCaptor.capture()); 87 | verify(client).startTestItem(same(testId), itemCaptor.capture()); 88 | 89 | Date startTime = launchCaptor.getValue().getStartTime(); 90 | List items = itemCaptor.getAllValues(); 91 | for (StartTestItemRQ item : items) { 92 | assertThat(item.getStartTime(), allOf(notNullValue(), greaterThanOrEqualTo(startTime))); 93 | startTime = item.getStartTime(); 94 | } 95 | } 96 | 97 | @Test 98 | public void verify_time_order_step_reporter() { 99 | TestUtils.runTests(BellyStepReporter.class); 100 | 101 | ArgumentCaptor launchCaptor = ArgumentCaptor.forClass(StartLaunchRQ.class); 102 | verify(client).startLaunch(launchCaptor.capture()); 103 | ArgumentCaptor itemCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 104 | verify(client).startTestItem(itemCaptor.capture()); 105 | verify(client).startTestItem(same(suiteId), itemCaptor.capture()); 106 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 107 | verify(client, times(5)).startTestItem(same(testId), stepCaptor.capture()); 108 | 109 | Date startTime = launchCaptor.getValue().getStartTime(); 110 | List items = itemCaptor.getAllValues(); 111 | for (StartTestItemRQ item : items) { 112 | assertThat(item.getStartTime(), allOf(notNullValue(), greaterThanOrEqualTo(startTime))); 113 | startTime = item.getStartTime(); 114 | } 115 | 116 | for (StartTestItemRQ step : stepCaptor.getAllValues()) { 117 | assertThat(step.getStartTime(), allOf(notNullValue(), greaterThanOrEqualTo(startTime))); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/LaunchLoggingContextTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.listeners.ListenerParameters; 4 | import com.epam.reportportal.service.Launch; 5 | import com.epam.reportportal.service.ReportPortal; 6 | import org.junit.jupiter.api.Test; 7 | import org.mockito.Mock; 8 | 9 | import static org.mockito.Mockito.*; 10 | 11 | /** 12 | * @author Ihar Kahadouski 13 | */ 14 | public class LaunchLoggingContextTest { 15 | 16 | @Mock 17 | private ReportPortal reportPortal; 18 | 19 | @Mock 20 | private ListenerParameters listenerParameters; 21 | 22 | @Mock 23 | private Launch launch; 24 | 25 | @Test 26 | public void verifyLaunchStartsBeforeFeatureStepReporter() { 27 | StepReporter stepReporter = new StepReporter() { 28 | @Override 29 | protected ReportPortal buildReportPortal() { 30 | return reportPortal; 31 | } 32 | }; 33 | 34 | when(reportPortal.getParameters()).thenReturn(listenerParameters); 35 | when(reportPortal.newLaunch(any())).thenReturn(launch); 36 | stepReporter.uri("url"); 37 | 38 | verify(launch, times(1)).start(); 39 | } 40 | 41 | @Test 42 | public void verifyLaunchStartsBeforeFeatureScenarioReporter() { 43 | ScenarioReporter scenarioReporter = new ScenarioReporter() { 44 | @Override 45 | protected ReportPortal buildReportPortal() { 46 | return reportPortal; 47 | } 48 | }; 49 | 50 | when(reportPortal.getParameters()).thenReturn(listenerParameters); 51 | when(reportPortal.newLaunch(any())).thenReturn(launch); 52 | scenarioReporter.uri("url"); 53 | 54 | verify(launch, times(1)).start(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/LaunchSystemAttributesTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 4 | import com.epam.reportportal.service.ReportPortal; 5 | import com.epam.reportportal.service.ReportPortalClient; 6 | import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; 7 | import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; 8 | import io.reactivex.Maybe; 9 | import org.junit.jupiter.api.BeforeAll; 10 | import org.junit.jupiter.api.BeforeEach; 11 | import org.junit.jupiter.api.Test; 12 | import org.mockito.ArgumentCaptor; 13 | import org.mockito.Mock; 14 | import org.mockito.MockitoAnnotations; 15 | 16 | import java.util.ArrayList; 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | import java.util.regex.Pattern; 21 | 22 | import static java.util.Optional.ofNullable; 23 | import static org.hamcrest.MatcherAssert.assertThat; 24 | import static org.hamcrest.Matchers.*; 25 | import static org.mockito.ArgumentMatchers.any; 26 | import static org.mockito.Mockito.*; 27 | 28 | /** 29 | * @author Ivan Budayeu 30 | */ 31 | public class LaunchSystemAttributesTest { 32 | 33 | private static final Map properties = new HashMap<>(); 34 | 35 | private static final String SKIPPED_ISSUE_KEY = "skippedIssue"; 36 | 37 | private StepReporter stepReporter; 38 | 39 | @Mock 40 | private ReportPortalClient reportPortalClient; 41 | 42 | @BeforeAll 43 | public static void initKeys() { 44 | properties.put("os", Pattern.compile("^.+\\|.+\\|.+$")); 45 | properties.put("jvm", Pattern.compile("^.+\\|.+\\|.+$")); 46 | properties.put("agent", Pattern.compile("^test-agent\\|test-1\\.0$")); 47 | } 48 | 49 | @BeforeEach 50 | public void initLaunch() { 51 | MockitoAnnotations.initMocks(this); 52 | stepReporter = new StepReporter() { 53 | @Override 54 | protected ReportPortal buildReportPortal() { 55 | return ReportPortal.create(reportPortalClient, TestUtils.standardParameters()); 56 | } 57 | }; 58 | } 59 | 60 | @Test 61 | public void shouldRetrieveSystemAttributes() { 62 | when(reportPortalClient.startLaunch(any(StartLaunchRQ.class))).then(t -> Maybe.create(emitter -> { 63 | emitter.onSuccess("launchId"); 64 | emitter.onComplete(); 65 | }).cache()); 66 | 67 | //noinspection ResultOfMethodCallIgnored 68 | stepReporter.launch.get().start().blockingGet(); 69 | 70 | ArgumentCaptor launchRQArgumentCaptor = ArgumentCaptor.forClass(StartLaunchRQ.class); 71 | verify(reportPortalClient, times(1)).startLaunch(launchRQArgumentCaptor.capture()); 72 | 73 | StartLaunchRQ startLaunchRequest = launchRQArgumentCaptor.getValue(); 74 | 75 | assertThat(startLaunchRequest.getAttributes(), notNullValue()); 76 | 77 | List attributes = new ArrayList<>(startLaunchRequest.getAttributes()); 78 | attributes.removeIf(attribute -> attribute.getKey().equals(SKIPPED_ISSUE_KEY)); 79 | 80 | assertThat(attributes, hasSize(3)); 81 | attributes.forEach(attr -> { 82 | assertThat(attr.isSystem(), equalTo(Boolean.TRUE)); 83 | Pattern pattern = LaunchSystemAttributesTest.this.getPattern(attr); 84 | assertThat(pattern, notNullValue()); 85 | assertThat(attr.getValue(), allOf(notNullValue(), matchesPattern(pattern))); 86 | }); 87 | } 88 | 89 | private Pattern getPattern(ItemAttributesRQ attribute) { 90 | return ofNullable(properties.get(attribute.getKey())).orElse(null); 91 | 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/NestedStepsScenarioReporterTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; 12 | import cucumber.api.CucumberOptions; 13 | import cucumber.api.testng.AbstractTestNGCucumberTests; 14 | import org.apache.commons.lang3.tuple.Pair; 15 | import org.junit.jupiter.api.AfterEach; 16 | import org.junit.jupiter.api.BeforeEach; 17 | import org.junit.jupiter.api.Test; 18 | import org.mockito.ArgumentCaptor; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | import java.util.OptionalInt; 23 | import java.util.Set; 24 | import java.util.concurrent.ExecutorService; 25 | import java.util.concurrent.Executors; 26 | import java.util.stream.Collectors; 27 | import java.util.stream.IntStream; 28 | import java.util.stream.Stream; 29 | 30 | import static org.hamcrest.MatcherAssert.assertThat; 31 | import static org.hamcrest.Matchers.*; 32 | import static org.mockito.Mockito.*; 33 | 34 | public class NestedStepsScenarioReporterTest { 35 | 36 | @CucumberOptions(features = "src/test/resources/features/NestedStepsFeature.feature", glue = { 37 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 38 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 39 | public static class NestedStepsScenarioReporter extends AbstractTestNGCucumberTests { 40 | 41 | } 42 | 43 | private final String launchId = CommonUtils.namedId("launch_"); 44 | private final String suiteId = CommonUtils.namedId("suite_"); 45 | private final String testId = CommonUtils.namedId("test_"); 46 | private final String stepId = CommonUtils.namedId("step_"); 47 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("nested_step_")) 48 | .limit(4) 49 | .collect(Collectors.toList()); 50 | private final List secondNestedStepIds = Stream.generate(() -> CommonUtils.namedId("double_nested_step_")) 51 | .limit(3) 52 | .collect(Collectors.toList()); 53 | private final String nestedNestedNestedStepId = CommonUtils.namedId("triple_nested_step_"); 54 | private final List> firstLevelNestedStepIds = nestedStepIds.stream() 55 | .map(s -> Pair.of(stepId, s)) 56 | .collect(Collectors.toList()); 57 | 58 | private final List> secondLevelNestedStepIds = Stream.concat(Stream.of(Pair.of(nestedStepIds.get(1), 59 | secondNestedStepIds.get(0) 60 | )), 61 | secondNestedStepIds.stream().skip(1).map(i -> Pair.of(nestedStepIds.get(2), i)) 62 | ).collect(Collectors.toList()); 63 | 64 | private final ListenerParameters params = TestUtils.standardParameters(); 65 | private final ReportPortalClient client = mock(ReportPortalClient.class); 66 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 67 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 68 | 69 | @BeforeEach 70 | public void setup() { 71 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepId); 72 | TestUtils.mockNestedSteps(client, firstLevelNestedStepIds); 73 | TestUtils.mockNestedSteps(client, secondLevelNestedStepIds); 74 | TestUtils.mockNestedSteps(client, Pair.of(secondNestedStepIds.get(0), nestedNestedNestedStepId)); 75 | TestScenarioReporter.RP.set(reportPortal); 76 | TestStepReporter.RP.set(reportPortal); 77 | } 78 | 79 | @AfterEach 80 | public void tearDown() { 81 | CommonUtils.shutdownExecutorService(executorService); 82 | } 83 | 84 | public static final List FIRST_LEVEL_NAMES = Arrays.asList("Before hooks", 85 | "Given I have a step", 86 | "When I have one more step", 87 | "After hooks" 88 | ); 89 | 90 | public static final List SECOND_LEVEL_NAMES = Arrays.asList("A step inside step", 91 | "A step with parameters", 92 | "A step with attributes" 93 | ); 94 | 95 | @Test 96 | public void test_scenario_reporter_nested_steps() { 97 | TestUtils.runTests(NestedStepsScenarioReporter.class); 98 | 99 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 100 | verify(client, times(1)).startTestItem(captor.capture()); 101 | verify(client, times(1)).startTestItem(same(suiteId), captor.capture()); 102 | verify(client, times(1)).startTestItem(same(testId), captor.capture()); 103 | List parentItems = captor.getAllValues(); 104 | parentItems.forEach(i -> assertThat(i.isHasStats(), anyOf(equalTo(Boolean.TRUE)))); 105 | 106 | ArgumentCaptor firstLevelCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 107 | verify(client, times(4)).startTestItem(same(stepId), firstLevelCaptor.capture()); 108 | 109 | List firstLevelRqs = firstLevelCaptor.getAllValues(); 110 | firstLevelRqs.forEach(rq -> { 111 | assertThat(rq.isHasStats(), equalTo(Boolean.FALSE)); 112 | assertThat(rq.getName(), in(FIRST_LEVEL_NAMES)); 113 | }); 114 | 115 | OptionalInt firstNestedStep = IntStream.range(0, firstLevelRqs.size()) 116 | .filter(i -> firstLevelRqs.get(i).getName().equals(FIRST_LEVEL_NAMES.get(1))) 117 | .findAny(); 118 | assertThat(firstNestedStep.isPresent(), equalTo(Boolean.TRUE)); 119 | 120 | ArgumentCaptor secondLevelCaptor1 = ArgumentCaptor.forClass(StartTestItemRQ.class); 121 | verify(client, times(1)).startTestItem(same(nestedStepIds.get(firstNestedStep.getAsInt())), secondLevelCaptor1.capture()); 122 | 123 | StartTestItemRQ secondLevelRq1 = secondLevelCaptor1.getValue(); 124 | assertThat(secondLevelRq1.getName(), equalTo(SECOND_LEVEL_NAMES.get(0))); 125 | assertThat(secondLevelRq1.isHasStats(), equalTo(Boolean.FALSE)); 126 | 127 | ArgumentCaptor secondLevelCaptor2 = ArgumentCaptor.forClass(StartTestItemRQ.class); 128 | verify(client, times(2)).startTestItem(same(nestedStepIds.get(2)), secondLevelCaptor2.capture()); 129 | 130 | List secondLevelRqs2 = secondLevelCaptor2.getAllValues(); 131 | IntStream.range(1, SECOND_LEVEL_NAMES.size()).forEach(i -> { 132 | assertThat(secondLevelRqs2.get(i - 1).getName(), equalTo(SECOND_LEVEL_NAMES.get(i))); 133 | assertThat(secondLevelRqs2.get(i - 1).isHasStats(), equalTo(Boolean.FALSE)); 134 | }); 135 | 136 | StartTestItemRQ stepWithAttributes = secondLevelRqs2.get(1); 137 | Set attributes = stepWithAttributes.getAttributes(); 138 | assertThat(attributes, allOf(notNullValue(), hasSize(2))); 139 | List> kvAttributes = attributes.stream() 140 | .map(a -> Pair.of(a.getKey(), a.getValue())) 141 | .collect(Collectors.toList()); 142 | List> keyAndValueList = kvAttributes.stream().filter(kv -> kv.getKey() != null).collect(Collectors.toList()); 143 | assertThat(keyAndValueList, hasSize(1)); 144 | assertThat(keyAndValueList.get(0).getKey(), equalTo("key")); 145 | assertThat(keyAndValueList.get(0).getValue(), equalTo("value")); 146 | 147 | List> tagList = kvAttributes.stream().filter(kv -> kv.getKey() == null).collect(Collectors.toList()); 148 | assertThat(tagList, hasSize(1)); 149 | assertThat(tagList.get(0).getValue(), equalTo("tag")); 150 | 151 | ArgumentCaptor thirdLevelCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 152 | verify(client, times(1)).startTestItem(same(secondNestedStepIds.get(0)), thirdLevelCaptor.capture()); 153 | 154 | StartTestItemRQ thirdLevelRq = thirdLevelCaptor.getValue(); 155 | assertThat(thirdLevelRq.getName(), equalTo("A step inside nested step")); 156 | assertThat(thirdLevelRq.isHasStats(), equalTo(Boolean.FALSE)); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/NestedStepsStepReporterTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; 12 | import cucumber.api.CucumberOptions; 13 | import cucumber.api.testng.AbstractTestNGCucumberTests; 14 | import org.apache.commons.lang3.tuple.Pair; 15 | import org.junit.jupiter.api.AfterEach; 16 | import org.junit.jupiter.api.BeforeEach; 17 | import org.junit.jupiter.api.Test; 18 | import org.mockito.ArgumentCaptor; 19 | 20 | import java.util.*; 21 | import java.util.concurrent.ExecutorService; 22 | import java.util.concurrent.Executors; 23 | import java.util.stream.Collectors; 24 | import java.util.stream.IntStream; 25 | import java.util.stream.Stream; 26 | 27 | import static org.hamcrest.MatcherAssert.assertThat; 28 | import static org.hamcrest.Matchers.*; 29 | import static org.mockito.Mockito.*; 30 | 31 | public class NestedStepsStepReporterTest { 32 | 33 | @CucumberOptions(features = "src/test/resources/features/NestedStepsFeature.feature", glue = { 34 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 35 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 36 | public static class NestedStepsStepReporter extends AbstractTestNGCucumberTests { 37 | 38 | } 39 | 40 | private final String launchId = CommonUtils.namedId("launch_"); 41 | private final String suiteId = CommonUtils.namedId("suite_"); 42 | private final String testId = CommonUtils.namedId("test_"); 43 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(4).collect(Collectors.toList()); 44 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("nested_step_")) 45 | .limit(3) 46 | .collect(Collectors.toList()); 47 | private final String nestedNestedStepId = CommonUtils.namedId("double_nested_step_"); 48 | private final List> firstLevelNestedStepIds = Stream.concat(Stream.of(Pair.of(stepIds.get(1), 49 | nestedStepIds.get(0) 50 | )), nestedStepIds.stream().skip(1).map(i -> Pair.of(stepIds.get(2), i))) 51 | .collect(Collectors.toList()); 52 | 53 | private final ListenerParameters params = TestUtils.standardParameters(); 54 | private final ReportPortalClient client = mock(ReportPortalClient.class); 55 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 56 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 57 | 58 | @BeforeEach 59 | public void setup() { 60 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 61 | TestUtils.mockNestedSteps(client, firstLevelNestedStepIds); 62 | TestUtils.mockNestedSteps(client, Pair.of(nestedStepIds.get(0), nestedNestedStepId)); 63 | TestScenarioReporter.RP.set(reportPortal); 64 | TestStepReporter.RP.set(reportPortal); 65 | } 66 | 67 | @AfterEach 68 | public void tearDown() { 69 | CommonUtils.shutdownExecutorService(executorService); 70 | } 71 | 72 | public static final List FIRST_LEVEL_NAMES = Arrays.asList("A step inside step", 73 | "A step with parameters", 74 | "A step with attributes" 75 | ); 76 | 77 | @Test 78 | public void test_step_reporter_nested_steps() { 79 | TestUtils.runTests(NestedStepsStepReporter.class); 80 | 81 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 82 | verify(client, times(1)).startTestItem(captor.capture()); 83 | verify(client, times(1)).startTestItem(same(suiteId), captor.capture()); 84 | verify(client, times(4)).startTestItem(same(testId), captor.capture()); 85 | List parentItems = captor.getAllValues(); 86 | parentItems.forEach(i -> assertThat(i.isHasStats(), anyOf(equalTo(Boolean.TRUE)))); 87 | 88 | ArgumentCaptor parentIdCapture = ArgumentCaptor.forClass(String.class); 89 | ArgumentCaptor itemRequestCapture = ArgumentCaptor.forClass(StartTestItemRQ.class); 90 | verify(client, times(1 + 4 + 3 + 1)).startTestItem(parentIdCapture.capture(), itemRequestCapture.capture()); 91 | 92 | List parentIdList = parentIdCapture.getAllValues(); 93 | List itemRequestList = itemRequestCapture.getAllValues(); 94 | 95 | Map> firstLevelRequests = IntStream.range(0, parentIdList.size()) 96 | .filter(i -> stepIds.contains(parentIdList.get(i))) 97 | .mapToObj(i -> Pair.of(parentIdList.get(i), itemRequestList.get(i))) 98 | .collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList()))); 99 | assertThat(firstLevelRequests.keySet(), hasSize(2)); 100 | Iterator>> entryIterator = firstLevelRequests.entrySet().iterator(); 101 | Map.Entry> firstPair = entryIterator.next(); 102 | Map.Entry> secondPair = entryIterator.next(); 103 | 104 | if (firstPair.getValue().size() > secondPair.getValue().size()) { 105 | Map.Entry> tmp = firstPair; 106 | firstPair = secondPair; 107 | secondPair = tmp; 108 | } 109 | 110 | StartTestItemRQ firstLevelRq1 = firstPair.getValue().get(0); 111 | assertThat(firstLevelRq1.getName(), equalTo(FIRST_LEVEL_NAMES.get(0))); 112 | assertThat(firstLevelRq1.isHasStats(), equalTo(Boolean.FALSE)); 113 | 114 | List firstLevelRqs2 = secondPair.getValue(); 115 | IntStream.range(1, FIRST_LEVEL_NAMES.size()).forEach(i -> { 116 | assertThat(firstLevelRqs2.get(i - 1).getName(), equalTo(FIRST_LEVEL_NAMES.get(i))); 117 | assertThat(firstLevelRqs2.get(i - 1).isHasStats(), equalTo(Boolean.FALSE)); 118 | }); 119 | 120 | StartTestItemRQ stepWithAttributes = firstLevelRqs2.get(1); 121 | Set attributes = stepWithAttributes.getAttributes(); 122 | assertThat(attributes, allOf(notNullValue(), hasSize(2))); 123 | List> kvAttributes = attributes.stream() 124 | .map(a -> Pair.of(a.getKey(), a.getValue())) 125 | .collect(Collectors.toList()); 126 | List> keyAndValueList = kvAttributes.stream().filter(kv -> kv.getKey() != null).collect(Collectors.toList()); 127 | assertThat(keyAndValueList, hasSize(1)); 128 | assertThat(keyAndValueList.get(0).getKey(), equalTo("key")); 129 | assertThat(keyAndValueList.get(0).getValue(), equalTo("value")); 130 | 131 | List> tagList = kvAttributes.stream().filter(kv -> kv.getKey() == null).collect(Collectors.toList()); 132 | assertThat(tagList, hasSize(1)); 133 | assertThat(tagList.get(0).getValue(), equalTo("tag")); 134 | 135 | Map> secondLevelSteps = IntStream.range(0, parentIdList.size()) 136 | .filter(i -> nestedStepIds.contains(parentIdList.get(i))) 137 | .mapToObj(i -> Pair.of(parentIdList.get(i), itemRequestList.get(i))) 138 | .collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList()))); 139 | assertThat(secondLevelSteps.entrySet(), hasSize(1)); 140 | List secondLevelRqs = secondLevelSteps.values().iterator().next(); 141 | assertThat(secondLevelRqs, hasSize(1)); 142 | 143 | StartTestItemRQ secondLevelRq = secondLevelRqs.get(0); 144 | assertThat(secondLevelRq.getName(), equalTo("A step inside nested step")); 145 | assertThat(secondLevelRq.isHasStats(), equalTo(Boolean.FALSE)); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.reportportal.utils.formatting.MarkdownUtils; 11 | import com.epam.ta.reportportal.ws.model.ParameterResource; 12 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 13 | import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; 14 | import cucumber.api.CucumberOptions; 15 | import cucumber.api.testng.AbstractTestNGCucumberTests; 16 | import okhttp3.MultipartBody; 17 | import org.apache.commons.lang3.tuple.Pair; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | import org.mockito.ArgumentCaptor; 21 | 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.concurrent.ExecutorService; 25 | import java.util.concurrent.Executors; 26 | import java.util.stream.Collectors; 27 | import java.util.stream.IntStream; 28 | import java.util.stream.Stream; 29 | 30 | import static com.epam.reportportal.cucumber.integration.util.TestUtils.filterLogs; 31 | import static org.hamcrest.MatcherAssert.assertThat; 32 | import static org.hamcrest.Matchers.*; 33 | import static org.mockito.Mockito.any; 34 | import static org.mockito.Mockito.*; 35 | 36 | /** 37 | * @author Ihar Kahadouski 38 | */ 39 | public class ParameterScenarioReporterTest { 40 | 41 | @CucumberOptions(features = "src/test/resources/features/OneSimpleAndOneScenarioOutline.feature", glue = { 42 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 43 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 44 | public static class OneSimpleAndOneScenarioOutlineScenarioReporterTest extends AbstractTestNGCucumberTests { 45 | 46 | } 47 | 48 | @CucumberOptions(features = "src/test/resources/features/DocStringParameters.feature", glue = { 49 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 50 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 51 | public static class DocstringParameterTest extends AbstractTestNGCucumberTests { 52 | } 53 | 54 | @CucumberOptions(features = "src/test/resources/features/DataTableParameter.feature", glue = { 55 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 56 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 57 | public static class DataTableParameterTest extends AbstractTestNGCucumberTests { 58 | } 59 | 60 | private static final String DOCSTRING_PARAM = "My very long parameter\nWith some new lines"; 61 | private static final String TABLE_PARAM = MarkdownUtils.formatDataTable(Arrays.asList( 62 | Arrays.asList("key", "value"), 63 | Arrays.asList("myKey", "myValue") 64 | )); 65 | 66 | private final String launchId = CommonUtils.namedId("launch_"); 67 | private final String suiteId = CommonUtils.namedId("suite_"); 68 | private final String testId = CommonUtils.namedId("test_"); 69 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()); 70 | 71 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("nested_step_")) 72 | .limit(9) 73 | .collect(Collectors.toList()); 74 | 75 | private final List> nestedStepMap = Stream.concat( 76 | IntStream.range(0, 4) 77 | .mapToObj(i -> Pair.of(stepIds.get(0), nestedStepIds.get(i))), 78 | IntStream.range(4, 9).mapToObj(i -> Pair.of(stepIds.get(1), nestedStepIds.get(i))) 79 | ).collect(Collectors.toList()); 80 | 81 | private final ReportPortalClient client = mock(ReportPortalClient.class); 82 | private final ListenerParameters parameters = TestUtils.standardParameters(); 83 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 84 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 85 | 86 | @BeforeEach 87 | public void initLaunch() { 88 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 89 | TestUtils.mockNestedSteps(client, nestedStepMap); 90 | TestUtils.mockLogging(client); 91 | TestScenarioReporter.RP.set(reportPortal); 92 | TestStepReporter.RP.set(reportPortal); 93 | } 94 | 95 | public static final List> PARAMETERS = Arrays.asList(Pair.of("String", "first"), Pair.of("int", 123)); 96 | 97 | public static final List STEP_NAMES = Arrays.asList( 98 | String.format("When I have parameter %s", PARAMETERS.get(0).getValue()), 99 | String.format("Then I emit number %s on level info", PARAMETERS.get(1).getValue().toString()) 100 | ); 101 | 102 | @Test 103 | public void verify_agent_creates_correct_step_names() { 104 | TestUtils.runTests(OneSimpleAndOneScenarioOutlineScenarioReporterTest.class); 105 | 106 | verify(client, times(1)).startTestItem(any()); 107 | verify(client, times(1)).startTestItem(same(suiteId), any()); 108 | verify(client, times(2)).startTestItem(same(testId), any()); 109 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 110 | verify(client, times(5)).startTestItem(same(stepIds.get(1)), captor.capture()); 111 | 112 | List items = captor.getAllValues() 113 | .stream() 114 | .filter(e -> e.getName().startsWith("When") || e.getName().startsWith("Then")) 115 | .collect(Collectors.toList()); 116 | IntStream.range(0, items.size()).forEach(i -> { 117 | StartTestItemRQ step = items.get(i); 118 | assertThat(step.getName(), equalTo(STEP_NAMES.get(i))); 119 | }); 120 | } 121 | 122 | @Test 123 | @SuppressWarnings("unchecked") 124 | public void verify_agent_reports_docstring_parameter() { 125 | TestUtils.runTests(DocstringParameterTest.class); 126 | 127 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 128 | verify(client, times(4)).startTestItem(same(stepIds.get(0)), captor.capture()); 129 | 130 | List items = captor.getAllValues(); 131 | List params = items.get(2).getParameters(); 132 | assertThat(params, allOf(notNullValue(), hasSize(1))); 133 | ParameterResource param1 = params.get(0); 134 | assertThat(param1.getKey(), equalTo("java.lang.String")); 135 | assertThat(param1.getValue(), equalTo(DOCSTRING_PARAM)); 136 | 137 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 138 | verify(client, atLeast(2)).log(logCaptor.capture()); 139 | List logs = filterLogs(logCaptor, l -> l.getItemUuid().equals(nestedStepIds.get(2))).stream() 140 | .map(SaveLogRQ::getMessage) 141 | .collect(Collectors.toList()); 142 | 143 | assertThat(logs, hasSize(2)); 144 | assertThat(logs, hasItem(equalTo("\"\"\"\n" + DOCSTRING_PARAM + "\n\"\"\""))); 145 | } 146 | 147 | @Test 148 | @SuppressWarnings("unchecked") 149 | public void verify_agent_reports_data_table_parameter() { 150 | TestUtils.runTests(DataTableParameterTest.class); 151 | 152 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 153 | verify(client, times(3)).startTestItem(same(stepIds.get(0)), captor.capture()); 154 | 155 | List items = captor.getAllValues(); 156 | List params = items.get(1).getParameters(); 157 | assertThat(params, allOf(notNullValue(), hasSize(1))); 158 | ParameterResource param1 = params.get(0); 159 | assertThat(param1.getKey(), equalTo("cucumber.api.DataTable")); 160 | assertThat(param1.getValue(), equalTo(TABLE_PARAM)); 161 | 162 | ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); 163 | verify(client, atLeast(1)).log(logCaptor.capture()); 164 | List logs = filterLogs(logCaptor, l -> l.getItemUuid().equals(nestedStepIds.get(1))).stream() 165 | .map(SaveLogRQ::getMessage) 166 | .collect(Collectors.toList()); 167 | 168 | assertThat(logs, hasSize(2)); 169 | assertThat(logs, hasItem(equalTo(TABLE_PARAM))); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/ScenarioOutlineStepReporterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 20 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 27 | import cucumber.api.CucumberOptions; 28 | import cucumber.api.testng.AbstractTestNGCucumberTests; 29 | import org.apache.commons.lang3.tuple.Pair; 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | import org.mockito.ArgumentCaptor; 33 | 34 | import java.util.Collections; 35 | import java.util.List; 36 | import java.util.concurrent.ExecutorService; 37 | import java.util.concurrent.Executors; 38 | import java.util.stream.Collectors; 39 | import java.util.stream.Stream; 40 | 41 | import static org.hamcrest.MatcherAssert.assertThat; 42 | import static org.hamcrest.Matchers.equalTo; 43 | import static org.hamcrest.Matchers.hasItems; 44 | import static org.mockito.Mockito.*; 45 | 46 | /** 47 | * @author Ihar Kahadouski 48 | */ 49 | public class ScenarioOutlineStepReporterTest { 50 | 51 | @CucumberOptions(features = "src/test/resources/features/BasicScenarioOutlineParameters.feature", glue = { 52 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 53 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 54 | public static class RunOutlineParametersTestStepReporter extends AbstractTestNGCucumberTests { 55 | 56 | } 57 | 58 | @CucumberOptions(features = "src/test/resources/features/DynamicScenarioOutlineNames.feature", glue = { 59 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 60 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 61 | public static class RunDynamicScenarioOutlineTitlesTestStepReporter extends AbstractTestNGCucumberTests { 62 | 63 | } 64 | 65 | private final String launchId = CommonUtils.namedId("launch_"); 66 | private final String suiteId = CommonUtils.namedId("suite_"); 67 | private final List testIds = Stream.generate(() -> CommonUtils.namedId("test_")).limit(3).collect(Collectors.toList()); 68 | private final List>> tests = testIds.stream() 69 | .map(id -> Pair.of(id, Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()))) 70 | .collect(Collectors.toList()); 71 | 72 | private final ReportPortalClient client = mock(ReportPortalClient.class); 73 | private final ListenerParameters parameters = TestUtils.standardParameters(); 74 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 75 | private final ReportPortal reportPortal = ReportPortal.create(client, parameters, executorService); 76 | 77 | @BeforeEach 78 | public void initLaunch() { 79 | TestUtils.mockLaunch(client, launchId, suiteId, tests); 80 | TestScenarioReporter.RP.set(reportPortal); 81 | TestStepReporter.RP.set(reportPortal); 82 | } 83 | 84 | // Do not add iteration indexes / numbers, since it breaks re-runs 85 | @Test 86 | public void verify_scenario_outline_names() { 87 | TestUtils.runTests(RunOutlineParametersTestStepReporter.class); 88 | 89 | verify(client, times(1)).startTestItem(any()); 90 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 91 | verify(client, times(3)).startTestItem(same(suiteId), captor.capture()); 92 | 93 | List items = captor.getAllValues().stream().map(StartTestItemRQ::getName).collect(Collectors.toList()); 94 | 95 | assertThat(items, equalTo(Collections.nCopies(3, "Scenario Outline: Test with different parameters"))); 96 | } 97 | 98 | @Test 99 | public void verify_dynamic_scenario_outline_names() { 100 | TestUtils.runTests(RunDynamicScenarioOutlineTitlesTestStepReporter.class); 101 | 102 | verify(client, times(1)).startTestItem(any()); 103 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 104 | verify(client, times(3)).startTestItem(same(suiteId), captor.capture()); 105 | 106 | List items = captor.getAllValues().stream().map(StartTestItemRQ::getName).collect(Collectors.toList()); 107 | 108 | assertThat(items, hasItems( 109 | "Scenario Outline: Test with the parameter \"first\"", 110 | "Scenario Outline: Test with the parameter \"second\"", 111 | "Scenario Outline: Test with the parameter \"third\"" 112 | )); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/SimpleVerificationTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 6 | import com.epam.reportportal.listeners.ListenerParameters; 7 | import com.epam.reportportal.service.ReportPortal; 8 | import com.epam.reportportal.service.ReportPortalClient; 9 | import com.epam.reportportal.util.test.CommonUtils; 10 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 11 | import cucumber.api.CucumberOptions; 12 | import cucumber.api.testng.AbstractTestNGCucumberTests; 13 | import org.apache.commons.lang3.tuple.Pair; 14 | import org.junit.jupiter.api.BeforeEach; 15 | import org.junit.jupiter.api.Test; 16 | import org.mockito.ArgumentCaptor; 17 | 18 | import java.util.List; 19 | import java.util.Optional; 20 | import java.util.Set; 21 | import java.util.concurrent.ExecutorService; 22 | import java.util.concurrent.Executors; 23 | import java.util.stream.Collectors; 24 | import java.util.stream.Stream; 25 | 26 | import static org.hamcrest.MatcherAssert.assertThat; 27 | import static org.hamcrest.Matchers.*; 28 | import static org.mockito.ArgumentMatchers.same; 29 | import static org.mockito.Mockito.*; 30 | 31 | public class SimpleVerificationTest { 32 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 33 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 34 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 35 | public static class SimpleTestStepReporter extends AbstractTestNGCucumberTests { 36 | 37 | } 38 | 39 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 40 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 41 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 42 | public static class SimpleTestScenarioReporter extends AbstractTestNGCucumberTests { 43 | 44 | } 45 | 46 | private final String launchId = CommonUtils.namedId("launch_"); 47 | private final String suiteId = CommonUtils.namedId("suite_"); 48 | private final String testId = CommonUtils.namedId("test_"); 49 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 50 | private final List nestedStepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 51 | private final List> nestedSteps = nestedStepIds.stream() 52 | .map(s -> Pair.of(stepIds.get(0), s)) 53 | .collect(Collectors.toList()); 54 | 55 | private final ListenerParameters params = TestUtils.standardParameters(); 56 | private final ReportPortalClient client = mock(ReportPortalClient.class); 57 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 58 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 59 | 60 | @BeforeEach 61 | public void setup() { 62 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 63 | TestScenarioReporter.RP.set(reportPortal); 64 | TestStepReporter.RP.set(reportPortal); 65 | } 66 | 67 | public static void verifyRequest(StartTestItemRQ rq, String type, boolean hasStats) { 68 | assertThat(rq.getType(), allOf(notNullValue(), equalTo(type))); 69 | assertThat(rq.getStartTime(), notNullValue()); 70 | assertThat(rq.getName(), notNullValue()); 71 | assertThat(rq.isHasStats(), equalTo(hasStats)); 72 | } 73 | 74 | @Test 75 | public void verify_step_reporter_steps_integrity() { 76 | TestUtils.runTests(SimpleTestStepReporter.class); 77 | 78 | ArgumentCaptor suiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 79 | verify(client, times(1)).startTestItem(suiteCaptor.capture()); 80 | verifyRequest(suiteCaptor.getValue(), "STORY", true); 81 | 82 | ArgumentCaptor testCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 83 | verify(client, times(1)).startTestItem(same(suiteId), testCaptor.capture()); 84 | verifyRequest(testCaptor.getValue(), "SCENARIO", true); 85 | 86 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 87 | verify(client, times(5)).startTestItem(same(testId), stepCaptor.capture()); 88 | 89 | List steps = stepCaptor.getAllValues(); 90 | Set stepTypes = steps.stream().map(StartTestItemRQ::getType).collect(Collectors.toSet()); 91 | assertThat(stepTypes, hasSize(3)); 92 | assertThat(stepTypes, hasItems("BEFORE_TEST", "STEP", "AFTER_TEST")); 93 | 94 | Optional beforeTest = steps.stream().filter(s -> "BEFORE_TEST".equals(s.getType())).findAny(); 95 | //noinspection OptionalGetWithoutIsPresent 96 | verifyRequest(beforeTest.get(), "BEFORE_TEST", true); 97 | steps.stream().filter(s -> "STEP".equals(s.getType())).forEach(rq -> verifyRequest(rq, "STEP", true)); 98 | Optional afterTest = steps.stream().filter(s -> "AFTER_TEST".equals(s.getType())).findAny(); 99 | //noinspection OptionalGetWithoutIsPresent 100 | verifyRequest(afterTest.get(), "AFTER_TEST", true); 101 | } 102 | 103 | @Test 104 | public void verify_scenario_reporter_steps_integrity() { 105 | TestUtils.mockNestedSteps(client, nestedSteps); 106 | TestUtils.runTests(SimpleTestScenarioReporter.class); 107 | 108 | ArgumentCaptor mainSuiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 109 | verify(client, times(1)).startTestItem(mainSuiteCaptor.capture()); 110 | verifyRequest(mainSuiteCaptor.getValue(), "SUITE", true); 111 | 112 | ArgumentCaptor suiteCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 113 | verify(client, times(1)).startTestItem(same(suiteId), suiteCaptor.capture()); 114 | verifyRequest(suiteCaptor.getValue(), "STORY", true); 115 | 116 | ArgumentCaptor testCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 117 | verify(client, times(1)).startTestItem(same(testId), testCaptor.capture()); 118 | verifyRequest(testCaptor.getValue(), "STEP", true); 119 | 120 | ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); 121 | verify(client, times(5)).startTestItem(same(stepIds.get(0)), stepCaptor.capture()); 122 | 123 | List steps = stepCaptor.getAllValues(); 124 | Set stepTypes = steps.stream().map(StartTestItemRQ::getType).collect(Collectors.toSet()); 125 | assertThat(stepTypes, hasSize(3)); 126 | assertThat(stepTypes, hasItems("BEFORE_TEST", "STEP", "AFTER_TEST")); 127 | 128 | Optional beforeTest = steps.stream().filter(s -> "BEFORE_TEST".equals(s.getType())).findAny(); 129 | //noinspection OptionalGetWithoutIsPresent 130 | verifyRequest(beforeTest.get(), "BEFORE_TEST", false); 131 | steps.stream().filter(s -> "STEP".equals(s.getType())).forEach(rq -> verifyRequest(rq, "STEP", false)); 132 | Optional afterTest = steps.stream().filter(s -> "AFTER_TEST".equals(s.getType())).findAny(); 133 | //noinspection OptionalGetWithoutIsPresent 134 | verifyRequest(afterTest.get(), "AFTER_TEST", false); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/SystemAttributesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber; 18 | 19 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 20 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 21 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 22 | import com.epam.reportportal.listeners.ListenerParameters; 23 | import com.epam.reportportal.service.ReportPortal; 24 | import com.epam.reportportal.service.ReportPortalClient; 25 | import com.epam.reportportal.util.test.CommonUtils; 26 | import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; 27 | import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; 28 | import cucumber.api.CucumberOptions; 29 | import cucumber.api.testng.AbstractTestNGCucumberTests; 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | import org.mockito.ArgumentCaptor; 33 | 34 | import java.util.Collections; 35 | import java.util.List; 36 | import java.util.Set; 37 | import java.util.concurrent.ExecutorService; 38 | import java.util.concurrent.Executors; 39 | import java.util.stream.Collectors; 40 | import java.util.stream.Stream; 41 | 42 | import static org.hamcrest.MatcherAssert.assertThat; 43 | import static org.hamcrest.Matchers.*; 44 | import static org.mockito.Mockito.mock; 45 | import static org.mockito.Mockito.verify; 46 | 47 | public class SystemAttributesTest { 48 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 49 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 50 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 51 | public static class SimpleTestStepReporter extends AbstractTestNGCucumberTests { 52 | 53 | } 54 | 55 | private final String launchId = CommonUtils.namedId("launch_"); 56 | private final String suiteId = CommonUtils.namedId("suite_"); 57 | private final String testId = CommonUtils.namedId("test_"); 58 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 59 | private final ReportPortalClient client = mock(ReportPortalClient.class); 60 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 61 | 62 | @BeforeEach 63 | public void setup() { 64 | ListenerParameters params = TestUtils.standardParameters(); 65 | params.setAttributes(Collections.singleton(new ItemAttributesRQ("key", "value"))); 66 | ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 67 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 68 | TestScenarioReporter.RP.set(reportPortal); 69 | TestStepReporter.RP.set(reportPortal); 70 | } 71 | 72 | @Test 73 | public void verify_start_launch_request_contains_system_attributes() { 74 | TestUtils.runTests(SimpleTestStepReporter.class); 75 | 76 | ArgumentCaptor startCaptor = ArgumentCaptor.forClass(StartLaunchRQ.class); 77 | verify(client).startLaunch(startCaptor.capture()); 78 | 79 | StartLaunchRQ launchStart = startCaptor.getValue(); 80 | 81 | Set attributes = launchStart.getAttributes(); 82 | assertThat(attributes, allOf(notNullValue(), hasSize(greaterThan(0)))); 83 | Set attributesStr = attributes.stream() 84 | .filter(ItemAttributesRQ::isSystem) 85 | .map(e -> e.getKey() + ":" + e.getValue()) 86 | .collect(Collectors.toSet()); 87 | assertThat(attributesStr, hasSize(4)); 88 | assertThat(attributesStr, hasItem("skippedIssue:true")); 89 | assertThat(attributesStr, hasItem("agent:test-agent|test-1.0")); 90 | assertThat(attributesStr, hasItem(startsWith("os:"))); 91 | assertThat(attributesStr, hasItem(startsWith("jvm:"))); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/TestCaseIdTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber; 2 | 3 | import com.epam.reportportal.cucumber.integration.TestScenarioReporter; 4 | import com.epam.reportportal.cucumber.integration.TestStepReporter; 5 | import com.epam.reportportal.cucumber.integration.feature.TestCaseIdOnMethodSteps; 6 | import com.epam.reportportal.cucumber.integration.util.TestUtils; 7 | import com.epam.reportportal.listeners.ListenerParameters; 8 | import com.epam.reportportal.service.ReportPortal; 9 | import com.epam.reportportal.service.ReportPortalClient; 10 | import com.epam.reportportal.util.test.CommonUtils; 11 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 12 | import cucumber.api.CucumberOptions; 13 | import cucumber.api.testng.AbstractTestNGCucumberTests; 14 | import org.junit.jupiter.api.AfterEach; 15 | import org.junit.jupiter.api.BeforeEach; 16 | import org.junit.jupiter.api.Test; 17 | import org.mockito.ArgumentCaptor; 18 | 19 | import java.util.List; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.concurrent.Executors; 22 | import java.util.stream.Collectors; 23 | import java.util.stream.Stream; 24 | 25 | import static org.hamcrest.MatcherAssert.assertThat; 26 | import static org.hamcrest.Matchers.*; 27 | import static org.mockito.Mockito.any; 28 | import static org.mockito.Mockito.*; 29 | 30 | public class TestCaseIdTest { 31 | 32 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 33 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 34 | "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) 35 | public static class RunBellyTestScenarioReporter extends AbstractTestNGCucumberTests { 36 | 37 | } 38 | 39 | @CucumberOptions(features = "src/test/resources/features/belly.feature", glue = { 40 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 41 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 42 | public static class RunBellyTestStepReporter extends AbstractTestNGCucumberTests { 43 | 44 | } 45 | 46 | @CucumberOptions(features = "src/test/resources/features/TestCaseIdOnAMethod.feature", glue = { 47 | "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", 48 | "com.epam.reportportal.cucumber.integration.TestStepReporter" }) 49 | public static class StepDefStepReporter extends AbstractTestNGCucumberTests { 50 | 51 | } 52 | 53 | private final String launchId = CommonUtils.namedId("launch_"); 54 | private final String suiteId = CommonUtils.namedId("suite_"); 55 | private final String testId = CommonUtils.namedId("test_"); 56 | private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); 57 | 58 | private final ListenerParameters params = TestUtils.standardParameters(); 59 | private final ReportPortalClient client = mock(ReportPortalClient.class); 60 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); 61 | private final ReportPortal reportPortal = ReportPortal.create(client, params, executorService); 62 | 63 | @BeforeEach 64 | public void setup() { 65 | TestUtils.mockLaunch(client, launchId, suiteId, testId, stepIds); 66 | TestScenarioReporter.RP.set(reportPortal); 67 | TestStepReporter.RP.set(reportPortal); 68 | } 69 | 70 | @AfterEach 71 | public void tearDown() { 72 | CommonUtils.shutdownExecutorService(executorService); 73 | } 74 | 75 | @Test 76 | public void shouldSendCaseIdWhenParametrizedScenarioReporter() { 77 | TestUtils.runTests(RunBellyTestScenarioReporter.class); 78 | 79 | verify(client, times(1)).startTestItem(any()); 80 | verify(client, times(1)).startTestItem(same(suiteId), any()); 81 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 82 | verify(client, times(1)).startTestItem(same(testId), captor.capture()); 83 | 84 | StartTestItemRQ rq = captor.getValue(); 85 | assertThat(rq.getTestCaseId(), equalTo("src/test/resources/features/belly.feature:4")); 86 | } 87 | 88 | @Test 89 | public void shouldSendCaseIdWhenParametrizedStepReporter() { 90 | TestUtils.runTests(RunBellyTestStepReporter.class); 91 | 92 | verify(client, times(1)).startTestItem(any()); 93 | verify(client, times(1)).startTestItem(same(suiteId), any()); 94 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 95 | verify(client, times(5)).startTestItem(same(testId), captor.capture()); 96 | 97 | List allSteps = captor.getAllValues(); 98 | List testSteps = allSteps.stream() 99 | .filter(s -> !(s.getName().startsWith("Before") || s.getName().startsWith("After"))) 100 | .collect(Collectors.toList()); 101 | List testCaseIds = testSteps.stream().map(StartTestItemRQ::getTestCaseId).collect(Collectors.toList()); 102 | 103 | assertThat(testCaseIds, hasSize(3)); 104 | 105 | assertThat(testCaseIds, hasItem("com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.I_have_cukes_in_my_belly[42]")); 106 | assertThat(testCaseIds, hasItem("com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.I_wait[1]")); 107 | assertThat(testCaseIds, hasItem("com.epam.reportportal.cucumber.integration.feature.BellyStepdefs.my_belly_should_growl[]")); 108 | } 109 | 110 | @Test 111 | public void verify_test_case_id_bypassed_through_annotation_on_a_stepdef() { 112 | TestUtils.runTests(StepDefStepReporter.class); 113 | ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); 114 | verify(client, times(3)).startTestItem(same(testId), captor.capture()); 115 | 116 | List steps = captor.getAllValues().stream().filter(s -> s.getType().equals("STEP")).collect(Collectors.toList()); 117 | assertThat(steps, hasSize(1)); 118 | assertThat(steps.get(0).getTestCaseId(), equalTo(TestCaseIdOnMethodSteps.TEST_CASE_ID)); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/TestScenarioReporter.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration; 2 | 3 | import com.epam.reportportal.cucumber.ScenarioReporter; 4 | import com.epam.reportportal.service.ReportPortal; 5 | 6 | public class TestScenarioReporter extends ScenarioReporter { 7 | public static final ThreadLocal RP = new ThreadLocal<>(); 8 | 9 | @Override 10 | protected ReportPortal buildReportPortal() { 11 | return RP.get(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/TestScenarioReporterWithPause.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration; 18 | 19 | import com.epam.reportportal.cucumber.ScenarioReporter; 20 | import com.epam.reportportal.service.ReportPortal; 21 | import com.epam.reportportal.util.test.CommonUtils; 22 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 23 | import gherkin.formatter.model.Feature; 24 | 25 | import javax.annotation.Nonnull; 26 | 27 | public class TestScenarioReporterWithPause extends ScenarioReporter { 28 | public static final ThreadLocal RP = new ThreadLocal<>(); 29 | 30 | @Override 31 | protected ReportPortal buildReportPortal() { 32 | return RP.get(); 33 | } 34 | 35 | @Override 36 | @Nonnull 37 | protected StartTestItemRQ buildStartFeatureRequest(@Nonnull Feature feature, @Nonnull String uri) { 38 | StartTestItemRQ result = super.buildStartFeatureRequest(feature, uri); 39 | try { 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } catch (InterruptedException ignore) { 42 | } 43 | return result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/TestStepReporter.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration; 2 | 3 | import com.epam.reportportal.cucumber.StepReporter; 4 | import com.epam.reportportal.service.ReportPortal; 5 | 6 | public class TestStepReporter extends StepReporter { 7 | public static final ThreadLocal RP = new ThreadLocal<>(); 8 | 9 | @Override 10 | protected ReportPortal buildReportPortal() { 11 | return RP.get(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/TestStepReporterWithPause.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration; 18 | 19 | import com.epam.reportportal.cucumber.StepReporter; 20 | import com.epam.reportportal.service.ReportPortal; 21 | import com.epam.reportportal.util.test.CommonUtils; 22 | import com.epam.ta.reportportal.ws.model.StartTestItemRQ; 23 | import gherkin.formatter.model.Scenario; 24 | 25 | import javax.annotation.Nonnull; 26 | 27 | public class TestStepReporterWithPause extends StepReporter { 28 | public static final ThreadLocal RP = new ThreadLocal<>(); 29 | 30 | @Override 31 | protected ReportPortal buildReportPortal() { 32 | return RP.get(); 33 | } 34 | 35 | @Override 36 | @Nonnull 37 | protected StartTestItemRQ buildStartScenarioRequest(@Nonnull Scenario scenario, @Nonnull String uri) { 38 | StartTestItemRQ result = super.buildStartScenarioRequest(scenario, uri); 39 | try { 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } catch (InterruptedException ignore) { 42 | } 43 | return result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/callback/TestScenarioReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.callback; 18 | 19 | import com.epam.reportportal.cucumber.ScenarioReporter; 20 | import com.epam.reportportal.service.ReportPortal; 21 | 22 | public class TestScenarioReporter extends ScenarioReporter { 23 | public static final ThreadLocal RP = new ThreadLocal<>(); 24 | 25 | @Override 26 | protected ReportPortal buildReportPortal() { 27 | return RP.get(); 28 | } 29 | 30 | public static void addReportPortal(ReportPortal rp) { 31 | setReportPortal(rp); 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/callback/TestStepReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.callback; 18 | 19 | import com.epam.reportportal.cucumber.StepReporter; 20 | import com.epam.reportportal.service.ReportPortal; 21 | 22 | public class TestStepReporter extends StepReporter { 23 | public static final ThreadLocal RP = new ThreadLocal<>(); 24 | 25 | @Override 26 | protected ReportPortal buildReportPortal() { 27 | return RP.get(); 28 | } 29 | 30 | public static void addReportPortal(ReportPortal rp) { 31 | setReportPortal(rp); 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/callback/scenario/CallbackReportingSteps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.callback.scenario; 18 | 19 | import com.epam.reportportal.cucumber.AbstractReporter; 20 | import com.epam.reportportal.cucumber.util.ItemTreeUtils; 21 | import com.epam.reportportal.service.tree.ItemTreeReporter; 22 | import com.epam.reportportal.service.tree.TestItemTree; 23 | import com.epam.reportportal.util.test.CommonUtils; 24 | import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; 25 | import cucumber.api.Scenario; 26 | import cucumber.api.java.After; 27 | import cucumber.api.java.en.Given; 28 | 29 | import java.util.Calendar; 30 | 31 | public class CallbackReportingSteps { 32 | public static final String STEP_TEXT = "I have a step for callback reporting"; 33 | 34 | @Given(STEP_TEXT) 35 | public void a_step_for_callback_reporting() throws InterruptedException { 36 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 37 | } 38 | 39 | @After 40 | public void after(Scenario scenario) throws InterruptedException { 41 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 42 | if (scenario.getName().contains("failure")) { 43 | ItemTreeUtils.retrieveLeaf( 44 | "src/test/resources/features/CallbackReportingScenario.feature", 45 | 3, 46 | STEP_TEXT, 47 | AbstractReporter.ITEM_TREE 48 | ).ifPresent(itemLeaf -> { 49 | sendFinishRequest(itemLeaf, "FAILED", "secondTest"); 50 | attachLog(itemLeaf); 51 | }); 52 | } else { 53 | ItemTreeUtils.retrieveLeaf( 54 | "src/test/resources/features/CallbackReportingScenario.feature", 55 | 6, 56 | STEP_TEXT, 57 | AbstractReporter.ITEM_TREE 58 | ).ifPresent(itemLeaf -> sendFinishRequest(itemLeaf, "PASSED", "firstTest")); 59 | } 60 | } 61 | 62 | private void sendFinishRequest(TestItemTree.TestItemLeaf testResultLeaf, String status, String description) { 63 | FinishTestItemRQ finishTestItemRQ = new FinishTestItemRQ(); 64 | finishTestItemRQ.setDescription(description); 65 | finishTestItemRQ.setStatus(status); 66 | finishTestItemRQ.setEndTime(Calendar.getInstance().getTime()); 67 | //noinspection ResultOfMethodCallIgnored 68 | ItemTreeReporter.finishItem(AbstractReporter.getReportPortal().getClient(), 69 | finishTestItemRQ, 70 | AbstractReporter.ITEM_TREE.getLaunchId(), 71 | testResultLeaf 72 | ) 73 | .blockingGet(); 74 | } 75 | 76 | private void attachLog(TestItemTree.TestItemLeaf testItemLeaf) { 77 | ItemTreeReporter.sendLog(AbstractReporter.getReportPortal().getClient(), 78 | "ERROR", 79 | "Error message", 80 | Calendar.getInstance().getTime(), 81 | AbstractReporter.ITEM_TREE.getLaunchId(), 82 | testItemLeaf 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/callback/step/CallbackReportingSteps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.callback.step; 18 | 19 | import com.epam.reportportal.cucumber.AbstractReporter; 20 | import com.epam.reportportal.cucumber.util.ItemTreeUtils; 21 | import com.epam.reportportal.service.tree.ItemTreeReporter; 22 | import com.epam.reportportal.service.tree.TestItemTree; 23 | import com.epam.reportportal.util.test.CommonUtils; 24 | import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; 25 | import cucumber.api.Scenario; 26 | import cucumber.api.java.After; 27 | import cucumber.api.java.en.Given; 28 | 29 | import java.util.Calendar; 30 | 31 | public class CallbackReportingSteps { 32 | 33 | public static final String STEP_TEXT = "I have a step for callback reporting"; 34 | 35 | @Given(STEP_TEXT) 36 | public void a_step_for_callback_reporting() throws InterruptedException { 37 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 38 | } 39 | 40 | @After 41 | public void after(Scenario scenario) throws InterruptedException { 42 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 43 | if (scenario.getName().contains("failure")) { 44 | ItemTreeUtils.retrieveLeaf( 45 | "src/test/resources/features/CallbackReportingScenario.feature", 46 | 3, 47 | STEP_TEXT, 48 | AbstractReporter.ITEM_TREE 49 | ).ifPresent(itemLeaf -> { 50 | sendFinishRequest(itemLeaf, "FAILED", "secondTest"); 51 | attachLog(itemLeaf); 52 | }); 53 | } else { 54 | ItemTreeUtils.retrieveLeaf( 55 | "src/test/resources/features/CallbackReportingScenario.feature", 56 | 6, 57 | STEP_TEXT, 58 | AbstractReporter.ITEM_TREE 59 | ).ifPresent(itemLeaf -> sendFinishRequest(itemLeaf, "PASSED", "firstTest")); 60 | } 61 | } 62 | 63 | private void sendFinishRequest(TestItemTree.TestItemLeaf testResultLeaf, String status, String description) { 64 | FinishTestItemRQ finishTestItemRQ = new FinishTestItemRQ(); 65 | finishTestItemRQ.setDescription(description); 66 | finishTestItemRQ.setStatus(status); 67 | finishTestItemRQ.setEndTime(Calendar.getInstance().getTime()); 68 | //noinspection ResultOfMethodCallIgnored 69 | ItemTreeReporter.finishItem(AbstractReporter.getReportPortal().getClient(), 70 | finishTestItemRQ, 71 | AbstractReporter.ITEM_TREE.getLaunchId(), 72 | testResultLeaf 73 | ) 74 | .cache() 75 | .blockingGet(); 76 | } 77 | 78 | private void attachLog(TestItemTree.TestItemLeaf testItemLeaf) { 79 | ItemTreeReporter.sendLog(AbstractReporter.getReportPortal().getClient(), 80 | "ERROR", 81 | "Error message", 82 | Calendar.getInstance().getTime(), 83 | AbstractReporter.ITEM_TREE.getLaunchId(), 84 | testItemLeaf 85 | ); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/duplicate/DuplicateStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.duplicate; 18 | 19 | import com.epam.reportportal.cucumber.integration.feature.EmptySteps; 20 | import cucumber.api.java.en.Then; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | public class DuplicateStep { 25 | private static final Logger LOGGER = LoggerFactory.getLogger(EmptySteps.class); 26 | 27 | @Then("I have duplicate step") 28 | public void i_have_duplicate_step() { 29 | LOGGER.info("Inside 'I have duplicate step'"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/duplicate/OriginalSteps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.duplicate; 18 | 19 | import com.epam.reportportal.cucumber.integration.feature.EmptySteps; 20 | import cucumber.api.java.en.Given; 21 | import cucumber.api.java.en.Then; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | public class OriginalSteps { 26 | private static final Logger LOGGER = LoggerFactory.getLogger(EmptySteps.class); 27 | 28 | @Given("I have an unique step") 29 | public void i_have_unique_step() { 30 | LOGGER.info("Inside 'I have an unique step'"); 31 | } 32 | 33 | @Then("I have duplicate step") 34 | public void i_have_duplicate_step() { 35 | LOGGER.info("Inside 'I have duplicate step'"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/embed/image/EmbeddingStepdefs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.embed.image; 18 | 19 | import com.epam.reportportal.util.test.CommonUtils; 20 | import cucumber.api.Scenario; 21 | import cucumber.api.java.After; 22 | import cucumber.api.java.en.Given; 23 | import org.apache.commons.io.IOUtils; 24 | 25 | import java.io.IOException; 26 | import java.util.Objects; 27 | 28 | public class EmbeddingStepdefs { 29 | public String type; 30 | 31 | @Given("I have a dummy step to make a screenshot with correct mime type") 32 | public void i_have_a_dummy_step_to_make_a_screenshot_correct_type() throws InterruptedException { 33 | type = "image/jpeg"; 34 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 35 | } 36 | 37 | @Given("I have a dummy step to make a screenshot with incorrect mime type") 38 | public void i_have_a_dummy_step_to_make_a_screenshot_incorrect_type() throws InterruptedException { 39 | type = "image/png"; 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } 42 | 43 | @Given("I have a dummy step to make a screenshot with partially correct mime type") 44 | public void i_have_a_dummy_step_to_make_a_screenshot_partially_correct_type() throws InterruptedException { 45 | type = "jpeg"; 46 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 47 | } 48 | 49 | @After 50 | public void embedAnImage(Scenario scenario) throws IOException { 51 | scenario.embed(IOUtils.toByteArray(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("files/unlucky.jpg"))), 52 | type 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/embed/pdf/EmbeddingStepdefs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.embed.pdf; 18 | 19 | import com.epam.reportportal.util.test.CommonUtils; 20 | import cucumber.api.Scenario; 21 | import cucumber.api.java.After; 22 | import cucumber.api.java.en.Given; 23 | import org.apache.commons.io.IOUtils; 24 | 25 | import java.io.IOException; 26 | import java.util.Objects; 27 | 28 | public class EmbeddingStepdefs { 29 | public String type; 30 | 31 | @Given("I have a dummy step to attach a pdf correct mime type") 32 | public void i_have_a_dummy_step_to_make_a_screenshot_correct_type() throws InterruptedException { 33 | type = "application/pdf"; 34 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 35 | } 36 | 37 | @Given("I have a dummy step to attach a pdf with incorrect mime type") 38 | public void i_have_a_dummy_step_to_make_a_screenshot_incorrect_type() throws InterruptedException { 39 | type = "image/png"; 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } 42 | 43 | @Given("I have a dummy step to attach a pdf with partially correct mime type") 44 | public void i_have_a_dummy_step_to_make_a_screenshot_partially_correct_type() throws InterruptedException { 45 | type = "pdf"; 46 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 47 | } 48 | 49 | @After 50 | public void embedAnPdf(Scenario scenario) throws IOException { 51 | scenario.embed(IOUtils.toByteArray(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("files/test.pdf"))), 52 | type 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/embed/text/EmbeddingStepdefs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.embed.text; 18 | 19 | import com.epam.reportportal.util.test.CommonUtils; 20 | import cucumber.api.Scenario; 21 | import cucumber.api.java.After; 22 | import cucumber.api.java.en.Given; 23 | import org.apache.commons.io.IOUtils; 24 | 25 | import java.io.IOException; 26 | import java.util.Objects; 27 | 28 | public class EmbeddingStepdefs { 29 | public String type; 30 | 31 | @Given("I have a dummy step to attach a text with correct mime type") 32 | public void i_have_a_dummy_step_to_attach_a_text_correct_type() throws InterruptedException { 33 | type = "text/plain"; 34 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 35 | } 36 | 37 | @Given("I have a dummy step to attach a text with incorrect mime type") 38 | public void i_have_a_dummy_step_to_attach_a_text_incorrect_type() throws InterruptedException { 39 | type = "image/png"; 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } 42 | 43 | @Given("I have a dummy step to attach a text with partially correct mime type") 44 | public void i_have_a_dummy_step_to_attach_a_text_partially_correct_type() throws InterruptedException { 45 | type = "text"; 46 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 47 | } 48 | 49 | @After 50 | public void embedAText(Scenario scenario) throws IOException { 51 | scenario.embed(IOUtils.toByteArray(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("files/plain.txt"))), 52 | type 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/embed/zip/EmbeddingStepdefs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.embed.zip; 18 | 19 | import com.epam.reportportal.util.test.CommonUtils; 20 | import cucumber.api.Scenario; 21 | import cucumber.api.java.After; 22 | import cucumber.api.java.en.Given; 23 | import org.apache.commons.io.IOUtils; 24 | 25 | import java.io.IOException; 26 | import java.util.Objects; 27 | 28 | public class EmbeddingStepdefs { 29 | public String type; 30 | 31 | @Given("I have a dummy step to attach an archive with correct mime type") 32 | public void i_have_a_dummy_step_to_attach_an_archive_correct_type() throws InterruptedException { 33 | type = "application/zip"; 34 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 35 | } 36 | 37 | @Given("I have a dummy step to attach an archive with incorrect mime type") 38 | public void i_have_a_dummy_step_to_attach_an_archive_incorrect_type() throws InterruptedException { 39 | type = "image/png"; 40 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 41 | } 42 | 43 | @Given("I have a dummy step to attach an archive with partially correct mime type") 44 | public void i_have_a_dummy_step_to_attach_an_archive_partially_correct_type() throws InterruptedException { 45 | type = "zip"; 46 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 47 | } 48 | 49 | @After 50 | public void embedAnArchive(Scenario scenario) throws IOException { 51 | scenario.embed(IOUtils.toByteArray(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("files/demo.zip"))), 52 | type 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/AmbiguousSteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import cucumber.api.java.en.Given; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | public class AmbiguousSteps { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(AmbiguousSteps.class); 9 | 10 | @Given("I have an ambiguous step (\\w+)") 11 | public void i_have_an_ambiguous_step(String param) { 12 | LOGGER.info("Inside 'I have an ambiguous step', parameter: " + param); 13 | } 14 | 15 | @Given("I have an ambiguous step two") 16 | public void i_have_an_ambiguous_step_two() { 17 | LOGGER.info("Inside 'I have an ambiguous step two'"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/BellyStepdefs.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.annotations.attribute.Attribute; 4 | import com.epam.reportportal.annotations.attribute.Attributes; 5 | import com.epam.reportportal.annotations.attribute.MultiKeyAttribute; 6 | import com.epam.reportportal.annotations.attribute.MultiValueAttribute; 7 | import com.epam.reportportal.cucumber.integration.service.Belly; 8 | import cucumber.api.java.en.Given; 9 | import cucumber.api.java.en.Then; 10 | import cucumber.api.java.en.When; 11 | 12 | import static org.hamcrest.MatcherAssert.assertThat; 13 | import static org.hamcrest.Matchers.equalTo; 14 | 15 | public class BellyStepdefs { 16 | 17 | private final Belly belly = new Belly(); 18 | 19 | @Attributes(attributes = { @Attribute(key = "key", value = "value") }) 20 | @Given("^I have (\\d+) cukes in my belly$") 21 | public void I_have_cukes_in_my_belly(int cukes) { 22 | belly.eat(cukes); 23 | } 24 | 25 | @Attributes(attributes = { @Attribute(key = "key1", value = "value1"), 26 | @Attribute(key = "key2", value = "value2") }, multiKeyAttributes = { @MultiKeyAttribute(keys = { "k1", "k2" }, value = "v") }) 27 | @When("^I wait (\\d+) hour$") 28 | public void I_wait(int hours) { 29 | belly.wait(hours); 30 | } 31 | 32 | @Attributes(multiValueAttributes = { @MultiValueAttribute(isNullKey = true, values = { "v1", "v2" }) }) 33 | @Then("^my belly should growl$") 34 | public void my_belly_should_growl() { 35 | assertThat(belly.growl(), equalTo(Boolean.TRUE)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/DummyHooks.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.util.test.CommonUtils; 4 | import cucumber.api.java.After; 5 | import cucumber.api.java.Before; 6 | 7 | public class DummyHooks { 8 | 9 | @Before 10 | public void beforePause() throws InterruptedException { 11 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 12 | } 13 | 14 | @After 15 | public void afterPause() throws InterruptedException { 16 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/EmptySteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import cucumber.api.java.en.Given; 4 | import cucumber.api.java.en.Then; 5 | import cucumber.api.java.en.When; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class EmptySteps { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(EmptySteps.class); 11 | 12 | @Given("I have empty step") 13 | public void i_have_empty_step() { 14 | LOGGER.info("Inside 'I have empty step'"); 15 | } 16 | 17 | @Then("I have another empty step") 18 | public void i_have_another_empty_step() { 19 | LOGGER.info("Inside 'I have another empty step'"); 20 | } 21 | 22 | @When("I have one more empty step") 23 | public void i_have_one_more_empty_step() { 24 | LOGGER.info("I have one more empty step'"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/FailedSteps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 EPAM Systems 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.epam.reportportal.cucumber.integration.feature; 18 | 19 | import cucumber.api.java.en.Given; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | public class FailedSteps { 24 | private static final Logger LOGGER = LoggerFactory.getLogger(FailedSteps.class); 25 | 26 | public static final String ERROR_MESSAGE = "A failed step"; 27 | 28 | @Given("I have a failed step") 29 | public void i_have_a_failed_step() { 30 | LOGGER.info("Inside 'I have a failed step'"); 31 | throw new IllegalStateException(ERROR_MESSAGE); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/ManualStepReporterSteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.listeners.ItemStatus; 4 | import com.epam.reportportal.service.Launch; 5 | import com.epam.reportportal.service.step.StepReporter; 6 | import com.epam.reportportal.util.test.CommonUtils; 7 | import cucumber.api.java.en.Given; 8 | import cucumber.api.java.en.Then; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import java.io.File; 13 | 14 | public class ManualStepReporterSteps { 15 | private static final Logger LOGGER = LoggerFactory.getLogger(ManualStepReporterSteps.class); 16 | public static final String FIRST_NAME = "I am the first nested step"; 17 | public static final String SECOND_NAME = "I am the second nested step"; 18 | public static final String THIRD_NAME = "I am the third nested step"; 19 | public static final String FIRST_NESTED_STEP_LOG = "Inside first nested step"; 20 | public static final String SECOND_NESTED_STEP_LOG = "Inside second nested step"; 21 | public static final String THIRD_NESTED_STEP_LOG = "Third error log of the second step"; 22 | public static final String DURING_SECOND_NESTED_STEP_LOG = "A log entry during the second nested step report"; 23 | 24 | @Given("A step with a manual step") 25 | public void i_have_a_step_with_a_manual_step() throws InterruptedException { 26 | StepReporter stepReporter = Launch.currentLaunch().getStepReporter(); 27 | 28 | stepReporter.sendStep(FIRST_NAME); 29 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 30 | LOGGER.info(FIRST_NESTED_STEP_LOG); 31 | } 32 | 33 | @Then("A step with two manual steps") 34 | public void i_have_a_step_with_two_manual_steps() throws InterruptedException { 35 | StepReporter stepReporter = Launch.currentLaunch().getStepReporter(); 36 | 37 | stepReporter.sendStep(SECOND_NAME, DURING_SECOND_NESTED_STEP_LOG); 38 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 39 | LOGGER.info(SECOND_NESTED_STEP_LOG); 40 | 41 | stepReporter.sendStep(ItemStatus.FAILED, THIRD_NAME, new File("files/unlucky.jpg")); 42 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 43 | LOGGER.error(THIRD_NESTED_STEP_LOG); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/NestedSteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.annotations.Step; 4 | import com.epam.reportportal.annotations.attribute.Attribute; 5 | import com.epam.reportportal.annotations.attribute.AttributeValue; 6 | import com.epam.reportportal.annotations.attribute.Attributes; 7 | import com.epam.reportportal.util.test.CommonUtils; 8 | import cucumber.api.java.After; 9 | import cucumber.api.java.Before; 10 | import cucumber.api.java.en.Given; 11 | import cucumber.api.java.en.When; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | public class NestedSteps { 16 | private static final Logger LOGGER = LoggerFactory.getLogger(NestedSteps.class); 17 | 18 | public static final long PARAM1 = 7L; 19 | 20 | public static final String PARAM2 = "second param"; 21 | 22 | @Given("^I have a step$") 23 | public void i_have_empty_step() throws InterruptedException { 24 | LOGGER.info("Inside 'I have a step'"); 25 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 26 | and_a_step_inside_step(); 27 | } 28 | 29 | @Step("A step inside step") 30 | public void and_a_step_inside_step() throws InterruptedException { 31 | LOGGER.info("Inside 'and_a_step_inside_nested_step'"); 32 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 33 | and_a_step_inside_nested_step(); 34 | } 35 | 36 | @Step("A step inside nested step") 37 | public void and_a_step_inside_nested_step() { 38 | LOGGER.info("Inside 'and_a_step_inside_nested_step'"); 39 | } 40 | 41 | @When("I have one more step") 42 | public void i_have_one_more_empty_step() throws InterruptedException { 43 | LOGGER.info("Inside 'I have one more step'"); 44 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 45 | with_a_step_with_parameters(PARAM1, PARAM2); 46 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 47 | with_a_step_with_attributes(); 48 | } 49 | 50 | @Step("A step with parameters") 51 | public void with_a_step_with_parameters(long one, String two) throws InterruptedException { 52 | LOGGER.info("Inside 'with_a_step_with_parameters': '" + one + "'; '" + two + "'"); 53 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 54 | } 55 | 56 | @Step("A step with attributes") 57 | @Attributes(attributes = @Attribute(key = "key", value = "value"), attributeValues = @AttributeValue("tag")) 58 | public void with_a_step_with_attributes() throws InterruptedException { 59 | LOGGER.info("Inside 'with_a_step_with_attributes'"); 60 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/ParametersTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.util.test.CommonUtils; 4 | import cucumber.api.java.After; 5 | import cucumber.api.java.Before; 6 | import cucumber.api.java.en.Given; 7 | import cucumber.api.java.en.Then; 8 | import cucumber.api.java.en.When; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import static org.testng.Assert.assertEquals; 13 | 14 | /** 15 | * @author Ihar Kahadouski 16 | */ 17 | public class ParametersTest { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(ParametersTest.class); 20 | private int itemsCount; 21 | 22 | @Given("I have (\\d+) (\\w+) in my pocket") 23 | public void iHaveNumberItemInMyPocket(int number, String item) { 24 | itemsCount = number; 25 | LOGGER.info("I have {} {} in my pocket", number, item); 26 | 27 | } 28 | 29 | @When("^I eat one$") 30 | public void iEatOne() { 31 | itemsCount -= 1; 32 | LOGGER.info("I eat one"); 33 | } 34 | 35 | @Then("I have (\\d+) in my pocket") 36 | public void iHaveResultInMyPocket(int result) { 37 | assertEquals(result, itemsCount); 38 | LOGGER.info("I have {} in my pocket", result); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/ReportsTestWithParameters.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.annotations.ParameterKey; 4 | import com.epam.reportportal.util.test.CommonUtils; 5 | import cucumber.api.DataTable; 6 | import cucumber.api.java.en.Given; 7 | import cucumber.api.java.en.Then; 8 | import cucumber.api.java.en.When; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class ReportsTestWithParameters { 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(ReportsTestWithParameters.class); 15 | 16 | @Given("It is test with parameters") 17 | public void infoLevel() { 18 | LOGGER.info("It is test with parameters"); 19 | } 20 | 21 | @When("I have parameter (\\w+)") 22 | public void iHaveParameterStr(String str) { 23 | LOGGER.info("String parameter {}", str); 24 | } 25 | 26 | @When("I have a docstring parameter:") 27 | public void iHaveParameterDocstring(String str) { 28 | iHaveParameterStr(str); 29 | } 30 | 31 | @Then("I emit number (\\d+) on level info") 32 | public void infoLevel(int parameters) { 33 | LOGGER.info("Test with parameters: " + parameters); 34 | } 35 | 36 | @Given("It is a step with an integer parameter (\\d+)") 37 | public void iHaveAnIntInlineParameter(int parameter) { 38 | LOGGER.info("Integer parameter: " + parameter); 39 | } 40 | 41 | @When("I have a step with a string parameter (\\w+)") 42 | public void iHaveAnStrInlineParameter(String str) { 43 | LOGGER.info("String parameter {}", str); 44 | } 45 | 46 | @When("I have a step with a named string parameter (\\w+)") 47 | public void iHaveANamedStrInlineParameter(@ParameterKey("my name") String str) { 48 | LOGGER.info("String parameter {}", str); 49 | } 50 | 51 | @Given("a step with a data table:") 52 | public void testStep(DataTable dataTable) throws InterruptedException { 53 | LOGGER.info("DataTable parameter:\r\n{}", dataTable.toString()); 54 | Thread.sleep(CommonUtils.MINIMAL_TEST_PAUSE); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/feature/TestCaseIdOnMethodSteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.feature; 2 | 3 | import com.epam.reportportal.annotations.TestCaseId; 4 | import cucumber.api.java.en.Given; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class TestCaseIdOnMethodSteps { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(TestCaseIdOnMethodSteps.class); 10 | public static final String TEST_CASE_ID = "My test case id"; 11 | 12 | 13 | @Given("I have a test case ID on a step definition method") 14 | @TestCaseId(TEST_CASE_ID) 15 | public void i_have_a_test_case_id_on_a_stepdef_method() { 16 | LOGGER.info("Inside 'i_have_a_test_case_id_on_a_stepdef_method' method"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/hooks/EmptySteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.hooks; 2 | 3 | import cucumber.api.java.After; 4 | import cucumber.api.java.Before; 5 | import cucumber.api.java.en.Given; 6 | import cucumber.api.java.en.Then; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class EmptySteps { 11 | private static final Logger LOGGER = LoggerFactory.getLogger(EmptySteps.class); 12 | 13 | @Before 14 | public void my_before_hook() { 15 | LOGGER.info("Inside 'my_before_hook'"); 16 | } 17 | 18 | @Given("I have empty step") 19 | public void i_have_empty_step() { 20 | LOGGER.info("Inside 'I have empty step'"); 21 | } 22 | 23 | @Then("I have another empty step") 24 | public void i_have_another_empty_step() { 25 | LOGGER.info("Inside 'I have another empty step'"); 26 | } 27 | 28 | @After 29 | public void my_after_hook() { 30 | LOGGER.info("Inside 'my_after_hook'"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/nohooks/EmptySteps.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.nohooks; 2 | 3 | import cucumber.api.java.en.Given; 4 | import cucumber.api.java.en.Then; 5 | import cucumber.api.java.en.When; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class EmptySteps { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(EmptySteps.class); 11 | 12 | @Given("I have empty step") 13 | public void i_have_empty_step() { 14 | LOGGER.info("Inside 'I have empty step'"); 15 | } 16 | 17 | @Then("I have another empty step") 18 | public void i_have_another_empty_step() { 19 | LOGGER.info("Inside 'I have another empty step'"); 20 | } 21 | 22 | @When("I have one more empty step") 23 | public void i_have_one_more_empty_step() { 24 | LOGGER.info("I have one more empty step'"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/service/Belly.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.service; 2 | 3 | public class Belly { 4 | 5 | private int satiation = 0; 6 | 7 | public void eat(int cukes) { 8 | satiation += cukes; 9 | } 10 | 11 | public void wait(int hours) { 12 | if ((hours > 0) && (satiation > 0)) { 13 | int utilized = 60 * hours; 14 | if (utilized > satiation) { 15 | utilized = satiation; 16 | } 17 | satiation -= utilized; 18 | } 19 | } 20 | 21 | public boolean growl() { 22 | return satiation <= 0; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/epam/reportportal/cucumber/integration/util/TestUtils.java: -------------------------------------------------------------------------------- 1 | package com.epam.reportportal.cucumber.integration.util; 2 | 3 | import com.epam.reportportal.listeners.ListenerParameters; 4 | import com.epam.reportportal.service.ReportPortalClient; 5 | import com.epam.reportportal.utils.http.HttpRequestUtils; 6 | import com.epam.ta.reportportal.ws.model.BatchSaveOperatingRS; 7 | import com.epam.ta.reportportal.ws.model.Constants; 8 | import com.epam.ta.reportportal.ws.model.OperationCompletionRS; 9 | import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS; 10 | import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS; 11 | import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; 12 | import com.fasterxml.jackson.core.type.TypeReference; 13 | import io.reactivex.Maybe; 14 | import okhttp3.MultipartBody; 15 | import okio.Buffer; 16 | import org.apache.commons.lang3.tuple.Pair; 17 | import org.mockito.ArgumentCaptor; 18 | import org.mockito.stubbing.Answer; 19 | import org.testng.TestNG; 20 | 21 | import java.io.IOException; 22 | import java.util.*; 23 | import java.util.function.Predicate; 24 | import java.util.stream.Collectors; 25 | 26 | import static com.epam.reportportal.util.test.CommonUtils.generateUniqueId; 27 | import static java.util.Optional.ofNullable; 28 | import static org.mockito.ArgumentMatchers.*; 29 | import static org.mockito.Mockito.when; 30 | 31 | /** 32 | * @author Ihar Kahadouski 33 | */ 34 | public class TestUtils { 35 | 36 | public static final String TEST_NAME = "TestContainer"; 37 | 38 | public static TestNG runTests(Class... classes) { 39 | final TestNG testNG = new TestNG(true); 40 | testNG.setTestClasses(classes); 41 | testNG.setDefaultTestName(TEST_NAME); 42 | testNG.setExcludedGroups("optional"); 43 | testNG.run(); 44 | return testNG; 45 | } 46 | 47 | public static void mockLaunch(ReportPortalClient client, String launchUuid, String suiteUuid, String testClassUuid, 48 | String testMethodUuid) { 49 | mockLaunch(client, launchUuid, suiteUuid, testClassUuid, Collections.singleton(testMethodUuid)); 50 | } 51 | 52 | public static void mockLaunch(ReportPortalClient client, String launchUuid, String suiteUuid, String testClassUuid, 53 | Collection testMethodUuidList) { 54 | mockLaunch(client, launchUuid, suiteUuid, Collections.singletonList(Pair.of(testClassUuid, testMethodUuidList))); 55 | } 56 | 57 | @SuppressWarnings("unchecked") 58 | public static > void mockLaunch(ReportPortalClient client, String launchUuid, String suiteUuid, 59 | Collection> testSteps) { 60 | when(client.startLaunch(any())).thenReturn(Maybe.just(new StartLaunchRS(launchUuid, 1L))); 61 | 62 | Maybe suiteMaybe = Maybe.just(new ItemCreatedRS(suiteUuid, suiteUuid)); 63 | when(client.startTestItem(any())).thenReturn(suiteMaybe); 64 | 65 | List> testResponses = testSteps.stream() 66 | .map(Pair::getKey) 67 | .map(uuid -> Maybe.just(new ItemCreatedRS(uuid, uuid))) 68 | .collect(Collectors.toList()); 69 | 70 | Maybe first = testResponses.get(0); 71 | Maybe[] other = testResponses.subList(1, testResponses.size()).toArray(new Maybe[0]); 72 | when(client.startTestItem(same(suiteUuid), any())).thenReturn(first, other); 73 | 74 | testSteps.forEach(test -> { 75 | String testClassUuid = test.getKey(); 76 | List> stepResponses = test.getValue() 77 | .stream() 78 | .map(uuid -> Maybe.just(new ItemCreatedRS(uuid, uuid))) 79 | .collect(Collectors.toList()); 80 | 81 | Maybe myFirst = stepResponses.get(0); 82 | Maybe[] myOther = stepResponses.subList(1, stepResponses.size()).toArray(new Maybe[0]); 83 | when(client.startTestItem(same(testClassUuid), any())).thenReturn(myFirst, myOther); 84 | new HashSet<>(test.getValue()).forEach(testMethodUuid -> when(client.finishTestItem(same(testMethodUuid), any())).thenReturn( 85 | Maybe.just(new OperationCompletionRS()))); 86 | when(client.finishTestItem(same(testClassUuid), any())).thenReturn(Maybe.just(new OperationCompletionRS())); 87 | }); 88 | 89 | Maybe suiteFinishMaybe = Maybe.just(new OperationCompletionRS()); 90 | when(client.finishTestItem(eq(suiteUuid), any())).thenReturn(suiteFinishMaybe); 91 | 92 | when(client.finishLaunch(eq(launchUuid), any())).thenReturn(Maybe.just(new OperationCompletionRS())); 93 | } 94 | 95 | @SuppressWarnings("unchecked") 96 | public static void mockLogging(ReportPortalClient client) { 97 | when(client.log(any(List.class))).thenReturn(Maybe.just(new BatchSaveOperatingRS())); 98 | } 99 | 100 | public static void mockNestedSteps(ReportPortalClient client, Pair parentNestedPair) { 101 | mockNestedSteps(client, Collections.singletonList(parentNestedPair)); 102 | } 103 | 104 | @SuppressWarnings("unchecked") 105 | public static void mockNestedSteps(final ReportPortalClient client, final List> parentNestedPairs) { 106 | Map> responseOrders = parentNestedPairs.stream() 107 | .collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList()))); 108 | responseOrders.forEach((k, v) -> { 109 | List> responses = v.stream() 110 | .map(uuid -> Maybe.just(new ItemCreatedRS(uuid, uuid))) 111 | .collect(Collectors.toList()); 112 | 113 | Maybe first = responses.get(0); 114 | Maybe[] other = responses.subList(1, responses.size()).toArray(new Maybe[0]); 115 | when(client.startTestItem(eq(k), any())).thenReturn(first, other); 116 | }); 117 | parentNestedPairs.forEach(p -> when(client.finishTestItem( 118 | same(p.getValue()), 119 | any() 120 | )).thenAnswer((Answer>) invocation -> Maybe.just(new OperationCompletionRS()))); 121 | } 122 | 123 | public static ListenerParameters standardParameters() { 124 | ListenerParameters result = new ListenerParameters(); 125 | result.setClientJoin(false); 126 | result.setBatchLogsSize(1); 127 | result.setLaunchName("My-test-launch" + generateUniqueId()); 128 | result.setProjectName("test-project"); 129 | result.setEnable(true); 130 | result.setBaseUrl("http://localhost:8080"); 131 | return result; 132 | } 133 | 134 | public static List extractJsonParts(List parts) { 135 | return parts.stream() 136 | .filter(p -> ofNullable(p.headers()).map(headers -> headers.get("Content-Disposition")) 137 | .map(h -> h.contains(Constants.LOG_REQUEST_JSON_PART)) 138 | .orElse(false)) 139 | .map(MultipartBody.Part::body) 140 | .map(b -> { 141 | Buffer buf = new Buffer(); 142 | try { 143 | b.writeTo(buf); 144 | } catch (IOException ignore) { 145 | } 146 | return buf.readByteArray(); 147 | }) 148 | .map(b -> { 149 | try { 150 | return HttpRequestUtils.MAPPER.readValue(b, new TypeReference>() { 151 | }); 152 | } catch (IOException e) { 153 | return Collections.emptyList(); 154 | } 155 | }) 156 | .flatMap(Collection::stream) 157 | .collect(Collectors.toList()); 158 | } 159 | 160 | public static List filterLogs(ArgumentCaptor> logCaptor, Predicate filter) { 161 | return logCaptor.getAllValues().stream().flatMap(l -> extractJsonParts(l).stream()).filter(filter).collect(Collectors.toList()); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension: -------------------------------------------------------------------------------- 1 | org.mockito.junit.jupiter.MockitoExtension 2 | -------------------------------------------------------------------------------- /src/test/resources/agent.properties: -------------------------------------------------------------------------------- 1 | agent.name=test-agent 2 | agent.version=test-1.0 -------------------------------------------------------------------------------- /src/test/resources/features/AmbiguousTest.feature: -------------------------------------------------------------------------------- 1 | Feature: Ambiguous test feature 2 | 3 | Scenario: Test ambiguous step 4 | Given I have an ambiguous step two 5 | -------------------------------------------------------------------------------- /src/test/resources/features/BackgroundScenario.feature: -------------------------------------------------------------------------------- 1 | Feature: Test scenario with a background 2 | 3 | Background: Init our scenario 4 | Given I have empty step 5 | 6 | Scenario: The first scenario 7 | Then I have another empty step 8 | 9 | Scenario: The second scenario 10 | Then I have one more empty step 11 | -------------------------------------------------------------------------------- /src/test/resources/features/BasicInlineParameters.feature: -------------------------------------------------------------------------------- 1 | Feature: Basic test with inline parameters 2 | 3 | Scenario: Test with a inline parameters 4 | Given It is a step with an integer parameter 42 5 | When I have a step with a string parameter string 6 | When I have a step with a named string parameter string -------------------------------------------------------------------------------- /src/test/resources/features/BasicScenarioOutlineParameters.feature: -------------------------------------------------------------------------------- 1 | Feature: Basic test with parameters 2 | 3 | Scenario Outline: Test with different parameters 4 | Given It is test with parameters 5 | When I have parameter 6 | Then I emit number on level info 7 | 8 | Examples: 9 | | str | parameters | 10 | | first | 123 | 11 | | second | 12345 | 12 | | third | 12345678 | -------------------------------------------------------------------------------- /src/test/resources/features/CallbackReportingScenario.feature: -------------------------------------------------------------------------------- 1 | Feature: Callback reporting feature 2 | 3 | Scenario: A failure scenario 4 | Given I have a step for callback reporting 5 | 6 | Scenario: A passing scenario 7 | Given I have a step for callback reporting -------------------------------------------------------------------------------- /src/test/resources/features/DataTableParameter.feature: -------------------------------------------------------------------------------- 1 | Feature: A basic test with a Data Table parameter 2 | 3 | Scenario: Test with Data Table 4 | Given a step with a data table: 5 | | key | value | 6 | | myKey | myValue | 7 | -------------------------------------------------------------------------------- /src/test/resources/features/DocStringParameters.feature: -------------------------------------------------------------------------------- 1 | Feature: Basic test with a docstring parameter 2 | 3 | Scenario: Test with a docstring parameter 4 | Given It is test with parameters 5 | When I have a docstring parameter: 6 | """ 7 | My very long parameter 8 | With some new lines 9 | """ 10 | -------------------------------------------------------------------------------- /src/test/resources/features/DummyScenario.feature: -------------------------------------------------------------------------------- 1 | Feature: Test dummy scenario 2 | 3 | Scenario: The scenario 4 | Given I have empty step 5 | Then I have another empty step 6 | -------------------------------------------------------------------------------- /src/test/resources/features/DuplicateStep.feature: -------------------------------------------------------------------------------- 1 | Feature: Test dummy scenario 2 | 3 | Scenario: The scenario 4 | Given I have an unique step 5 | Then I have duplicate step 6 | -------------------------------------------------------------------------------- /src/test/resources/features/DynamicScenarioOutlineNames.feature: -------------------------------------------------------------------------------- 1 | Feature: Dynamic scenario outline names 2 | 3 | Scenario Outline: Test with the parameter 4 | Given It is test with parameters 5 | When I have parameter 6 | Then I emit number on level info 7 | 8 | Examples: 9 | | str | parameters | 10 | | "first" | 123 | 11 | | "second" | 12345 | 12 | | "third" | 12345678 | 13 | -------------------------------------------------------------------------------- /src/test/resources/features/FailedScenario.feature: -------------------------------------------------------------------------------- 1 | Feature: Test failed scenario 2 | 3 | Scenario: The scenario 4 | Given I have a failed step 5 | -------------------------------------------------------------------------------- /src/test/resources/features/ManualStepReporter.feature: -------------------------------------------------------------------------------- 1 | Feature: Manual StepReporter 2 | 3 | Scenario: Test manual StepReporter 4 | Given A step with a manual step 5 | Then A step with two manual steps 6 | -------------------------------------------------------------------------------- /src/test/resources/features/NestedStepsFeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Test scenario with nested steps 2 | Scenario: Nested steps scenario 3 | Given I have a step 4 | When I have one more step 5 | -------------------------------------------------------------------------------- /src/test/resources/features/OneSimpleAndOneScenarioOutline.feature: -------------------------------------------------------------------------------- 1 | Feature: Basic test with parameters 2 | 3 | Scenario: The scenario 4 | Given I have empty step 5 | Then I have another empty step 6 | 7 | Scenario Outline: Test with different parameters 8 | Given It is test with parameters 9 | When I have parameter 10 | Then I emit number on level info 11 | 12 | Examples: 13 | | str | parameters | 14 | | first | 123 | -------------------------------------------------------------------------------- /src/test/resources/features/TestCaseIdOnAMethod.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Case ID on a method feature 2 | 3 | Scenario: Test Case ID 4 | Given I have a test case ID on a step definition method 5 | -------------------------------------------------------------------------------- /src/test/resources/features/TwoScenarioInOne.feature: -------------------------------------------------------------------------------- 1 | Feature: Test with two scenarios 2 | 3 | Scenario: The first scenario 4 | Given I have empty step 5 | Then I have another empty step 6 | 7 | Scenario: The second scenario 8 | Given I have empty step 9 | Then I have another empty step 10 | -------------------------------------------------------------------------------- /src/test/resources/features/TwoScenarioOutlineParameters.feature: -------------------------------------------------------------------------------- 1 | Feature: Test with two parameters 2 | 3 | Scenario Outline: Test with few parameter in method 4 | Given I have in my pocket 5 | When I eat one 6 | Then I have in my pocket 7 | 8 | Examples: 9 | | number | item | result | 10 | | 100 | apples | 99 | 11 | | 3 | cucumbers | 2 | 12 | | 1 | cake | 0 | 13 | -------------------------------------------------------------------------------- /src/test/resources/features/belly.feature: -------------------------------------------------------------------------------- 1 | Feature: Belly 2 | 3 | @ok 4 | Scenario: a few cukes 5 | Given I have 42 cukes in my belly 6 | When I wait 1 hour 7 | Then my belly should growl 8 | -------------------------------------------------------------------------------- /src/test/resources/features/embedding/ArchiveEmbeddingFeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Archive embedding feature 2 | 3 | Scenario: Embed a correct mime type Archive 4 | Given I have a dummy step to attach an archive with correct mime type 5 | 6 | Scenario: Embed an incorrect mime type Archive 7 | Given I have a dummy step to attach an archive with incorrect mime type 8 | 9 | Scenario: Embed a partially correct mime type Archive 10 | Given I have a dummy step to attach an archive with partially correct mime type -------------------------------------------------------------------------------- /src/test/resources/features/embedding/ImageEmbeddingFeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Image embedding feature 2 | 3 | Scenario: Embed a correct mime type image 4 | Given I have a dummy step to make a screenshot with correct mime type 5 | 6 | Scenario: Embed an incorrect mime type image 7 | Given I have a dummy step to make a screenshot with incorrect mime type 8 | 9 | Scenario: Embed a partially correct mime type image 10 | Given I have a dummy step to make a screenshot with partially correct mime type -------------------------------------------------------------------------------- /src/test/resources/features/embedding/PdfEmbeddingFeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Pdf embedding feature 2 | 3 | Scenario: Embed a correct mime type pdf 4 | Given I have a dummy step to attach a pdf correct mime type 5 | 6 | Scenario: Embed an incorrect mime type pdf 7 | Given I have a dummy step to attach a pdf with incorrect mime type 8 | 9 | Scenario: Embed a partially correct mime type pdf 10 | Given I have a dummy step to attach a pdf with partially correct mime type -------------------------------------------------------------------------------- /src/test/resources/features/embedding/TextEmbeddingFeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Text embedding feature 2 | 3 | Scenario: Embed a correct mime type text 4 | Given I have a dummy step to attach a text with correct mime type 5 | 6 | Scenario: Embed an incorrect mime type text 7 | Given I have a dummy step to attach a text with incorrect mime type 8 | 9 | Scenario: Embed a partially correct mime type text 10 | Given I have a dummy step to attach a text with partially correct mime type -------------------------------------------------------------------------------- /src/test/resources/files/demo.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reportportal/agent-java-cucumber/5efd14cc70556d62c68a7cd54872ffc30b3f0c6a/src/test/resources/files/demo.zip -------------------------------------------------------------------------------- /src/test/resources/files/plain.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020 EPAM Systems 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. -------------------------------------------------------------------------------- /src/test/resources/files/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reportportal/agent-java-cucumber/5efd14cc70556d62c68a7cd54872ffc30b3f0c6a/src/test/resources/files/test.pdf -------------------------------------------------------------------------------- /src/test/resources/files/unlucky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reportportal/agent-java-cucumber/5efd14cc70556d62c68a7cd54872ffc30b3f0c6a/src/test/resources/files/unlucky.jpg -------------------------------------------------------------------------------- /src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.extensions.autodetection.enabled=true 2 | -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{HH:mm:ss.SSS} %-5level %logger{5} - %thread - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | %d{HH:mm:ss.SSS} [%t] %-5level - %msg%n 16 | [%t] - %msg%n 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | --------------------------------------------------------------------------------