Skip to content

v6.0.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 May 02:09
261f8e1

What's new since v6.0.0-rc2

  • Prepared v6 stable release: pinned 'drupal/drupal-driver' to stable v3 and tidied release docs. @AlexSkrypnyk (#859)

Full Changelog: v6.0.0-rc2...v6.0.0

@AlexSkrypnyk

Migration

For migration instructions, see UPGRADING.md.

Implemented across pre-stable v6

This combines the release notes from every pre-stable v6 release - v6.0.0-alpha1, v6.0.0-rc1, and v6.0.0-rc2. The complete set is what ships in v6.0.0 stable. Each section lists the items first introduced in that specific pre-release.

v6.0.0-alpha1

Version 6.0 enforces a consistent set of step-definition conventions across all bundled contexts. The conventions are documented in CONTRIBUTING.md and validated by scripts/docs.php; CI fails on any violation.

See UPGRADING.md for detailed migration instructions covering all breaking changes, and the table below for a summary of highlights and breaking changes.

Highlights

  • Updated 'drupal/drupal-driver' to 3.x and migrated to capability-based API. @AlexSkrypnyk (#803)
    The monolithic DriverInterface is replaced with capability interfaces (AuthenticationCapabilityInterface, MailCapabilityInterface, ConfigCapabilityInterface, ContentCapabilityInterface, CacheCapabilityInterface, CronCapabilityInterface, LanguageCapabilityInterface, RoleCapabilityInterface, UserCapabilityInterface) and every CRUD method is renamed to a verb-noun form. Migration: bump drupal/drupal-driver to ^3.0, rename driver calls (createNodenodeCreate, runCroncronRun, clearCachecacheClear, startCollectingMailmailStartCollecting, getMailmailGet, sendMailmailSend, etc.), and add capability-interface guards before invoking driver methods in subclasses.
  • [#469] Added typed random tokens with '[?name:type,args]' syntax and deprecated '<?name>' form. @AlexSkrypnyk (#844)
    RandomContext ships six built-in generators (string, name, machine_name, int, email, uuid) selectable via [?name:type,args], with subclasses able to register custom types by overriding a single method. Equivalent literals share a scenario-scoped cache key, so [?title], [?title:string], and [?title:string,10] all produce the same value within one scenario.
  • [#258] Added BigPipe NOJS cookie bypass to 'DrupalContext'. @AlexSkrypnyk (#821)
    Tagging a scenario with @bigpipe sets the big_pipe_nojs cookie on non-JS Mink drivers (BrowserKit, Goutte) so Drupal renders pages fully server-side instead of leaving placeholders that only the BigPipe JS would replace. This makes authenticated-user assertions like "I should see Log out" reliable on BigPipe-enabled sites without switching to a real browser.
  • [#732] Added 'login_field' configuration to submit a custom user property as the login value. @AlexSkrypnyk (#820)
    Sites that authenticate by email rather than username (via mail_login, email_registration, or similar contrib) can now set login_field: mail (or any other user property) under Drupal\DrupalExtension, and the auth manager submits that property value to the username field instead of the hardcoded name. The default remains name, so existing setups are unaffected.
  • [#766] Added modern entity-field parser with 'field_parser' configuration flag. @AlexSkrypnyk (#818)
    The new EntityFieldParser introduces double-quote escaping, named-column compound syntax (country:"BE", locality:"Brussel"), structured ParseException errors with file/line context, and aggregated multi-error reporting. Bare - is now treated as literal text in scalar mode, so entity reference titles like "My article - Part 2" no longer require escaping.
  • Added 'suppress_deprecations' configuration and 'BEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONS' environment variable. @AlexSkrypnyk (#836)
    Both the suppress_deprecations config key and the BEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONS env var silence the extension's [Deprecation] notices to STDERR, with the env var winning over config. This lets teams roll forward through migrations without their CI failing on deprecation noise from extension-detected legacy patterns.
  • [#647] Added 'BEHAT_DRUPALEXTENSION_DISABLE_CLEANUP' env var to skip scenario teardown. @AlexSkrypnyk (#845)
    Setting BEHAT_DRUPALEXTENSION_DISABLE_CLEANUP=1 (or true/yes/on) skips the AfterScenario teardown of entities, users, and roles, and intentionally leaves the last logged-in session open so a failing scenario's database state and browser session can be inspected directly. Intended for ad-hoc local debugging - leave it off in CI.
  • [#479] Added verbose diagnostic output to AJAX timeout exception. @AlexSkrypnyk (#838)
    iWaitForAjaxToFinish() now captures the current URL, jQuery.active count, animated-element count, and each active Drupal.ajax.instances entry (selector, event, URL) at the moment of timeout and embeds them in a structured multi-line error message. Replaces the previous single-line "Unable to complete AJAX request." message that gave no clue why the browser was busy.

Breaking changes

  • Updated 'drupal/drupal-driver' to 3.x and migrated to capability-based API. @AlexSkrypnyk (#803)
    The monolithic DriverInterface is replaced with capability interfaces (AuthenticationCapabilityInterface, MailCapabilityInterface, ConfigCapabilityInterface, ContentCapabilityInterface, CacheCapabilityInterface, CronCapabilityInterface, LanguageCapabilityInterface, RoleCapabilityInterface, UserCapabilityInterface) and every CRUD method is renamed to a verb-noun form. Migration: bump drupal/drupal-driver to ^3.0, rename driver calls (createNodenodeCreate, runCroncronRun, clearCachecacheClear, startCollectingMailmailStartCollecting, getMailmailGet, sendMailmailSend, etc.), and add capability-interface guards before invoking driver methods in subclasses.
  • [#469] Added typed random tokens with '[?name:type,args]' syntax and deprecated '<?name>' form. @AlexSkrypnyk (#844)
    The legacy <?name> random-token form still works in 6.0 but emits a [Deprecation] notice once per literal. Migration: replace <?name> with [?name] (equivalent default) or one of the typed forms ([?slug:machine_name], [?age:int,18,99], [?email:email], [?id:uuid]); the legacy form is scheduled for removal in 6.1.
  • Renamed 'assert' action steps and tightened validator. @AlexSkrypnyk (#837)
    Action methods that previously used assertXxx names are renamed to action-style names (e.g. assertCroniRunCron, assertAuthenticatedByRoleiAmLoggedInAsUserWithRole, assertDrushCommandiRunDrush), and three negative-message steps move from @Given to @Then with matching method renames. Migration: see the rename table in MIGRATION.md and search-and-replace overridden method names in your subclasses; step text is unchanged for most steps but the three re-classified steps now require @Then semantics.
  • [#824] Converted 'BatchContext' into 'BatchTrait' on 'DrupalContext'. @AlexSkrypnyk (#835)
    BatchContext is deleted; its iWaitForTheBatchJobToFinish and thereIsAnItemInTheSystemQueue steps are now provided by DrupalContext via BatchTrait. Migration: remove Drupal\DrupalExtension\Context\BatchContext from the contexts: list in your behat.yml - the steps are loaded automatically with DrupalContext.
  • Moved driver and mail manager classes under 'Drupal\DrupalExtension\Manager' namespace. @AlexSkrypnyk (#833)
    Drupal\DrupalDriverManagerDrupal\DrupalExtension\Manager\DriverManager (the Drupal prefix drops), Drupal\DrupalDriverManagerInterfaceDrupal\DrupalExtension\Manager\DriverManagerInterface, Drupal\DrupalMailManagerDrupal\DrupalExtension\Manager\DrupalMailManager, Drupal\DrupalMailManagerInterfaceDrupal\DrupalExtension\Manager\DrupalMailManagerInterface. Migration: update use statements and any FQCN references; the user and authentication managers retain their existing namespaces.
  • Moved 'ParametersAwareInterface' to root namespace alongside 'ParametersTrait'. @AlexSkrypnyk (#832)
    The interface moved from Drupal\DrupalExtension\Context\ParametersAwareInterface to Drupal\DrupalExtension\ParametersAwareInterface. Migration: update use statements to import from the root namespace; signatures (setParameters, getParameter) are unchanged.
  • [#825] Extracted Drupal AJAX handling into 'DrupalAjaxTrait'. @AlexSkrypnyk (#830)
    The three Drupal-specific AJAX methods (iWaitForAjaxToFinish, beforeJavascriptStep, afterJavascriptStep) move from MinkContext into DrupalAjaxTrait. MinkContext composes the trait so existing consumers see no behavior change, but downstream subclasses that overrode these methods inline must now override the trait methods or compose DrupalAjaxTrait directly.
  • Moved 'ajax_timeout' to 'Drupal\DrupalExtension' and renamed parameters interface. @AlexSkrypnyk (#829)
    ajax_timeout configuration moves from Drupal\MinkExtension to Drupal\DrupalExtension, and the parameters API drops its Drupal prefix: DrupalParametersAwareInterfaceParametersAwareInterface, DrupalParametersTraitParametersTrait, setDrupalParameterssetParameters, getDrupalParametergetParameter, $drupalParameters$parameters. Migration: relocate ajax_timeout in behat.yml and rename interface/trait/method/property references in subclasses.
  • [#822] Rebased MessageContext on RawMinkContext and moved message selectors to Drupal\MinkExtension. @AlexSkrypnyk (#827)
    MessageContext now extends RawMinkContext instead of RawDrupalContext, so it can be registered in any Mink suite without booting the Drupal driver; subclasses that depended on RawDrupalContext helpers must compose ParametersTrait themselves or change their base. The four message selectors (message_selector, error_message_selector, success_message_selector, warning_message_selector) move from Drupal\DrupalExtension.selectors: to Drupal\MinkExtension.selectors:; the legacy location still works in 6.0 with a one-shot deprecation notice and is removed in 6.1.
  • [#258] Added BigPipe NOJS cookie bypass to 'DrupalContext'. @AlexSkrypnyk (#821)
    This is additive (opt-in via @bigpipe tag) but ships as part of DrupalContext, so subclasses that override the existing BeforeScenario / BeforeStep hook methods without calling parent will silently disable the bypass. Migration: if you override these hooks, call parent:: or use BigPipeTrait explicitly so the cookie management still runs.
  • Replaced Sphinx documentation with Markdown-based docs in 'docs/'. @AlexSkrypnyk (#819)
    The Read the Docs / Sphinx tree under doc/ is removed and replaced with Markdown under docs/. Migration: update bookmarks and any internal links pointing at doc/*.rst to the new docs/*.md paths; the Read the Docs site is no longer maintained.
  • [#766] Added modern entity-field parser with 'field_parser' configuration flag. @AlexSkrypnyk (#818)
    The default field-value parser is now EntityFieldParser, which uses double-quote escaping and detects compound mode by key:"value" form rather than - separator spacing. Migration: set field_parser: legacy under Drupal\DrupalExtension in behat.yml to keep the 5.x behavior (emits a one-shot deprecation notice); the legacy parser is removed in 6.1. Cells containing - no longer require escaping under the modern parser.
  • Renamed 'classifier()' calls to 'getFieldClassifier()' to match drupal-driver API. @AlexSkrypnyk (#817)
    The drupal-driver CoreInterface::classifier() accessor was renamed to getFieldClassifier(). Migration: replace direct calls of $driver->getCore()->classifier() with $driver->getCore()->getFieldClassifier(); no backwards-compatibility shim is provided.
  • [#337] Replaced 'stdClass' entity stubs with typed 'EntityStub' from driver. @AlexSkrypnyk (#814)
    Hook scopes (BeforeNodeCreateScope, AfterNodeCreateScope, etc.) and step methods now expose EntityStubInterface instead of \stdClass, and EntityScope::getEntity() is renamed to getStub(). Migration: replace ad-hoc property reads with $stub->getValue('title') and writes with $stub->setValue(...); replace (object) [...] constructions with new EntityStub($entity_type, $bundle, $values); replace $saved->nid / $saved->tid with $stub->getId(); rename getEntity() calls to getStub().
  • [#806] Removed 'store' parameter from 'DrupalMailManager' and 'DrupalMailManagerInterface'. @AlexSkrypnyk (#812)
    getMail() and clearMail() no longer accept a $store argument because the v3 driver only exposes a single implicit collector. Migration: drop the $store argument from any direct calls and from any subclass overrides that implement DrupalMailManagerInterface; tracked counts in RawMailContext are now a scalar int rather than an array keyed by store.
  • [#752] Replaced generic exceptions with typed Mink exceptions across bundled contexts. @AlexSkrypnyk (#811)
    Roughly 30 \Exception throws across the bundled contexts are replaced with Behat\Mink\Exception\ElementNotFoundException (lookups), Behat\Mink\Exception\ExpectationException (assertion mismatches), or \RuntimeException (configuration errors). Migration: any tests or hooks that catch \Exception from these steps continue to work, but code that asserts on specific exception classes or messages must update to the typed classes; Mink exceptions append URL and page-snippet context via __toString().
  • Enforced step-definition conventions for v6 across all bundled contexts. @AlexSkrypnyk (#810)
    Roughly 50 @Then methods are renamed to <concern>Assert<action> form, around 29 step texts are updated to satisfy the new conventions (e.g. Given users:Given the following users:, Then drush output should contain XThen the drush output should contain X, Then I log outWhen I log out), and several methods are re-categorised from @Then to @When for side-effect steps. Migration: search-and-replace step text in your feature files using the table in MIGRATION.md; rename overridden method names in your subclasses.
  • Removed deprecated APIs in preparation for 6.0.0. @AlexSkrypnyk (#809)
    Subcontext auto-discovery (subcontexts.paths config, .behat.inc loading, DrupalSubContextInterface, DrupalSubContextBase), the annotation-based hook reader (Annotation\Reader), RawDrupalContext::loggedInWithRole(), and the AnnotatedDefinitionProposal shim are all removed. Migration: rewrite subcontexts as regular Behat contexts using PHP attributes; remove any subcontexts: block from behat.yml; replace loggedInWithRole() calls with the standard authenticated-user flow.
  • [#823] Rebased 'RandomContext' on bare Behat context interface. @AlexSkrypnyk (#834)
    RandomContext no longer extends RawDrupalContext; it implements Behat\Behat\Context\Context directly and instantiates a Random lazily. Migration: subclassers that relied on inherited Drupal/Mink helpers must compose those traits themselves or change their base class; documented in MIGRATION.md under "RandomContext base class".

All changes

  • [#356] Strengthened 'author' property test to assert author is applied. @AlexSkrypnyk (#847)
    The existing scenario for the author property in Given the following :type content: was rewritten as a direct test that creates an article with author = Joe User, visits /admin/content, and asserts Joe User appears in the article's author column. Previously the scenario only verified the syntax did not error.
  • [#647] Added 'BEHAT_DRUPALEXTENSION_DISABLE_CLEANUP' env var to skip scenario teardown. @AlexSkrypnyk (#845)
    Setting BEHAT_DRUPALEXTENSION_DISABLE_CLEANUP=1 (or true/yes/on) skips the AfterScenario teardown of entities, users, and roles, and intentionally leaves the last logged-in session open so a failing scenario's database state and browser session can be inspected directly. Intended for ad-hoc local debugging - leave it off in CI.
  • [#735] Added test coverage and docs for options in 'I run drush :command :arguments' step. @AlexSkrypnyk (#846)
    The existing I run drush :command :arguments step already supported flags because the arguments string is appended verbatim to the shell command, but this was undocumented. The docblock now shows a combined positional-argument-plus-flag example, and a new scenario exercises config:get "system.site uuid --format=string" end to end.
  • [#469] Added typed random tokens with '[?name:type,args]' syntax and deprecated '<?name>' form. @AlexSkrypnyk (#844)
    RandomContext ships six built-in generators (string, name, machine_name, int, email, uuid) selectable via [?name:type,args], with subclasses able to register custom types by overriding a single method. Equivalent literals share a scenario-scoped cache key, so [?title], [?title:string], and [?title:string,10] all produce the same value within one scenario.
  • [#733] Added test coverage and docs for configurable login and logout URLs. @AlexSkrypnyk (#843)
    Three new PHPUnit tests pin the visit() argument so a regression that hardcoded /user back into DrupalAuthenticationManager would now fail loudly, and the logout_confirm_url entry was added to the documented text: example so all three login/logout URL keys are visible together.
  • [#415] Added test coverage for URI-only link field values. @AlexSkrypnyk (#841)
    Five new Behat scenarios exercise URI-only link field values - bare URIs, comma-separated lists, the named uri: compound column, and a mixed scenario - covering the upstream LinkHandler fix in drupal-driver that wraps a bare string as ['uri' => $value].
  • Fixed chrome port and AJAX assertion after Pygmy and Lagoon stack migration. @AlexSkrypnyk (#840)
    The Selenium VNC port mapping was changed from a fixed 7900:7900 host binding to a Docker-assigned ephemeral port to avoid conflicts, and the AJAX timeout assertion in FeatureContext no longer hardcodes http://blackbox so it works against the new in-process PHP server (http://cli:8888). CONTRIBUTING.md now documents how to read the dynamic VNC URL from ahoy info.
  • [#730] Migrated local stack to Pygmy and Lagoon images. @AlexSkrypnyk (#839)
    The Wodby + Traefik local stack is replaced with Lagoon container images fronted by Pygmy, matching the layout used by drevops/behat-steps. The blackbox nginx container is dropped in favour of an in-process PHP server started by BlackboxServerContext inside the cli container, the drupal_https profile is removed, and provisioning steps move into a single scripts/provision.sh shared by ahoy and CI.
  • [#479] Added verbose diagnostic output to AJAX timeout exception. @AlexSkrypnyk (#838)
    iWaitForAjaxToFinish() now captures the current URL, jQuery.active count, animated-element count, and each active Drupal.ajax.instances entry (selector, event, URL) at the moment of timeout and embeds them in a structured multi-line error message. Replaces the previous single-line "Unable to complete AJAX request." message that gave no clue why the browser was busy.
  • Renamed 'assert' action steps and tightened validator. @AlexSkrypnyk (#837)
    Action methods that previously used assertXxx names are renamed to action-style names (e.g. assertCroniRunCron, assertAuthenticatedByRoleiAmLoggedInAsUserWithRole, assertDrushCommandiRunDrush), and three negative-message steps move from @Given to @Then with matching method renames. The validator now hard-fails when @Given/@When step text contains should or method names contain Assert.
  • Added 'suppress_deprecations' configuration and 'BEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONS' environment variable. @AlexSkrypnyk (#836)
    Both the suppress_deprecations config key and the BEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONS env var silence the extension's [Deprecation] notices to STDERR, with the env var winning over config. This lets teams roll forward through migrations without their CI failing on deprecation noise from extension-detected legacy patterns.
  • [#824] Converted 'BatchContext' into 'BatchTrait' on 'DrupalContext'. @AlexSkrypnyk (#835)
    BatchContext is deleted; its iWaitForTheBatchJobToFinish and thereIsAnItemInTheSystemQueue steps are now provided by DrupalContext via BatchTrait. Both steps depend on \Drupal:: calls, so hosting them on the API-driver-only DrupalContext keeps them behind a bootstrapped Drupal kernel and prevents silent failures under Blackbox or Drush drivers.
  • Moved driver and mail manager classes under 'Drupal\DrupalExtension\Manager' namespace. @AlexSkrypnyk (#833)
    Drupal\DrupalDriverManagerDrupal\DrupalExtension\Manager\DriverManager (the Drupal prefix drops because driver routing is generic infrastructure), and the mail manager and its interface move alongside the user/auth managers under the same namespace. The dead psr-0 autoload entry in composer.json is removed.
  • [#823] Rebased 'RandomContext' on bare Behat context interface. @AlexSkrypnyk (#834)
    RandomContext no longer extends RawDrupalContext; it implements Behat\Behat\Context\Context directly and instantiates a Random lazily, so the context can be registered in any Behat suite regardless of whether the Drupal extension is loaded. New PHPUnit tests cover the standalone shape and the token substitution contract.
  • Moved 'ParametersAwareInterface' to root namespace alongside 'ParametersTrait'. @AlexSkrypnyk (#832)
    The interface moved from Drupal\DrupalExtension\Context\ParametersAwareInterface to Drupal\DrupalExtension\ParametersAwareInterface so it sits next to its companion ParametersTrait and RegionTrait. setParameters / getParameter signatures are unchanged - only the FQN moves.
  • [#826] Documented 'ParametersTrait' and 'RegionTrait' as Mink-only consumption points. @AlexSkrypnyk (#831)
    The two traits work on any RawMinkContext consumer without requiring a Drupal driver bootstrap; the trait docblocks and a new "Mink-only contexts" section in docs/contexts.md make the pattern explicit. The bundled MinkContext, MarkupContext, and MessageContext already follow this pattern.
  • [#825] Extracted Drupal AJAX handling into 'DrupalAjaxTrait'. @AlexSkrypnyk (#830)
    The three Drupal-specific AJAX methods (iWaitForAjaxToFinish, beforeJavascriptStep, afterJavascriptStep) move from MinkContext into DrupalAjaxTrait; MinkContext composes the trait so existing consumers see no behavior change. The trait can now be reused in custom Mink-based contexts without inheriting from MinkContext.
  • Moved 'ajax_timeout' to 'Drupal\DrupalExtension' and renamed parameters interface. @AlexSkrypnyk (#829)
    ajax_timeout configuration moves from Drupal\MinkExtension to Drupal\DrupalExtension so all custom config lives under one extension, and the parameters API drops its Drupal prefix throughout: interface, trait, methods, and property name. The Drupal\MinkExtension extension now only registers the BrowserKit driver factory.
  • Moved 'ClassGenerator' out of 'Context/ContextClass/' into a top-level 'Generator/' namespace. @AlexSkrypnyk (#828)
    ClassGenerator (Behat's behat --init scaffolder for Drupal context classes) moves from Drupal\DrupalExtension\Context\ContextClass to Drupal\DrupalExtension\Generator, away from the actual step-defining contexts. The class is only instantiated by Behat's DI from inside the extension, so no downstream user code is affected. New PHPUnit tests cover both namespaced and rootless context-class generation.
  • [#822] Rebased MessageContext on RawMinkContext and moved message selectors to Drupal\MinkExtension. @AlexSkrypnyk (#827)
    MessageContext now extends RawMinkContext instead of RawDrupalContext, so blackbox-only suites no longer pay the cost of booting the Drupal driver stack. The four message selectors move from Drupal\DrupalExtension.selectors: to a new Drupal\MinkExtension.selectors: map; the legacy location keeps working in 6.0 with a one-shot deprecation notice.
  • [#258] Added BigPipe NOJS cookie bypass to 'DrupalContext'. @AlexSkrypnyk (#821)
    Tagging a scenario with @bigpipe sets the big_pipe_nojs cookie on non-JS Mink drivers so Drupal renders pages fully server-side instead of leaving placeholders that only the BigPipe JS would replace. The cookie is re-applied on every step because login redirects drop session cookies, and the trait is a no-op when the active driver supports JavaScript.
  • [#732] Added 'login_field' configuration to submit a custom user property as the login value. @AlexSkrypnyk (#820)
    Sites that authenticate by email rather than username (via mail_login, email_registration, or similar contrib) can now set login_field: mail (or any other user property) under Drupal\DrupalExtension, and the auth manager submits that property value to the username field instead of the hardcoded name. The default remains name, so existing setups are unaffected.
  • Replaced Sphinx documentation with Markdown-based docs in 'docs/'. @AlexSkrypnyk (#819)
    The Read the Docs / Sphinx tree under doc/ is removed and replaced with plain Markdown under docs/ covering installation, configuration, drivers, contexts, hooks, and writing tests. The Read the Docs badge and links in README.md are also dropped.
  • [#766] Added modern entity-field parser with 'field_parser' configuration flag. @AlexSkrypnyk (#818)
    The new EntityFieldParser introduces double-quote escaping, named-column compound syntax (country:"BE", locality:"Brussel"), structured ParseException errors with file/line context, and aggregated multi-error reporting. Bare - is now treated as literal text in scalar mode, so entity reference titles like "My article - Part 2" no longer require escaping.
  • [#766] Extracted field parsing into 'ParserInterface' and 'LegacyEntityFieldsParser'. @AlexSkrypnyk (#816)
    This is a pure refactor that lifts the cell-level field-value parsing out of RawDrupalContext::parseEntityFields() into a new LegacyEntityFieldsParser implementing a new ParserInterface. Behavior is unchanged in this PR; the contract is introduced first so the new modern parser (#818) can land against a stable interface.
  • Renamed 'classifier()' calls to 'getFieldClassifier()' to match drupal-driver API. @AlexSkrypnyk (#817)
    The drupal-driver CoreInterface::classifier() accessor was renamed to getFieldClassifier() upstream, and this PR updates the single call site in parseEntityFields() and the four mock setups in RawDrupalContextTest. No backwards-compatibility shim is provided.
  • Removed PHPSpec-based unit testing from the project. @AlexSkrypnyk (#815)
    The 22 PHPSpec spec files, the test-phpspec ahoy command, and the phpspec/phpspec Composer dev dependency are all removed; PHPUnit and Behat already cover the same ground. CI now runs one fewer parallel step.
  • [#337] Replaced 'stdClass' entity stubs with typed 'EntityStub' from driver. @AlexSkrypnyk (#814)
    Hook scopes and step methods now expose EntityStubInterface instead of \stdClass, four parallel creation paths collapse into a single entityCreate() entry point, and the four cleanNodes()/cleanTerms()/cleanUsers()/cleanLanguages() AfterScenario hooks become a single cleanEntities() reverse-walk. (object) [...] constructions become new EntityStub($type, $bundle, $values) and ad-hoc property access becomes getValue()/setValue().
  • [#806] Removed 'store' parameter from 'DrupalMailManager' and 'DrupalMailManagerInterface'. @AlexSkrypnyk (#812)
    getMail() and clearMail() no longer accept a $store argument because the v3 driver only exposes a single implicit collector. Tracked counts in RawMailContext collapse from array<string, int> to a plain int, and the interim assertDefaultStore() guard added in #803 is removed.
  • [#752] Replaced generic exceptions with typed Mink exceptions across bundled contexts. @AlexSkrypnyk (#811)
    Around 30 \Exception throws across the bundled contexts are replaced with Behat\Mink\Exception\ElementNotFoundException (lookups), Behat\Mink\Exception\ExpectationException (assertion mismatches), or \RuntimeException (configuration errors), with an "Exception conventions" section added to CONTRIBUTING.md. Mink exception classes append URL and page-snippet context via __toString(), so callers and test output get richer error messages without the throw site embedding the URL manually.
  • Enforced step-definition conventions for v6 across all bundled contexts. @AlexSkrypnyk (#810)
    Roughly 50 @Then methods are renamed to <concern>Assert<action> form, around 29 step texts are updated to satisfy the new conventions (Given users:Given the following users:, Then drush output should contain XThen the drush output should contain X, Then I log outWhen I log out), and side-effect steps move from @Then to @When. The scripts/docs.php validator now hard-fails CI on any violation instead of warning.
  • Removed deprecated APIs in preparation for 6.0.0. @AlexSkrypnyk (#809)
    Subcontext auto-discovery (subcontexts.paths config, .behat.inc loading, DrupalSubContextInterface, DrupalSubContextBase), the annotation-based hook reader (Annotation\Reader), RawDrupalContext::loggedInWithRole(), and the AnnotatedDefinitionProposal shim are all removed. Two remaining getSelectorsHandler()->xpathLiteral() calls in MinkContext are replaced with the modern Escaper::escapeLiteral().
  • Updated code to comply with PHPStan level 7. @AlexSkrypnyk (#808)
    PHPStan level is raised from 3 to 7, resolving 180 violations across 44 files. The fixes are all type annotations, return-type declarations, and narrowing casts that make existing semantics explicit to the analyser - no public API behaviour has changed.
  • Switched to Drupal coding standards. @AlexSkrypnyk (#807)
    The custom phpcs.xml ruleset is replaced with the full Drupal coding standards via drevops/phpcs-standard 0.7.x, aligning the project with drupal/drupal-driver. phpcbf auto-fixed roughly 1,270 violations across 82 files; the upgrade enforces snake_case local variables, Generic.PHP.RequireStrictTypes, and the previously excluded Drupal.Files.LineLength.TooLong and Drupal.Semantics.FunctionTriggerError rules.
  • Updated 'drupal/drupal-driver' to 3.x and migrated to capability-based API. @AlexSkrypnyk (#803)
    The monolithic DriverInterface is replaced with capability interfaces (AuthenticationCapabilityInterface, MailCapabilityInterface, ConfigCapabilityInterface, ContentCapabilityInterface, CacheCapabilityInterface, CronCapabilityInterface, LanguageCapabilityInterface, RoleCapabilityInterface, UserCapabilityInterface) and every CRUD method is renamed to a verb-noun form (createNodenodeCreate, runCroncronRun, clearCachecacheClear, startCollectingMailmailStartCollecting, etc.). Field classification moves to a dedicated FieldClassifierInterface exposed via Core::classifier().
  • Added 6.x note to readme. @AlexSkrypnyk (#805)
    A short 6.x note in README.md directs readers to the 5.x branch for the 5.x maintenance line and to main for the upcoming 6.0 release.

Full Changelog: v5.4.0...v6.0.0-alpha1

v6.0.0-rc1

  • Bumped 'drupal/drupal-driver' to 3.0.0-rc1 and tightened 'minimum-stability' to RC. @AlexSkrypnyk (#856)
  • [#854] Made 'Before/AfterEntityCreate' hooks fire for every entity create path. @AlexSkrypnyk (#855)
  • [#194] Added 'Given the following :type entities:' step for generic entity creation. @AlexSkrypnyk (#853)
  • Allowed bundle fields defined in hooks to be recognised. @AlexSkrypnyk (#852)

Full Changelog: v6.0.0-alpha1...v6.0.0-rc1

v6.0.0-rc2

Full Changelog: v6.0.0-rc1...v6.0.0-rc2