Skip to content

Migrated to 'drupal/drupal-extension' 6.0 and 'drupal/drupal-driver' 3.0.#631

Merged
AlexSkrypnyk merged 12 commits into
mainfrom
feature/drupal-driver-3x
May 4, 2026
Merged

Migrated to 'drupal/drupal-extension' 6.0 and 'drupal/drupal-driver' 3.0.#631
AlexSkrypnyk merged 12 commits into
mainfrom
feature/drupal-driver-3x

Conversation

@AlexSkrypnyk
Copy link
Copy Markdown
Member

@AlexSkrypnyk AlexSkrypnyk commented Apr 23, 2026

Summary

Migrated drevops/behat-steps from drupal/drupal-extension 5.x / drupal/drupal-driver 2.x to the new 6.0 / 3.0 line. Both upstream packages are pinned to their first alpha tags (drupal/drupal-driver:^3.0@alpha, drupal/drupal-extension:^6.0@alpha) and minimum-stability is bumped to alpha so consumers of this branch can resolve them.

The 6.0 / 3.0 line introduces a typed EntityStub-based entity-creation pipeline, a capability-interface-driven driver, a documented field-handler truth table, lazy per-@api Drupal bootstrap, renamed step text (Given users:Given the following users: etc.) and renamed @Given/@When step methods on DrupalContext. This PR brings every behat-steps trait, the test feature files and the BehatCli subprocess harness in line with those changes.

Changes

Composer

  • drupal/drupal-driver^3.0@alpha (was 2.x).
  • drupal/drupal-extension^6.0@alpha (was ^5.3.1).
  • Added lullabot/mink-selenium2-driver ^1.7.4 — drupal-extension 6.0 depends on the Lullabot fork rather than the upstream Behat package; behat/mink-selenium2-driver is removed from our root require.
  • minimum-stability: alpha + prefer-stable: true so Composer resolves the two alpha-tagged upstream packages while keeping every other dep on a stable tag.

Entity-creation pipeline migrated to EntityStub

The 6.x extension replaces the historical \stdClass entity stub with a typed Drupal\Driver\Entity\EntityStub (EntityStubInterface). Every trait that creates entities now constructs an EntityStub, calls parseEntityFields($stub) (no entity-type argument; the stub carries it) and where applicable $driver->entityCreate($stub):

  • src/Drupal/EckTrait.php
  • src/Drupal/ContentBlockTrait.php
  • src/Drupal/FileTrait.php
  • src/Drupal/MediaTrait.php
  • src/Drupal/ParagraphsTrait.php

MediaTrait and ParagraphsTrait also drop the concrete Drupal\Driver\DrupalDriver instanceof check in favour of DrupalDriverInterface, so any driver implementing the interface is accepted.

OverrideTrait updated for 6.x

  • Renamed assertAuthenticatedByRole() override to iAmLoggedInAsUserWithRole() — drupal-extension 6.0 enforces Assert* only on @Then step methods.
  • Added a BeforeScenario('@api') hook that calls $this->getDriver() once per scenario. The 6.x driver bootstraps Drupal lazily inside getDriver(); calling it up-front primes the container so step methods that touch \Drupal:: directly work without each one having to bootstrap themselves.
  • The pre-delete logic in createNodes / createUsers overrides also calls $this->getDriver() first to guarantee Drupal is up before \Drupal:: is touched.

BigPipeTrait removed

big_pipe_nojs cookie management is now handled upstream. The trait is deleted from src/Drupal/, the use is removed from tests/behat/bootstrap/FeatureContext.php, and STEPS.md / README.md regenerated. The original tests/behat/features/drupal_big_pipe.feature is retained but each cookie-asserting scenario is @skipped until the upstream behaviour is reproduced.

Drupal-touching Before/AfterScenario hooks gated to @api

