All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.qameta.allure.spock2.AllureSpock2 Maven / Gradle / Ivy

The newest version!
/*
 *  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.spock2;

import io.qameta.allure.Allure;
import io.qameta.allure.AllureId;
import io.qameta.allure.AllureLifecycle;
import io.qameta.allure.model.FixtureResult;
import io.qameta.allure.model.Label;
import io.qameta.allure.model.Link;
import io.qameta.allure.model.Parameter;
import io.qameta.allure.model.Status;
import io.qameta.allure.model.StatusDetails;
import io.qameta.allure.model.TestResult;
import io.qameta.allure.model.TestResultContainer;
import io.qameta.allure.testfilter.FileTestPlanSupplier;
import io.qameta.allure.testfilter.TestPlan;
import io.qameta.allure.testfilter.TestPlanV1_0;
import io.qameta.allure.util.AnnotationUtils;
import io.qameta.allure.util.ExceptionUtils;
import io.qameta.allure.util.ResultsUtils;
import org.spockframework.runtime.AbstractRunListener;
import org.spockframework.runtime.extension.IGlobalExtension;
import org.spockframework.runtime.extension.IMethodInterceptor;
import org.spockframework.runtime.extension.IMethodInvocation;
import org.spockframework.runtime.model.ErrorInfo;
import org.spockframework.runtime.model.FeatureInfo;
import org.spockframework.runtime.model.IterationInfo;
import org.spockframework.runtime.model.MethodInfo;
import org.spockframework.runtime.model.MethodKind;
import org.spockframework.runtime.model.SpecInfo;
import org.spockframework.runtime.model.TestTag;

import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static io.qameta.allure.util.ResultsUtils.bytesToHex;
import static io.qameta.allure.util.ResultsUtils.createFrameworkLabel;
import static io.qameta.allure.util.ResultsUtils.createHostLabel;
import static io.qameta.allure.util.ResultsUtils.createLanguageLabel;
import static io.qameta.allure.util.ResultsUtils.createPackageLabel;
import static io.qameta.allure.util.ResultsUtils.createParameter;
import static io.qameta.allure.util.ResultsUtils.createParentSuiteLabel;
import static io.qameta.allure.util.ResultsUtils.createSubSuiteLabel;
import static io.qameta.allure.util.ResultsUtils.createSuiteLabel;
import static io.qameta.allure.util.ResultsUtils.createTestClassLabel;
import static io.qameta.allure.util.ResultsUtils.createTestMethodLabel;
import static io.qameta.allure.util.ResultsUtils.createThreadLabel;
import static io.qameta.allure.util.ResultsUtils.firstNonEmpty;
import static io.qameta.allure.util.ResultsUtils.getMd5Digest;
import static io.qameta.allure.util.ResultsUtils.getProvidedLabels;
import static io.qameta.allure.util.ResultsUtils.getStatus;
import static io.qameta.allure.util.ResultsUtils.getStatusDetails;
import static io.qameta.allure.util.ResultsUtils.md5;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.comparing;

/**
 * @author charlie (Dmitry Baev).
 */
@SuppressWarnings({
        "PMD.NcssCount"
})
public class AllureSpock2 extends AbstractRunListener implements IGlobalExtension {

    private final ThreadLocal testResults = new InheritableThreadLocal() {
        @Override
        protected String initialValue() {
            return UUID.randomUUID().toString();
        }
    };

    private final AllureLifecycle lifecycle;

    private final TestPlan testPlan;

    @SuppressWarnings("unused")
    public AllureSpock2() {
        this(Allure.getLifecycle());
    }

    public AllureSpock2(final AllureLifecycle lifecycle) {
        this(lifecycle, new FileTestPlanSupplier().supply().orElse(null));
    }

    public AllureSpock2(final AllureLifecycle lifecycle, final TestPlan plan) {
        this.lifecycle = lifecycle;
        this.testPlan = plan;
    }

    @Override
    public void visitSpec(final SpecInfo spec) {
        spec.getAllFeatures().forEach(methodInfo -> methodInfo.setSkipped(this.isSkipped(methodInfo)));

        spec.addListener(this);

        final String specContainerUuid = UUID.randomUUID().toString();
        spec.addInterceptor(new AllureContainerInterceptor(specContainerUuid));

        spec.getAllFixtureMethods().forEach(methodInfo -> {
            if (methodInfo.getKind().isSpecScopedFixtureMethod()) {
                methodInfo.addInterceptor(new AllureSpecFixtureMethodInterceptor(specContainerUuid));
            }
            if (methodInfo.getKind().isFeatureScopedFixtureMethod()) {
                methodInfo.addInterceptor(new AllureFeatureFixtureMethodInterceptor());
            }
        });

        // add each feature to this container
        spec.getAllFeatures().stream()
                .map(FeatureInfo::getFeatureMethod)
                .filter(Objects::nonNull)
                .forEach(fm -> fm.addInterceptor(i -> {
                    getLifecycle().getCurrentTestCaseOrStep().ifPresent(uuid -> {
                        getLifecycle().updateTestContainer(
                                specContainerUuid,
                                c -> c.getChildren().add(uuid)
                        );
                    });
                    i.proceed();
                }));
    }

    @Override
    public void beforeIteration(final IterationInfo iteration) {
        final String uuid = testResults.get();

        final FeatureInfo feature = iteration.getFeature();
        final MethodInfo methodInfo = feature.getFeatureMethod();
        final Method method = methodInfo.getReflection();
        final Set




© 2015 - 2024 Weber Informatics LLC | Privacy Policy