diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb14edb6f..8f537bc9c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,8 @@ name: Build +permissions: + contents: read + on: workflow_dispatch: pull_request: @@ -15,10 +18,10 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v6 - name: "Set up JDK" - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'zulu' java-version: 21 diff --git a/.github/workflows/dependency-submission.yml b/.github/workflows/dependency-submission.yml index 79b0496d0..748dfe670 100644 --- a/.github/workflows/dependency-submission.yml +++ b/.github/workflows/dependency-submission.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@v4 + uses: gradle/actions/dependency-submission@v5 env: DEPENDENCY_GRAPH_EXCLUDE_PROJECTS: ':allure-java-commons-test' DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS: 'runtimeClasspath' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index e0d99fc81..f49976b59 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -3,9 +3,14 @@ name: "Set theme labels" on: - pull_request_target +permissions: + contents: read + jobs: triage: runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - uses: actions/labeler@v4 with: diff --git a/.github/workflows/labels-verify.yml b/.github/workflows/labels-verify.yml index 0c18ecb77..7315a905a 100644 --- a/.github/workflows/labels-verify.yml +++ b/.github/workflows/labels-verify.yml @@ -4,9 +4,14 @@ on: pull_request_target: types: [opened, labeled, unlabeled, synchronize] +permissions: + contents: none + jobs: triage: runs-on: ubuntu-latest + permissions: + pull-requests: read steps: - uses: baev/action-label-verify@main with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 28af62d51..2295deb90 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,14 +4,17 @@ on: release: types: [ published ] +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v6 - name: "Set up JDK" - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'zulu' java-version: '21' @@ -27,7 +30,7 @@ jobs: - name: "Gradle Publish" run: | - ./gradlew publishToSonatype -Pversion=${GITHUB_REF:10} \ + ./gradlew publishToSonatype closeSonatypeStagingRepository -Pversion=${GITHUB_REF:10} \ -Psigning.keyId=${GPG_KEY_ID} \ -Psigning.password=${GPG_PASSPHRASE} \ -Psigning.secretKeyRingFile=${GITHUB_WORKSPACE}/${GPG_KEY_ID}.gpg diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f8821c29..7d5ace556 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,9 +11,14 @@ on: description: "The next version in . format WITHOUT SNAPSHOT SUFFIX" required: true +permissions: + contents: read + jobs: triage: runs-on: ubuntu-latest + permissions: + contents: write steps: - name: "Check release version" run: | @@ -21,7 +26,7 @@ jobs: - name: "Check next version" run: | expr "${{ github.event.inputs.nextVersion }}" : '[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*$' - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v6 with: token: ${{ secrets.QAMETA_CI }} diff --git a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentData.java b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentData.java index e097b8815..5c6d09f34 100644 --- a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentData.java +++ b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentData.java @@ -20,6 +20,7 @@ * * @author charlie (Dmitry Baev). */ +@FunctionalInterface public interface AttachmentData { String getName(); diff --git a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentProcessor.java b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentProcessor.java index 467261139..99129f89a 100644 --- a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentProcessor.java +++ b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentProcessor.java @@ -19,6 +19,7 @@ * @param the type of attachment data. * @author charlie (Dmitry Baev). */ +@FunctionalInterface public interface AttachmentProcessor { void addAttachment(T attachmentData, AttachmentRenderer renderer); diff --git a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentRenderer.java b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentRenderer.java index 355f6d782..2b6f5b1a5 100644 --- a/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentRenderer.java +++ b/allure-attachments/src/main/java/io/qameta/allure/attachment/AttachmentRenderer.java @@ -20,6 +20,7 @@ * @author charlie (Dmitry Baev). */ @SuppressWarnings("PMD.AvoidUncheckedExceptionsInSignatures") +@FunctionalInterface public interface AttachmentRenderer { AttachmentContent render(T attachmentData) throws AttachmentRenderException; diff --git a/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpRequestAttachment.java b/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpRequestAttachment.java index 75cda2e96..a51052cf7 100644 --- a/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpRequestAttachment.java +++ b/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpRequestAttachment.java @@ -112,7 +112,6 @@ public String toString() { /** * Builder for HttpRequestAttachment. */ - @SuppressWarnings("PMD.AvoidFieldNameMatchingMethodName") public static final class Builder { private final String name; diff --git a/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpResponseAttachment.java b/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpResponseAttachment.java index 2369e10f8..d606af57e 100644 --- a/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpResponseAttachment.java +++ b/allure-attachments/src/main/java/io/qameta/allure/attachment/http/HttpResponseAttachment.java @@ -90,7 +90,6 @@ public String toString() { /** * Builder for HttpRequestAttachment. */ - @SuppressWarnings("PMD.AvoidFieldNameMatchingMethodName") public static final class Builder { private final String name; diff --git a/allure-awaitility/build.gradle.kts b/allure-awaitility/build.gradle.kts index e7afac938..3c9ed6c79 100644 --- a/allure-awaitility/build.gradle.kts +++ b/allure-awaitility/build.gradle.kts @@ -2,7 +2,7 @@ description = "Allure Awaitlity Integration" val agent: Configuration by configurations.creating -val awaitilityVersion = "4.2.1" +val awaitilityVersion = "4.3.0" dependencies { agent("org.aspectj:aspectjweaver") diff --git a/allure-awaitility/readme.md b/allure-awaitility/readme.md index 5a93b6a42..1fcb34691 100644 --- a/allure-awaitility/readme.md +++ b/allure-awaitility/readme.md @@ -7,11 +7,16 @@ For more information about awaitility highly recommended look into [awaitility u ### Configuration examples -Single line for all awaitility conditions in project +Single line for all awaitility conditions in project ```java Awaitility.setDefaultConditionEvaluationListener(new AllureAwaitilityListener()); ``` +And another line to prevent breaking allure lifecycle for Steps inside Awaitility evaluations +```java +Awaitility.pollInSameThread(); +``` + Moreover, it's possible logging only few unstable conditions with method `.conditionEvaluationListener()` ```java final AtomicInteger atomicInteger = new AtomicInteger(0); diff --git a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/ConditionListenersPositiveTest.java b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/ConditionListenersPositiveTest.java index 74cfa88f2..1a3bad814 100644 --- a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/ConditionListenersPositiveTest.java +++ b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/ConditionListenersPositiveTest.java @@ -18,6 +18,8 @@ import io.qameta.allure.model.Status; import io.qameta.allure.model.StepResult; import io.qameta.allure.model.TestResult; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DynamicNode; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; @@ -38,6 +40,11 @@ class ConditionListenersPositiveTest { + @BeforeAll + static void setup() { + Awaitility.pollInSameThread(); + } + /** * Positive test to check proper allure steps generation. *

diff --git a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsNegativeTest.java b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsNegativeTest.java index 29577aee2..5c169fd63 100644 --- a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsNegativeTest.java +++ b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsNegativeTest.java @@ -48,6 +48,7 @@ void reset() { @BeforeEach void setup() { + Awaitility.pollInSameThread(); Awaitility.setDefaultConditionEvaluationListener(new AllureAwaitilityListener()); } diff --git a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsPositiveTest.java b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsPositiveTest.java index db00c41e6..52a6b50db 100644 --- a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsPositiveTest.java +++ b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/GlobalSettingsPositiveTest.java @@ -48,6 +48,7 @@ void reset() { @BeforeEach void setup() { + Awaitility.pollInSameThread(); Awaitility.setDefaultConditionEvaluationListener(new AllureAwaitilityListener()); } diff --git a/allure-awaitility/src/test/java/io/qameta/allure/awaitility/MultipleConditionsTest.java b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/MultipleConditionsTest.java new file mode 100644 index 000000000..36a74a164 --- /dev/null +++ b/allure-awaitility/src/test/java/io/qameta/allure/awaitility/MultipleConditionsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016-2024 Qameta Software Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.qameta.allure.awaitility; + +import io.qameta.allure.model.Status; +import io.qameta.allure.model.TestResult; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.*; + +import java.util.List; +import java.util.stream.Stream; + +import static io.qameta.allure.test.RunUtils.runWithinTestContext; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +public class MultipleConditionsTest { + + @AfterEach + void reset() { + Awaitility.reset(); + } + + @BeforeEach + void setup() { + Awaitility.pollInSameThread(); + Awaitility.setDefaultConditionEvaluationListener(new AllureAwaitilityListener()); + } + + @TestFactory + Stream bothAwaitilityStepsShouldAppearTest() { + final List testResult = runWithinTestContext(() -> { + await().with() + .alias("First waiting") + .until(() -> true); + await().with() + .alias("Second waiting") + .until(() -> true); + }, + AllureAwaitilityListener::setLifecycle + ).getTestResults(); + + return Stream.of( + DynamicTest.dynamicTest("Exactly 2 top level step for 2 awaitility condition", () -> + assertThat(testResult.get(0).getSteps()) + .describedAs("Allure TestResult contains exactly 2 top level step for 2 awaitility condition") + .hasSize(2) + ), + DynamicTest.dynamicTest("All top level step for all awaitility condition has PASSED", () -> + assertThat(testResult.get(0).getSteps()) + .describedAs("Allure TestResult contains all top level step for all awaitility with PASSED condition") + .allMatch(step -> Status.PASSED.equals(step.getStatus())) + ) + ); + } + +} diff --git a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java index 8998226d8..b5a5d429d 100644 --- a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java +++ b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java @@ -82,7 +82,6 @@ "ClassDataAbstractionCoupling", "ClassFanOutComplexity", "MultipleStringLiterals", - "PMD.ExcessiveImports", }) public class AllureCucumber4Jvm implements ConcurrentEventListener { diff --git a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/LabelBuilder.java b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/LabelBuilder.java index a0ed3c28b..fbcbb3f10 100644 --- a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/LabelBuilder.java +++ b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/LabelBuilder.java @@ -49,8 +49,8 @@ /** * Scenario labels and links builder. */ -@SuppressWarnings({"CyclomaticComplexity", "PMD.CyclomaticComplexity", "PMD.NcssCount", "MultipleStringLiterals"}) -class LabelBuilder { +@SuppressWarnings({"CyclomaticComplexity", "MultipleStringLiterals"}) +final class LabelBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(LabelBuilder.class); private static final String COMPOSITE_TAG_DELIMITER = "="; @@ -89,34 +89,34 @@ class LabelBuilder { switch (tagKey) { case SEVERITY: - getScenarioLabels().add(ResultsUtils.createSeverityLabel(tagValue.toLowerCase())); + scenarioLabels.add(ResultsUtils.createSeverityLabel(tagValue.toLowerCase())); break; case TMS_LINK: - getScenarioLinks().add(ResultsUtils.createTmsLink(tagValue)); + scenarioLinks.add(ResultsUtils.createTmsLink(tagValue)); break; case ISSUE_LINK: - getScenarioLinks().add(ResultsUtils.createIssueLink(tagValue)); + scenarioLinks.add(ResultsUtils.createIssueLink(tagValue)); break; case PLAIN_LINK: - getScenarioLinks().add(ResultsUtils.createLink(null, tagValue, tagValue, null)); + scenarioLinks.add(ResultsUtils.createLink(null, tagValue, tagValue, null)); break; default: LOGGER.warn("Composite tag {} is not supported. adding it as RAW", tagKey); - getScenarioLabels().add(getTagLabel(tag)); + scenarioLabels.add(getTagLabel(tag)); break; } } else if (tagParser.isPureSeverityTag(tag)) { - getScenarioLabels().add(ResultsUtils.createSeverityLabel(tagString.substring(1))); + scenarioLabels.add(ResultsUtils.createSeverityLabel(tagString.substring(1))); } else if (!tagParser.isResultTag(tag)) { - getScenarioLabels().add(getTagLabel(tag)); + scenarioLabels.add(getTagLabel(tag)); } } final String featureName = feature.getName(); final String uri = scenario.getUri(); - getScenarioLabels().addAll(ResultsUtils.getProvidedLabels()); - getScenarioLabels().addAll(Arrays.asList( + scenarioLabels.addAll(ResultsUtils.getProvidedLabels()); + scenarioLabels.addAll(Arrays.asList( createHostLabel(), createThreadLabel(), createFeatureLabel(featureName), @@ -130,7 +130,7 @@ class LabelBuilder { featurePackage(uri, featureName) .map(ResultsUtils::createPackageLabel) - .ifPresent(getScenarioLabels()::add); + .ifPresent(scenarioLabels::add); } public List