[#645] Fixed 'emailBeforeScenario' bootstrap ordering under 'drupal/drupal-extension' 6.x.#649
Conversation
…rupal-extension' 6.x.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
WalkthroughEmailTrait now self-boots the Drupal kernel by calling ChangesDrupal lazy bootstrap ordering fix for EmailTrait
🎯 2 (Simple) | ⏱️ ~12 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #649 +/- ##
=======================================
Coverage 96.54% 96.54%
=======================================
Files 44 44
Lines 3355 3356 +1
=======================================
+ Hits 3239 3240 +1
Misses 116 116 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Closes #645
Summary
EmailTrait::emailBeforeScenario()calls\Drupal::config()(viaemailEnableTestSystem()→emailGetMailSystemDefault()) before the Drupal kernel is guaranteed to be booted. Underdrupal/drupal-extension6.x the driver bootstraps lazily insidegetDriver(), and Behat does not guarantee ordering betweenBeforeScenariohooks on different traits. On any scenario tagged@api @email, if the email hook fires before another trait triggers the bootstrap, the first\Drupal::config()call throwsDrupal\Core\DependencyInjection\ContainerNotInitializedExceptionand the scenario fails before its first step.The fix is one line: call
$this->getDriver()at the top ofemailBeforeScenario()(after the existing tag guards) to prime the lazy bootstrap. This matches the pattern documented inOverrideTrait::overrideBootstrapDrupal()and removes the need for consumers to monkey-patch the hook in their ownFeatureContext.Changes
src/Drupal/EmailTrait.phpAdded
$this->getDriver();inemailBeforeScenario()after thebehat-steps-skipand@emailtag guards, with a code comment explaining the lazy-bootstrap reason. The call is idempotent — when the kernel is already booted by another trait's hook, it is a no-op.tests/behat/bootstrap/BehatCliTrait.phpThe generated
FeatureContext.phptemplate used by@trait:subprocess scenarios includes abootstrapDrupal()workaround method that primes the lazy driver. That workaround was silently masking the bug inEmailTrait(and the same bug latent in other traits whose hooks call\Drupal::). Extracted the workaround into a{{BOOTSTRAP_METHOD}}template token, gated on a newbool $bootstrap_workaround = TRUEparameter onbehatCliWriteFeatureContextFile(). Default isTRUEso every existing@trait:scenario behaves identically.Added a tag scan in
behatCliBeforeScenario(): scenarios tagged@behat-cli-no-bootstrapcause the generated context to omit the workaround, allowing a trait to be exercised in true isolation.tests/behat/features/drupal_email.featureAdded one regression scenario tagged
@trait:Drupal\EmailTrait @behat-cli-no-bootstrapthat runs an@api @emailinner subprocess and asserts it passes. Before the fix the scenario fails with\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container. (Drupal\Core\DependencyInjection\ContainerNotInitializedException)reported on theFeatureContext::emailBeforeScenario()hook. After the fix the scenario passes.Before / After
Summary
This PR fixes a race condition in
EmailTrait::emailBeforeScenario()under drupal/drupal-extension 6.x, where the method could call\Drupal::config()before the Drupal kernel was guaranteed to be booted. The fix ensures the lazy-loading 6.x driver is primed by calling$this->getDriver()at the start of the hook (after existing tag guards), making the trait self-sufficient when used in isolation.Changes
src/Drupal/EmailTrait.php
$this->getDriver()call inemailBeforeScenario()(line 66) to force Drupal bootstrap before\Drupal::config()is accessedtests/behat/bootstrap/BehatCliTrait.php
behatCliBeforeScenario()to detect the@behat-cli-no-bootstraptag and pass a$bootstrap_workaroundboolean flagbehatCliWriteFeatureContextFile()signature: addedbool $bootstrap_workaround = TRUEparameter$bootstrap_workaroundis enabled (default), the generated FeatureContext template includes abootstrapDrupal()method annotated with#[BeforeScenario@api]that calls$this->getDriver()@behat-cli-no-bootstraptag), the workaround is omitted to test traits in isolation{{BOOTSTRAP_METHOD}}token replacement in the templatetests/behat/features/drupal_email.feature
@trait:Drupal\EmailTraitand@behat-cli-no-bootstrap@api@email`` inner subprocessAcceptance Criteria Met
✓ EmailTrait::emailBeforeScenario() calls $this->getDriver() after tag guards
✓
@api@emailscenarios run standalone without depending on other traits for bootstrap✓ getDriver() call is idempotent
✓ Regression test exercises the trait in isolation
✓ Generated FeatureContext template supports bootstrap workaround omission via
@behat-cli-no-bootstraptagCode Quality