package ru.yandex.qatools.allure; import ru.yandex.qatools.allure.config.AllureConfig; import ru.yandex.qatools.allure.config.AllureModelUtils; import ru.yandex.qatools.allure.events.ClearStepStorageEvent; import ru.yandex.qatools.allure.events.ClearTestStorageEvent; import ru.yandex.qatools.allure.events.RemoveAttachmentsEvent; import ru.yandex.qatools.allure.events.StepEvent; import ru.yandex.qatools.allure.events.StepFinishedEvent; import ru.yandex.qatools.allure.events.StepStartedEvent; import ru.yandex.qatools.allure.events.TestCaseEvent; import ru.yandex.qatools.allure.events.TestCaseFinishedEvent; import ru.yandex.qatools.allure.events.TestCaseStartedEvent; import ru.yandex.qatools.allure.events.TestSuiteEvent; import ru.yandex.qatools.allure.events.TestSuiteFinishedEvent; import ru.yandex.qatools.allure.experimental.LifecycleListener; import ru.yandex.qatools.allure.experimental.ListenersNotifier; import ru.yandex.qatools.allure.model.Status; import ru.yandex.qatools.allure.model.Step; import ru.yandex.qatools.allure.model.TestCaseResult; import ru.yandex.qatools.allure.model.TestSuiteResult; import ru.yandex.qatools.allure.storages.StepStorage; import ru.yandex.qatools.allure.storages.TestCaseStorage; import ru.yandex.qatools.allure.storages.TestSuiteStorage; import ru.yandex.qatools.allure.utils.AllureShutdownHook; import static ru.yandex.qatools.allure.utils.AllureResultsUtils.writeTestSuiteResult; /** * Allure Java API. Use this class to access to Allure lifecycle * * @author Dmitry Baev charlie@yandex-team.ru * Date: 11.11.13 */ public class Allure { public static final Allure LIFECYCLE = new Allure(); private static final Object TEST_SUITE_ADD_CHILD_LOCK = new Object(); private final StepStorage stepStorage = new StepStorage(); private final TestCaseStorage testCaseStorage = new TestCaseStorage(); private final TestSuiteStorage testSuiteStorage = new TestSuiteStorage(); private final ListenersNotifier notifier = new ListenersNotifier(); /** * Package private. Use Allure.LIFECYCLE singleton */ Allure() { Runtime.getRuntime().addShutdownHook(new Thread( new AllureShutdownHook(testSuiteStorage.getStartedSuites()) )); } /** * Process StepStartedEvent. New step will be created and added to * stepStorage. * * @param event to process */ public void fire(StepStartedEvent event) { Step step = new Step(); event.process(step); stepStorage.put(step); notifier.fire(event); } /** * Process any StepEvent. You can change last added to stepStorage * step using this method. * * @param event to process */ public void fire(StepEvent event) { Step step = stepStorage.getLast(); event.process(step); notifier.fire(event); } /** * Process StepFinishedEvent. Change last added to stepStorage step * and add it as child of previous step. * * @param event to process */ public void fire(StepFinishedEvent event) { Step step = stepStorage.adopt(); event.process(step); notifier.fire(event); } /** * Process TestCaseStartedEvent. New testCase will be created and added * to suite as child. * * @param event to process */ public void fire(TestCaseStartedEvent event) { //init root step in parent thread if needed stepStorage.get(); TestCaseResult testCase = testCaseStorage.get(); event.process(testCase); synchronized (TEST_SUITE_ADD_CHILD_LOCK) { testSuiteStorage.get(event.getSuiteUid()).getTestCases().add(testCase); } notifier.fire(event); } /** * Process TestCaseEvent. You can change current testCase context * using this method. * * @param event to process */ public void fire(TestCaseEvent event) { TestCaseResult testCase = testCaseStorage.get(); event.process(testCase); notifier.fire(event); } /** * Process TestCaseFinishedEvent. Add steps and attachments from * top step from stepStorage to current testCase, then remove testCase * and step from stores. Also remove attachments matches removeAttachments * config. * * @param event to process */ public void fire(TestCaseFinishedEvent event) { TestCaseResult testCase = testCaseStorage.get(); event.process(testCase); Step root = stepStorage.pollLast(); if (Status.PASSED.equals(testCase.getStatus())) { new RemoveAttachmentsEvent(AllureConfig.newInstance().getRemoveAttachments()).process(root); } testCase.getSteps().addAll(root.getSteps()); testCase.getAttachments().addAll(root.getAttachments()); stepStorage.remove(); testCaseStorage.remove(); notifier.fire(event); } /** * Process TestSuiteEvent. You can use this method to change current * testSuite context. Using event.getUid() to access testSuite. * * @param event to process */ public void fire(TestSuiteEvent event) { TestSuiteResult testSuite = testSuiteStorage.get(event.getUid()); event.process(testSuite); notifier.fire(event); } /** * Process TestSuiteFinishedEvent. Using event.getUid() to access testSuite. * Then remove this suite from storage and marshal testSuite to xml using * AllureResultsUtils.writeTestSuiteResult() * * @param event to process */ public void fire(TestSuiteFinishedEvent event) { String suiteUid = event.getUid(); TestSuiteResult testSuite = testSuiteStorage.remove(suiteUid); if (testSuite == null) { return; } event.process(testSuite); testSuite.setVersion(getVersion()); testSuite.getLabels().add(AllureModelUtils.createProgrammingLanguageLabel()); writeTestSuiteResult(testSuite); notifier.fire(event); } /** * This method just clear current step context. * * @param event will be ignored */ @SuppressWarnings("unused") public void fire(ClearStepStorageEvent event) { stepStorage.remove(); notifier.fire(event); } /** * This method just clear current testCase context. * * @param event will be ignored */ @SuppressWarnings("unused") public void fire(ClearTestStorageEvent event) { testCaseStorage.remove(); notifier.fire(event); } /** * Experimental. Can be removed in next releases. * <p/> * Add specified listener to notifier. * * @param listener to add * @see ru.yandex.qatools.allure.experimental.LifecycleListener * @since 1.4.0 */ public void addListener(LifecycleListener listener) { notifier.addListener(listener); } /** * Package private. For tests only. * * @return stepStorage */ StepStorage getStepStorage() { return stepStorage; } /** * Package private. For tests only. * * @return testCaseStorage */ TestCaseStorage getTestCaseStorage() { return testCaseStorage; } /** * Package private. For tests only. * * @return testSuiteStorage */ TestSuiteStorage getTestSuiteStorage() { return testSuiteStorage; } /** * Use this method to get Allure version in runtime. Supported since * version 1.3.6 * * @return current Allure version */ public String getVersion() { return AllureConfig.newInstance().getVersion(); } }