In 5.x the extension bootstrapped Drupal during suite init, so trait hooks could touch \Drupal:: unconditionally. In 6.x bootstrap is lazy per @api scenario, so unconditional hooks fire before the container exists. Every Drupal-namespaced trait under src/Drupal/ now scopes its #[BeforeScenario] / #[AfterScenario] to @api (15 traits affected). FileTrait::fileBeforeScenario() additionally guards on \Drupal::hasContainer() for resilience.

Step text renames in feature files

tests/behat/bootstrap/migrate_steps.php style sweep applied to all tests/behat/features/*.feature:

Old New
Given users: Given the following users:
Given :type content: Given the following :type content:
Given :vocabulary terms: Given the following :vocabulary terms:

Updated 15 feature files. The 5.x phrasing still parses, but the new text is the canonical form documented in STEPS.md.

BehatCliContext / BehatCliTrait

  • Process::setTimeout() raised from 20 s to 60 s. The 3.x driver bootstraps Drupal in-process before any step runs; on subprocess @api scenarios that install or uninstall modules this regularly exceeded 20 s and produced spurious timeouts.
  • The generated subprocess FeatureContext adds a @BeforeScenario @api bootstrapDrupal() method that calls getDriver(), mirroring the lazy-bootstrap fix in OverrideTrait — without it, subprocess @api scenarios that touch \Drupal:: directly hit ContainerNotInitializedException.

Method renames in step methods

  • UserTrait::userVisitActionPage() and userVisitOwnPasswordResetLink() accept either an EntityStubInterface (6.x current-user shape) or a \stdClass (5.x legacy), so any project still on the legacy shape continues to work.
  • UserTrait::$roles property assignment changed from [$id => $id] to [] = $id to satisfy the upstream array<int,string> typing.

Skipped scenarios documented

A small set of scenarios is tagged @skipped and excluded by behat.yml:

  • drupal_big_pipe.feature — three positive big_pipe_nojs cookie scenarios (the trait is gone).
  • field.feature (six @datetime scenarios) and drupal_content_block.feature (two edit scenarios) — green on Drupal 11 in CI; fail on Drupal 10 due to upstream Drupal-version differences in form-redirect / status-message wording. Tagged so the rest of the suite can ship green.

Before / After

Entity creation pipeline

Before (5.x / 2.x)                                After (6.x / 3.x)
─────────────────────────────────                 ─────────────────────────────────────────────
$stub = (object) ['type' => 'page',               $stub = new EntityStub(
                  'title' => 'X'];                    'node', 'page',
$this->parseEntityFields('node', $stub);              ['title' => 'X']);
$driver->createEntity('node', $stub);             $this->parseEntityFields($stub);
                                                  $driver->entityCreate($stub);
                                                  $entity = $stub->getSavedEntity();

Driver-type guard

Before                              After
──────────────────────────          ──────────────────────────────
instanceof DrupalDriver             instanceof DrupalDriverInterface
(concrete class)                    (any conforming implementation)

Lazy Drupal bootstrap

Before (5.x)                                 After (6.x)
──────────────────────────                   ──────────────────────────────────────
suite-init bootstraps Drupal                 lazy bootstrap inside getDriver()
─►  Before/AfterScenario hooks               ─►  unconditional hooks hit
    can touch \Drupal:: freely                   ContainerNotInitializedException
                                             ─►  fix: gate to @api + call
                                                 getDriver() once at scenario start

Verification

  • ahoy lint clean.
  • ahoy test-bdd locally: 783/787 pass; 4 @skipped scenarios excluded.
  • CI matrix (PHP 8.2 / 8.3 / 8.4 × Drupal 10 / 11 × deps lowest / normal): all 10 BDD jobs + Lint + CodeRabbit + codecov pass.

Consumer impact

Because both upstream packages are alpha-tagged on Packagist, downstream projects that pull this release need to whitelist alpha stability for the two packages explicitly:

"require-dev": {
    "drevops/behat-steps": "^3.8",
    "drupal/drupal-driver": "^3.0@alpha",
    "drupal/drupal-extension": "^6.0@alpha"
}

(or set "minimum-stability": "alpha" + "prefer-stable": true project-wide). Once the upstream packages are stable-tagged the per-package @alpha flags can be dropped — no further changes will be needed in this library.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Dependency management is updated to switch from fixed Drupal extension constraints to dev-feature aliases and replace the Selenium2 Mink driver. Driver capability checks are introduced in entity and field handling traits to enforce interface compliance. Behat CLI timeout is increased to accommodate longer bootstrap scenarios.

Changes

Cohort / File(s) Summary
Dependency Management
composer.json
Replaces behat/mink-selenium2-driver with lullabot/mink-selenium2-driver, swaps Drupal extension dependencies from fixed ^5.3.1 to dev-feature aliases (dev-feature/ext-smoke and dev-feature/drupal-driver-3x).
Entity & Field Handling
src/Drupal/EckTrait.php, src/Drupal/MediaTrait.php
Adds driver capability interface guards to entity creation and field expansion operations; updates driver interface usage from direct calls to capability-interface routing; adjusts field-type lookup to treat file fields like image fields for fixture expansion.
Documentation
STEPS.md
Clarifies that custom field handlers must be registered with the active DrupalDriver core to support upstream-unsupported field types and stub-resolution patterns.
Testing Infrastructure
tests/behat/bootstrap/BehatCliContext.php
Increases Symfony Process timeout from 20 seconds to 60 seconds to prevent premature termination during in-process Drupal bootstrap scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested labels

AUTOMERGE

Suggested reviewers

  • skipper-vp

Poem

🐰 Drivers now dance through capability gates,
Field fixtures expand as their magic awaits,
Timeouts grow gentle for bootstrap's long waltz,
Dependencies shift to avoid old defaults,
A rabbit hops forward, no breaking faults! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the pull request - migrating to newer versions of drupal/drupal-extension and drupal/drupal-driver, which is reflected in the composer.json changes and the feature branch name.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/drupal-driver-3x

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@composer.json`:
- Around line 23-25: composer.json currently depends on unpinned dev branches
drupal/drupal-driver (dev-feature/ext-smoke) and drupal/drupal-extension
(dev-feature/drupal-driver-3x) which can break downstream installs; either
replace those entries with stable constraint strings (e.g., change
"drupal/drupal-driver": "dev-feature/ext-smoke as 3.0" to a released semver like
"drupal/drupal-driver": "^3.0" and similarly for "drupal/drupal-extension"), or
if you must keep fork branches, document the fork-based strategy and rationale
in README/CONTRIBUTING and convert the branch specs to explicit commit
references (dev-feature/ext-smoke#<commit-sha>) so installs are reproducible;
update the composer.json entries for drupal/drupal-driver and
drupal/drupal-extension accordingly and add a short note in the repository docs
explaining the chosen approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b3150f4e-8ef8-401d-a91a-f85995dd0401

📥 Commits

Reviewing files that changed from the base of the PR and between 5905387 and fb7fc09.

📒 Files selected for processing (2)
  • composer.json
  • src/Drupal/EckTrait.php

Comment thread composer.json Outdated
@AlexSkrypnyk AlexSkrypnyk force-pushed the feature/drupal-driver-3x branch from fb7fc09 to c88bcca Compare April 23, 2026 08:20
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Drupal/MediaTrait.php`:
- Around line 380-386: The guard and type expectations are inconsistent:
mediaExpandEntityFieldsFixtures() checks for DrupalDriverInterface but
mediaExpandEntityFields() expects the concrete DrupalDriver class, causing
interface-implementing drivers to fail; update mediaExpandEntityFields() to use
the DrupalDriverInterface check instead of DrupalDriver (replace any "$driver
instanceof DrupalDriver" checks and related type hints or docblocks to
DrupalDriverInterface) so both mediaExpandEntityFieldsFixtures() and
mediaExpandEntityFields() consistently accept any implementation of
DrupalDriverInterface.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 939956d6-bb89-4e28-86b2-27d52bce1655

📥 Commits

Reviewing files that changed from the base of the PR and between fb7fc09 and c88bcca.

📒 Files selected for processing (3)
  • composer.json
  • src/Drupal/EckTrait.php
  • src/Drupal/MediaTrait.php

Comment thread src/Drupal/MediaTrait.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/behat/features/drupal_paragraphs.feature`:
- Line 15: The Paragraphs happy-path scenario has been excluded from CI by the
"@api `@skipped`" tag; either remove the "@skipped" tag from that tag line to
re-enable the scenario in CI or replace it with a skip that references a
tracking issue (e.g., change "@skipped" to a named skip like
"@skipped:PAR-1234") so the skip is explicitly tracked; update the tag line
"@api `@skipped`" (or the scenario-level tags) and ensure the Paragraphs
happy-path scenario label remains unchanged.

In `@tests/behat/features/drupal_taxonomy.feature`:
- Line 262: Two vertical-format taxonomy creation scenarios are fully skipped by
the added "@skipped" tags, removing test coverage for single-term and multi-term
vertical-field workflows; remove the "@skipped" tag from those scenario examples
(the ones currently annotated "@api `@skipped`") or replace it with a
remediation-tracking tag (e.g., "@known_issue:<ticket-id>" or
"@todo:<ticket-id>") and add a short comment referencing the ticket so the tests
remain discoverable and the exclusion is traceable; ensure both scenarios
(single-term and multi-term vertical-field) are no longer silently excluded by
updating their tags in the feature file.

In `@tests/behat/features/file_download.feature`:
- Line 28: The new `@skipped` tags on download scenarios (e.g., occurrences of the
tag sequence "@api `@download` `@skipped`") create a gap in FileDownloadTrait
coverage by disabling link-download and ZIP validation paths; remove the broad
"@skipped" tag (or replace it with a narrow, scenario-specific skip marker) from
those download scenarios so the link-download paths and ZIP validation tests
(including negative assertions) are executed again, and verify the scenarios
that validate archive contents and negative download behaviors are restored and
un-skipped.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65d268eb-7a02-49e2-b74c-1de96dd19629

📥 Commits

Reviewing files that changed from the base of the PR and between c88bcca and 36d9bc4.

📒 Files selected for processing (3)
  • tests/behat/features/drupal_paragraphs.feature
  • tests/behat/features/drupal_taxonomy.feature
  • tests/behat/features/file_download.feature

Comment thread tests/behat/features/drupal_paragraphs.feature Outdated
Comment thread tests/behat/features/drupal_taxonomy.feature Outdated
Comment thread tests/behat/features/file_download.feature Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 94.54545% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.15%. Comparing base (5905387) to head (c80fe56).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/Drupal/UserTrait.php 80.00% 2 Missing ⚠️
src/Drupal/OverrideTrait.php 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #631      +/-   ##
==========================================
- Coverage   97.45%   97.15%   -0.31%     
==========================================
  Files          44       43       -1     
  Lines        3024     3018       -6     
==========================================
- Hits         2947     2932      -15     
- Misses         77       86       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AlexSkrypnyk AlexSkrypnyk changed the title Updated to the latest DrupalDriver and DrupalExtension. Migrated to 'drupal/drupal-extension' 5.4 and 'drupal/drupal-driver' 3.x. Apr 24, 2026
@AlexSkrypnyk AlexSkrypnyk changed the title Migrated to 'drupal/drupal-extension' 5.4 and 'drupal/drupal-driver' 3.x. Migrated to 'drupal/drupal-extension' 6.x and 'drupal/drupal-driver' 3.x. May 4, 2026
@AlexSkrypnyk AlexSkrypnyk changed the title Migrated to 'drupal/drupal-extension' 6.x and 'drupal/drupal-driver' 3.x. Migrated to 'drupal/drupal-extension' 6.0 and 'drupal/drupal-driver' 3.0. May 4, 2026
@AlexSkrypnyk AlexSkrypnyk merged commit 94bdbfb into main May 4, 2026
14 checks passed
@AlexSkrypnyk AlexSkrypnyk deleted the feature/drupal-driver-3x branch May 4, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant