From 404195b585a2bd45c8f79737a5f3683765125947 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Thu, 11 Apr 2024 10:32:39 +1200 Subject: [PATCH] NEW Add RetryScenarioTester --- src/Extension.php | 13 +++++++++ src/Utility/RetryScenarioTester.php | 42 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/Utility/RetryScenarioTester.php diff --git a/src/Extension.php b/src/Extension.php index e2283e57..b5911c6b 100644 --- a/src/Extension.php +++ b/src/Extension.php @@ -19,6 +19,8 @@ use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; +use Behat\Behat\Tester\ServiceContainer\TesterExtension; +use SilverStripe\BehatExtension\Utility\RetryScenarioTester; /* * This file is part of the SilverStripe\BehatExtension @@ -100,6 +102,17 @@ public function load(ContainerBuilder $container, array $config) $container->setParameter('silverstripe_extension.region_map', $config['region_map']); } $container->setParameter('silverstripe_extension.bootstrap_file', $config['bootstrap_file']); + + // When running in CI, behat scenarios will occasionally sporadically fail + // decorate the scenario tester with our own class so we can retry it once if it fails + $isCI = $config['is_ci'] ?? false; + if ($isCI) { + $definition = new Definition(RetryScenarioTester::class, [ + new Reference(TesterExtension::SCENARIO_TESTER_ID), + ]); + $definition->addTag(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG); + $container->setDefinition(TesterExtension::SCENARIO_TESTER_WRAPPER_TAG . '.silverstripe', $definition); + } } /** diff --git a/src/Utility/RetryScenarioTester.php b/src/Utility/RetryScenarioTester.php new file mode 100644 index 00000000..3ab5e7ba --- /dev/null +++ b/src/Utility/RetryScenarioTester.php @@ -0,0 +1,42 @@ +decoratedTester = $decoratedTester; + } + + public function setUp(Environment $env, FeatureNode $feature, ScenarioInterface $scenario, $skip) + { + return $this->decoratedTester->setUp($env, $feature, $scenario, $skip); + } + + public function test(Environment $env, FeatureNode $feature, ScenarioInterface $scenario, $skip) + { + $result = $this->decoratedTester->test($env, $feature, $scenario, $skip); + if (!$skip && !$result->isPassed()) { + // Run the scenario again + $result = $this->decoratedTester->test($env, $feature, $scenario, $skip); + } + return $result; + } + + public function tearDown(Environment $env, FeatureNode $feature, ScenarioInterface $scenario, $skip, TestResult $result) + { + return $this->decoratedTester->tearDown($env, $feature, $scenario, $skip, $result); + } +}