diff --git a/src/Drupal/EmailTrait.php b/src/Drupal/EmailTrait.php index 6056b423..f0eab20c 100644 --- a/src/Drupal/EmailTrait.php +++ b/src/Drupal/EmailTrait.php @@ -61,6 +61,10 @@ public function emailBeforeScenario(BeforeScenarioScope $scope): void { return; } + // Force the lazy 6.x driver to boot Drupal so '\Drupal::config()' below is + // safe regardless of hook ordering between traits. + $this->getDriver(); + if ($scope->getScenario()->hasTag('debug')) { $this->emailDebug = TRUE; } diff --git a/tests/behat/bootstrap/BehatCliTrait.php b/tests/behat/bootstrap/BehatCliTrait.php index 51717f3d..5508b08f 100644 --- a/tests/behat/bootstrap/BehatCliTrait.php +++ b/tests/behat/bootstrap/BehatCliTrait.php @@ -49,7 +49,14 @@ public function behatCliBeforeScenario(BeforeScenarioScope $scope): void { return; } - $this->behatCliWriteFeatureContextFile($traits); + // The generated 'FeatureContext.php' normally includes a 'bootstrapDrupal' + // workaround that primes the lazy 6.x driver before any trait hook runs. + // Scenarios tagged '@behat-cli-no-bootstrap' opt out of that workaround so + // a trait under test can be exercised in true isolation - useful for + // proving a trait bootstraps Drupal itself when its hooks call '\Drupal::'. + $bootstrap_workaround = !$scope->getScenario()->hasTag('behat-cli-no-bootstrap'); + + $this->behatCliWriteFeatureContextFile($traits, $bootstrap_workaround); } #[BeforeStep] @@ -71,14 +78,21 @@ public function behatCliBeforeStep(): void { * * @param array $traits * Optional array of trait classes. + * @param bool $bootstrap_workaround + * When TRUE (default), the generated context includes a 'bootstrapDrupal' + * '@BeforeScenario @api' hook that primes the lazy 6.x driver. Pass FALSE + * to omit that hook so a trait under test can be exercised in true + * isolation - useful for proving a trait bootstraps Drupal itself when + * its hooks call '\Drupal::' before any step runs. * * @return string * Path to written file. */ - public function behatCliWriteFeatureContextFile(array $traits = []): string { + public function behatCliWriteFeatureContextFile(array $traits = [], bool $bootstrap_workaround = TRUE): string { $tokens = [ '{{USE_DECLARATION}}' => '', '{{USE_IN_CLASS}}' => '', + '{{BOOTSTRAP_METHOD}}' => '', ]; foreach ($traits as $trait) { // Check if trait contains slash to determine if it's in a subdirectory. @@ -138,16 +152,8 @@ public function behatCliWriteFeatureContextFile(array $traits = []): string { $tokens['{{USE_IN_CLASS}}'] .= sprintf('use %s;' . PHP_EOL, $trait_name); } - $content = <<<'EOL' -getDriver(); } +EOL; + } + + $content = <<<'EOL' +