drupal / drupal-driver
A collection of reusable Drupal drivers
Fund package maintenance!
Requires
- php: >=7.4
- drupal/core-utility: ^8.4 || ^9 || ^10 || ^11
- symfony/dependency-injection: ^2.6 || ^3.0 || ^4.4 || ^6 || ^7.1
- symfony/process: ^2.5 || ^3.0 || ^4.4 || ^6 || ^7
Requires (Dev)
- composer/installers: ^2.1
- dms/phpunit-arraysubset-asserts: ^0.4.0 || ^0.5.0
- drevops/phpcs-standard: ^0.7.0
- drupal/coder: ~8.3.0
- drupal/core-composer-scaffold: ^8.4 || ^9 || ^10 || ^11
- drupal/core-recommended: ^8.4 || ^9 || ^10 || ^11
- drupal/mailsystem: ^4.4 || 4.x-dev
- drush-ops/behat-drush-endpoint: *
- ergebnis/composer-normalize: ^2.50
- mockery/mockery: ^1.5
- palantirnet/drupal-rector: ^0.20
- php-parallel-lint/php-parallel-lint: ^1.0
- phpspec/phpspec: ^2.0 || ^4.0 || ^6.1 || ^7.5 || dev-main
- phpunit/phpunit: ^6.0 || ^7.0 || ^9 || ^10
- symfony/phpunit-bridge: ^6.1
Conflicts
- drupal/core: >=8.0 <9.3
- dev-master / 3.0.x-dev
- 2.x-dev
- v2.5.1
- v2.5.0
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.0
- v2.0.0-rc1
- v2.0.0-alpha6
- v2.0.0-alpha5
- v2.0.0-alpha4
- v2.0.0-alpha3
- v2.0.0-alpha2
- v2.0.0-alpha1
- v1.4.0
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-beta2
- v1.0.0-beta
- dev-feature/ext-smoke-ci
- dev-feature/field-coverage
- dev-feature/field-classifier
- dev-feature/driver-interface
- dev-feature/file-handler
- dev-feature/ext-smoke
This package is auto-updated.
Last update: 2026-04-28 08:44:39 UTC
README
A collection of lightweight drivers with a common interface for interacting with Drupal. These are generally intended for testing and are not meant to be API-complete.
Note: This
masterbranch is under heavy development for version 3.x. Drupal 6 and 7 support has been dropped. For the 2.x maintenance line, use the2.xbranch. See the 3.x epic for details and progress.
Drivers
| Driver | Description |
|---|---|
| Blackbox | No Drupal bootstrap. Interacts only through HTTP. |
| Drupal API | Bootstraps Drupal directly in PHP for programmatic access to entities, fields, users, and configuration. |
| Drush | Interacts with Drupal through the Drush command line tool. |
Installation
composer require drupal/drupal-driver
Usage
use Drupal\Driver\DrupalDriver; require 'vendor/autoload.php'; $path = './web'; // Path to Drupal root. $uri = 'http://my-site'; // Site URI. $driver = new DrupalDriver($path, $uri); $driver->setCoreFromVersion(); // Bootstrap Drupal. $driver->bootstrap(); // Create a node. $node = (object) [ 'type' => 'article', 'uid' => 1, 'title' => $driver->getRandom()->name(), ]; $driver->nodeCreate($node);
Extending
The driver lets consumer projects override two things without forking: individual field handlers and the top-level Core implementation.
Custom field handler
Implement Drupal\Driver\Core\Field\FieldHandlerInterface (extending
AbstractHandler is the usual path):
namespace MyProject\Driver\Field; use Drupal\Driver\Core\Field\AbstractHandler; class PhoneHandler extends AbstractHandler { public function expand(mixed $values): array { // Convert each scenario-facing phone string into the storage shape // Drupal's field system expects (a list of deltas keyed by column). return array_map(static fn (string $number): array => ['value' => $number], (array) $values); } }
Register it on the active Core instance, typically in a test bootstrap:
$driver = new DrupalDriver($root, $uri); $driver->setCoreFromVersion(); $driver->getCore()->registerFieldHandler('phone', \MyProject\Driver\Field\PhoneHandler::class);
Consumer registrations win over the handlers this project ships for the
same field type. Registration order at runtime is: driver default
handlers (populated by Core::registerDefaultFieldHandlers() at
construction) → consumer registrations → registry lookup at expand()
time, with a fall-through to DefaultHandler for field types no handler
claims.
Custom Core
Implement Drupal\Driver\Core\CoreInterface. The class name and
namespace do not matter. The easiest path is to extend
Drupal\Driver\Core\Core and add version-specific field handlers by
re-scanning your own Field/ directory:
namespace MyProject\Driver; use Drupal\Driver\Core\Core as BaseCore; class Core extends BaseCore { protected function registerDefaultFieldHandlers(): void { parent::registerDefaultFieldHandlers(); $this->registerHandlersFromDirectory(__DIR__ . '/Field', __NAMESPACE__ . '\\Field'); } }
Inject it with $driver->setCore($core):
$driver = new DrupalDriver($root, $uri); $driver->setCore(new \MyProject\Driver\Core($root, $uri));
Credits
- Originally developed by Jonathan Hedstrom
- Maintainers
Release notes
See GitHub Releases.
Contributing
Features and bug fixes are welcome!
See CONTRIBUTING.md for more information.