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
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 monolithicDriverInterfaceis 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: bumpdrupal/drupal-driverto^3.0, rename driver calls (createNode→nodeCreate,runCron→cronRun,clearCache→cacheClear,startCollectingMail→mailStartCollecting,getMail→mailGet,sendMail→mailSend, 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)
RandomContextships 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@bigpipesets thebig_pipe_nojscookie 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 (viamail_login,email_registration, or similar contrib) can now setlogin_field: mail(or any other user property) underDrupal\DrupalExtension, and the auth manager submits that property value to the username field instead of the hardcodedname. The default remainsname, so existing setups are unaffected. - [#766] Added modern entity-field parser with 'field_parser' configuration flag. @AlexSkrypnyk (#818)
The newEntityFieldParserintroduces double-quote escaping, named-column compound syntax (country:"BE", locality:"Brussel"), structuredParseExceptionerrors 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 thesuppress_deprecationsconfig key and theBEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONSenv 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)
SettingBEHAT_DRUPALEXTENSION_DISABLE_CLEANUP=1(ortrue/yes/on) skips theAfterScenarioteardown 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.activecount, animated-element count, and each activeDrupal.ajax.instancesentry (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 monolithicDriverInterfaceis 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: bumpdrupal/drupal-driverto^3.0, rename driver calls (createNode→nodeCreate,runCron→cronRun,clearCache→cacheClear,startCollectingMail→mailStartCollecting,getMail→mailGet,sendMail→mailSend, 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 usedassertXxxnames are renamed to action-style names (e.g.assertCron→iRunCron,assertAuthenticatedByRole→iAmLoggedInAsUserWithRole,assertDrushCommand→iRunDrush), and three negative-message steps move from@Givento@Thenwith matching method renames. Migration: see the rename table inMIGRATION.mdand search-and-replace overridden method names in your subclasses; step text is unchanged for most steps but the three re-classified steps now require@Thensemantics. - [#824] Converted 'BatchContext' into 'BatchTrait' on 'DrupalContext'. @AlexSkrypnyk (#835)
BatchContextis deleted; itsiWaitForTheBatchJobToFinishandthereIsAnItemInTheSystemQueuesteps are now provided byDrupalContextviaBatchTrait. Migration: removeDrupal\DrupalExtension\Context\BatchContextfrom thecontexts:list in yourbehat.yml- the steps are loaded automatically withDrupalContext. - Moved driver and mail manager classes under 'Drupal\DrupalExtension\Manager' namespace. @AlexSkrypnyk (#833)
Drupal\DrupalDriverManager→Drupal\DrupalExtension\Manager\DriverManager(theDrupalprefix drops),Drupal\DrupalDriverManagerInterface→Drupal\DrupalExtension\Manager\DriverManagerInterface,Drupal\DrupalMailManager→Drupal\DrupalExtension\Manager\DrupalMailManager,Drupal\DrupalMailManagerInterface→Drupal\DrupalExtension\Manager\DrupalMailManagerInterface. Migration: updateusestatements 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 fromDrupal\DrupalExtension\Context\ParametersAwareInterfacetoDrupal\DrupalExtension\ParametersAwareInterface. Migration: updateusestatements 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 fromMinkContextintoDrupalAjaxTrait.MinkContextcomposes the trait so existing consumers see no behavior change, but downstream subclasses that overrode these methods inline must now override the trait methods or composeDrupalAjaxTraitdirectly. - Moved 'ajax_timeout' to 'Drupal\DrupalExtension' and renamed parameters interface. @AlexSkrypnyk (#829)
ajax_timeoutconfiguration moves fromDrupal\MinkExtensiontoDrupal\DrupalExtension, and the parameters API drops itsDrupalprefix:DrupalParametersAwareInterface→ParametersAwareInterface,DrupalParametersTrait→ParametersTrait,setDrupalParameters→setParameters,getDrupalParameter→getParameter,$drupalParameters→$parameters. Migration: relocateajax_timeoutinbehat.ymland rename interface/trait/method/property references in subclasses. - [#822] Rebased MessageContext on RawMinkContext and moved message selectors to Drupal\MinkExtension. @AlexSkrypnyk (#827)
MessageContextnow extendsRawMinkContextinstead ofRawDrupalContext, so it can be registered in any Mink suite without booting the Drupal driver; subclasses that depended onRawDrupalContexthelpers must composeParametersTraitthemselves or change their base. The four message selectors (message_selector,error_message_selector,success_message_selector,warning_message_selector) move fromDrupal\DrupalExtension.selectors:toDrupal\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@bigpipetag) but ships as part ofDrupalContext, so subclasses that override the existingBeforeScenario/BeforeStephook methods without calling parent will silently disable the bypass. Migration: if you override these hooks, callparent::or useBigPipeTraitexplicitly so the cookie management still runs. - Replaced Sphinx documentation with Markdown-based docs in 'docs/'. @AlexSkrypnyk (#819)
The Read the Docs / Sphinx tree underdoc/is removed and replaced with Markdown underdocs/. Migration: update bookmarks and any internal links pointing atdoc/*.rstto the newdocs/*.mdpaths; 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 nowEntityFieldParser, which uses double-quote escaping and detects compound mode bykey:"value"form rather than-separator spacing. Migration: setfield_parser: legacyunderDrupal\DrupalExtensioninbehat.ymlto 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-driverCoreInterface::classifier()accessor was renamed togetFieldClassifier(). 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 exposeEntityStubInterfaceinstead of\stdClass, andEntityScope::getEntity()is renamed togetStub(). Migration: replace ad-hoc property reads with$stub->getValue('title')and writes with$stub->setValue(...); replace(object) [...]constructions withnew EntityStub($entity_type, $bundle, $values); replace$saved->nid/$saved->tidwith$stub->getId(); renamegetEntity()calls togetStub(). - [#806] Removed 'store' parameter from 'DrupalMailManager' and 'DrupalMailManagerInterface'. @AlexSkrypnyk (#812)
getMail()andclearMail()no longer accept a$storeargument because the v3 driver only exposes a single implicit collector. Migration: drop the$storeargument from any direct calls and from any subclass overrides that implementDrupalMailManagerInterface; tracked counts inRawMailContextare now a scalarintrather than an array keyed by store. - [#752] Replaced generic exceptions with typed Mink exceptions across bundled contexts. @AlexSkrypnyk (#811)
Roughly 30\Exceptionthrows across the bundled contexts are replaced withBehat\Mink\Exception\ElementNotFoundException(lookups),Behat\Mink\Exception\ExpectationException(assertion mismatches), or\RuntimeException(configuration errors). Migration: any tests or hooks that catch\Exceptionfrom 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@Thenmethods 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 X→Then the drush output should contain X,Then I log out→When I log out), and several methods are re-categorised from@Thento@Whenfor side-effect steps. Migration: search-and-replace step text in your feature files using the table inMIGRATION.md; rename overridden method names in your subclasses. - Removed deprecated APIs in preparation for 6.0.0. @AlexSkrypnyk (#809)
Subcontext auto-discovery (subcontexts.pathsconfig,.behat.incloading,DrupalSubContextInterface,DrupalSubContextBase), the annotation-based hook reader (Annotation\Reader),RawDrupalContext::loggedInWithRole(), and theAnnotatedDefinitionProposalshim are all removed. Migration: rewrite subcontexts as regular Behat contexts using PHP attributes; remove anysubcontexts:block frombehat.yml; replaceloggedInWithRole()calls with the standard authenticated-user flow. - [#823] Rebased 'RandomContext' on bare Behat context interface. @AlexSkrypnyk (#834)
RandomContextno longer extendsRawDrupalContext; it implementsBehat\Behat\Context\Contextdirectly and instantiates aRandomlazily. Migration: subclassers that relied on inherited Drupal/Mink helpers must compose those traits themselves or change their base class; documented inMIGRATION.mdunder "RandomContext base class".
All changes
- [#356] Strengthened 'author' property test to assert author is applied. @AlexSkrypnyk (#847)
The existing scenario for theauthorproperty inGiven the following :type content:was rewritten as a direct test that creates an article withauthor = Joe User, visits/admin/content, and assertsJoe Userappears 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)
SettingBEHAT_DRUPALEXTENSION_DISABLE_CLEANUP=1(ortrue/yes/on) skips theAfterScenarioteardown 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 existingI run drush :command :argumentsstep 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 exercisesconfig: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)
RandomContextships 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 thevisit()argument so a regression that hardcoded/userback intoDrupalAuthenticationManagerwould now fail loudly, and thelogout_confirm_urlentry was added to the documentedtext: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 nameduri:compound column, and a mixed scenario - covering the upstreamLinkHandlerfix 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 fixed7900:7900host binding to a Docker-assigned ephemeral port to avoid conflicts, and the AJAX timeout assertion inFeatureContextno longer hardcodeshttp://blackboxso it works against the new in-process PHP server (http://cli:8888).CONTRIBUTING.mdnow documents how to read the dynamic VNC URL fromahoy 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 bydrevops/behat-steps. The blackbox nginx container is dropped in favour of an in-process PHP server started byBlackboxServerContextinside theclicontainer, thedrupal_httpsprofile is removed, and provisioning steps move into a singlescripts/provision.shshared byahoyand CI. - [#479] Added verbose diagnostic output to AJAX timeout exception. @AlexSkrypnyk (#838)
iWaitForAjaxToFinish()now captures the current URL,jQuery.activecount, animated-element count, and each activeDrupal.ajax.instancesentry (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 usedassertXxxnames are renamed to action-style names (e.g.assertCron→iRunCron,assertAuthenticatedByRole→iAmLoggedInAsUserWithRole,assertDrushCommand→iRunDrush), and three negative-message steps move from@Givento@Thenwith matching method renames. The validator now hard-fails when@Given/@Whenstep text containsshouldor method names containAssert. - Added 'suppress_deprecations' configuration and 'BEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONS' environment variable. @AlexSkrypnyk (#836)
Both thesuppress_deprecationsconfig key and theBEHAT_DRUPALEXTENSION_SUPPRESS_DEPRECATIONSenv 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)
BatchContextis deleted; itsiWaitForTheBatchJobToFinishandthereIsAnItemInTheSystemQueuesteps are now provided byDrupalContextviaBatchTrait. Both steps depend on\Drupal::calls, so hosting them on the API-driver-onlyDrupalContextkeeps 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\DrupalDriverManager→Drupal\DrupalExtension\Manager\DriverManager(theDrupalprefix 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 deadpsr-0autoload entry incomposer.jsonis removed. - [#823] Rebased 'RandomContext' on bare Behat context interface. @AlexSkrypnyk (#834)
RandomContextno longer extendsRawDrupalContext; it implementsBehat\Behat\Context\Contextdirectly and instantiates aRandomlazily, 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 fromDrupal\DrupalExtension\Context\ParametersAwareInterfacetoDrupal\DrupalExtension\ParametersAwareInterfaceso it sits next to its companionParametersTraitandRegionTrait.setParameters/getParametersignatures are unchanged - only the FQN moves. - [#826] Documented 'ParametersTrait' and 'RegionTrait' as Mink-only consumption points. @AlexSkrypnyk (#831)
The two traits work on anyRawMinkContextconsumer without requiring a Drupal driver bootstrap; the trait docblocks and a new "Mink-only contexts" section indocs/contexts.mdmake the pattern explicit. The bundledMinkContext,MarkupContext, andMessageContextalready follow this pattern. - [#825] Extracted Drupal AJAX handling into 'DrupalAjaxTrait'. @AlexSkrypnyk (#830)
The three Drupal-specific AJAX methods (iWaitForAjaxToFinish,beforeJavascriptStep,afterJavascriptStep) move fromMinkContextintoDrupalAjaxTrait;MinkContextcomposes the trait so existing consumers see no behavior change. The trait can now be reused in custom Mink-based contexts without inheriting fromMinkContext. - Moved 'ajax_timeout' to 'Drupal\DrupalExtension' and renamed parameters interface. @AlexSkrypnyk (#829)
ajax_timeoutconfiguration moves fromDrupal\MinkExtensiontoDrupal\DrupalExtensionso all custom config lives under one extension, and the parameters API drops itsDrupalprefix throughout: interface, trait, methods, and property name. TheDrupal\MinkExtensionextension now only registers the BrowserKit driver factory. - Moved 'ClassGenerator' out of 'Context/ContextClass/' into a top-level 'Generator/' namespace. @AlexSkrypnyk (#828)
ClassGenerator(Behat'sbehat --initscaffolder for Drupal context classes) moves fromDrupal\DrupalExtension\Context\ContextClasstoDrupal\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)
MessageContextnow extendsRawMinkContextinstead ofRawDrupalContext, so blackbox-only suites no longer pay the cost of booting the Drupal driver stack. The four message selectors move fromDrupal\DrupalExtension.selectors:to a newDrupal\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@bigpipesets thebig_pipe_nojscookie 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 (viamail_login,email_registration, or similar contrib) can now setlogin_field: mail(or any other user property) underDrupal\DrupalExtension, and the auth manager submits that property value to the username field instead of the hardcodedname. The default remainsname, so existing setups are unaffected. - Replaced Sphinx documentation with Markdown-based docs in 'docs/'. @AlexSkrypnyk (#819)
The Read the Docs / Sphinx tree underdoc/is removed and replaced with plain Markdown underdocs/covering installation, configuration, drivers, contexts, hooks, and writing tests. The Read the Docs badge and links inREADME.mdare also dropped. - [#766] Added modern entity-field parser with 'field_parser' configuration flag. @AlexSkrypnyk (#818)
The newEntityFieldParserintroduces double-quote escaping, named-column compound syntax (country:"BE", locality:"Brussel"), structuredParseExceptionerrors 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 ofRawDrupalContext::parseEntityFields()into a newLegacyEntityFieldsParserimplementing a newParserInterface. 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-driverCoreInterface::classifier()accessor was renamed togetFieldClassifier()upstream, and this PR updates the single call site inparseEntityFields()and the four mock setups inRawDrupalContextTest. No backwards-compatibility shim is provided. - Removed PHPSpec-based unit testing from the project. @AlexSkrypnyk (#815)
The 22 PHPSpec spec files, thetest-phpspecahoy command, and thephpspec/phpspecComposer 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 exposeEntityStubInterfaceinstead of\stdClass, four parallel creation paths collapse into a singleentityCreate()entry point, and the fourcleanNodes()/cleanTerms()/cleanUsers()/cleanLanguages()AfterScenario hooks become a singlecleanEntities()reverse-walk.(object) [...]constructions becomenew EntityStub($type, $bundle, $values)and ad-hoc property access becomesgetValue()/setValue(). - [#806] Removed 'store' parameter from 'DrupalMailManager' and 'DrupalMailManagerInterface'. @AlexSkrypnyk (#812)
getMail()andclearMail()no longer accept a$storeargument because the v3 driver only exposes a single implicit collector. Tracked counts inRawMailContextcollapse fromarray<string, int>to a plainint, and the interimassertDefaultStore()guard added in #803 is removed. - [#752] Replaced generic exceptions with typed Mink exceptions across bundled contexts. @AlexSkrypnyk (#811)
Around 30\Exceptionthrows across the bundled contexts are replaced withBehat\Mink\Exception\ElementNotFoundException(lookups),Behat\Mink\Exception\ExpectationException(assertion mismatches), or\RuntimeException(configuration errors), with an "Exception conventions" section added toCONTRIBUTING.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@Thenmethods 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 X→Then the drush output should contain X,Then I log out→When I log out), and side-effect steps move from@Thento@When. Thescripts/docs.phpvalidator 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.pathsconfig,.behat.incloading,DrupalSubContextInterface,DrupalSubContextBase), the annotation-based hook reader (Annotation\Reader),RawDrupalContext::loggedInWithRole(), and theAnnotatedDefinitionProposalshim are all removed. Two remaininggetSelectorsHandler()->xpathLiteral()calls inMinkContextare replaced with the modernEscaper::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 customphpcs.xmlruleset is replaced with the full Drupal coding standards viadrevops/phpcs-standard0.7.x, aligning the project withdrupal/drupal-driver.phpcbfauto-fixed roughly 1,270 violations across 82 files; the upgrade enforces snake_case local variables,Generic.PHP.RequireStrictTypes, and the previously excludedDrupal.Files.LineLength.TooLongandDrupal.Semantics.FunctionTriggerErrorrules. - Updated 'drupal/drupal-driver' to 3.x and migrated to capability-based API. @AlexSkrypnyk (#803)
The monolithicDriverInterfaceis replaced with capability interfaces (AuthenticationCapabilityInterface,MailCapabilityInterface,ConfigCapabilityInterface,ContentCapabilityInterface,CacheCapabilityInterface,CronCapabilityInterface,LanguageCapabilityInterface,RoleCapabilityInterface,UserCapabilityInterface) and every CRUD method is renamed to a verb-noun form (createNode→nodeCreate,runCron→cronRun,clearCache→cacheClear,startCollectingMail→mailStartCollecting, etc.). Field classification moves to a dedicatedFieldClassifierInterfaceexposed viaCore::classifier(). - Added 6.x note to readme. @AlexSkrypnyk (#805)
A short 6.x note inREADME.mddirects readers to the5.xbranch for the 5.x maintenance line and tomainfor 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
- [#857] Allowed literal '"' inside unquoted scalar values. @AlexSkrypnyk (#858)
Full Changelog: v6.0.0-rc1...v6.0.0-rc2