package com.codeborne.selenide.testng; import com.codeborne.selenide.logevents.ErrorsCollector; import com.codeborne.selenide.logevents.SelenideLogger; import org.testng.ITestResult; import org.testng.annotations.Listeners; import org.testng.annotations.Test; import org.testng.reporters.ExitCodeListener; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import static com.codeborne.selenide.logevents.ErrorsCollector.LISTENER_SOFT_ASSERT; import static java.util.Arrays.asList; /** * Annotate your test class with {@code @Listeners({ SoftAsserts.class})} */ public class SoftAsserts extends ExitCodeListener { @Override public void onTestStart(ITestResult result) { addSelenideErrorListener(result); } @Override public void onTestFailure(ITestResult result) { failIfErrors(result); } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult result) { failIfErrors(result); } @Override public void onTestSuccess(ITestResult result) { failIfErrors(result); } @Override public void onConfigurationFailure(ITestResult result) { failIfErrors(result); } void addSelenideErrorListener(ITestResult result) { if (shouldIntercept(result.getTestClass().getRealClass()) && shouldIntercept(result.getMethod().getConstructorOrMethod().getMethod())) { SelenideLogger.addListener(LISTENER_SOFT_ASSERT, new ErrorsCollector()); } } boolean shouldIntercept(Class testClass) { Listeners listenersAnnotation = getListenersAnnotation(testClass); return listenersAnnotation != null && asList(listenersAnnotation.value()).contains(SoftAsserts.class); } boolean shouldIntercept(Method testMethod) { if (testMethod == null) return false; Test annotation = testMethod.getAnnotation(Test.class); return annotation != null && asList(annotation.expectedExceptions()).isEmpty(); } Listeners getListenersAnnotation(Class testClass) { Annotation annotation = testClass.getAnnotation(Listeners.class); return annotation != null ? (Listeners) annotation : testClass.getSuperclass() != null ? getListenersAnnotation(testClass.getSuperclass()) : null; } private void failIfErrors(ITestResult result) { ErrorsCollector errorsCollector = SelenideLogger.removeListener(LISTENER_SOFT_ASSERT); if (errorsCollector != null) { try { errorsCollector.failIfErrors(result.getTestClass().getName() + '.' + result.getName()); } catch (AssertionError e) { result.setStatus(ITestResult.FAILURE); result.setThrowable(e); } } } }