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.
| 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. |
composer require drupal/drupal-driveruse 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);The driver lets consumer projects override two things without forking: individual field handlers and the top-level Core implementation.
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.
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));- Originally developed by Jonathan Hedstrom
- Maintainers
See GitHub Releases.
Features and bug fixes are welcome!
See CONTRIBUTING.md for more information.