### KernelOrchestrator Initialization Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md Demonstrates how to instantiate and boot the necessary kernel objects and the Behat container to create a KernelOrchestrator instance. This setup is typically done before running Behat tests. ```php $symphonyKernel = new Kernel('test', true); $symphonyKernel->boot(); $driverKernel = clone $symphonyKernel; $driverKernel->boot(); $behatContainer = /* Behat's ContainerBuilder */; $orchestrator = new KernelOrchestrator( $symphonyKernel, $driverKernel, $behatContainer ); ``` -------------------------------- ### SymfonyDriver Initialization Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/02-symfony-driver.md Demonstrates how to instantiate the SymfonyDriver with a test Kernel and a base URL, then use it with a Mink session. This setup bypasses the need for a live web server. ```php use FriendsOfBehat\SymfonyExtension\Driver\SymfonyDriver; use Symfony\Component\HttpKernel\Kernel; $kernel = new Kernel('test', true); $kernel->boot(); $driver = new SymfonyDriver($kernel, 'http://localhost'); // Now use it with Mink $session = new \Behat\Mink\Session($driver); $session->visit('http://localhost/home'); ``` -------------------------------- ### Multiple Environments Configuration Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md Example demonstrating configuration for multiple environments, including a default and a production profile. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: ~ suites: default: contexts: - App\Tests\Behat\GeneralContext features: 'features/' production: extensions: FriendsOfBehat\SymfonyExtension: kernel: environment: 'prod' debug: false suites: default: contexts: - App\Tests\Behat\GeneralContext ``` -------------------------------- ### Instantiate MinkParameters Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/06-mink-integration.md Example of how to instantiate the `MinkParameters` class with configuration options. ```php $params = new MinkParameters([ 'base_url' => 'http://localhost', 'javascript_session' => 'default', 'default_session' => 'symfony', ]); ``` -------------------------------- ### Install SymfonyExtension via Composer Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Use Composer to install the SymfonyExtension. If using Mink, also install Mink-related packages. ```bash composer require --dev friends-of-behat/symfony-extension:^2.0 ``` ```bash composer require --dev \ behat/mink \ friends-of-behat/mink-extension \ behat/mink-browserkit-driver ``` -------------------------------- ### KernelOrchestrator setUp Method Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md The setUp method prepares kernels for a new scenario by injecting the Behat container into the Symfony kernel. This makes Behat services accessible to Symfony services. ```php public function setUp(): void ``` -------------------------------- ### Behat Configuration Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/00-index.md Example of how to configure the SymfonyExtension in the behat.yaml file. Shows default settings and overrides for bootstrap, kernel class, path, environment, and debug mode. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: bootstrap: ~ # Path to bootstrap file (auto-discovered) kernel: # Kernel configuration class: ~ # Kernel class name (auto-discovered) path: ~ # Path to kernel file (auto-discovered for Symfony 3) environment: ~ # Environment (fallback: APP_ENV or 'test') debug: ~ # Debug mode (fallback: APP_DEBUG or true) ``` -------------------------------- ### Build Environment Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Illustrates how the buildEnvironment method processes suite settings to create an uninitialized environment containing service contexts. ```php // Suite configured as: $suite->setSetting('contexts', [ 'App\Tests\Behat\SearchContext', // Service context 'App\Tests\Behat\DatabaseContext', // Service context ]); // buildEnvironment creates: $environment = $handler->buildEnvironment($suite); // $environment contains the uninitialized services ``` -------------------------------- ### Composer Installation Requirements Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Lists the necessary Composer packages to install for the Symfony driver to function correctly. Includes Mink, Mink Extension, and the BrowserKit driver. ```bash composer require --dev \ behat/mink \ friends-of-behat/mink-extension \ behat/mink-browserkit-driver ``` -------------------------------- ### ContextServiceEnvironmentHandler Support Check Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/README.md Example of checking if a specific Behat suite is supported by the ContextServiceEnvironmentHandler. ```php public function supportsSuite(Suite $suite): bool { return $suite->hasConfig('symfony') || $suite->hasConfig('kernel_id'); } ``` -------------------------------- ### SymfonyExtension Configuration with Mink Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/00-index.md Configure the SymfonyExtension alongside Mink for browser-based testing. This setup requires MinkExtension to be installed and configured with a base URL and a Symfony session. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: ~ Behat\MinkExtension: base_url: http://localhost sessions: symfony: symfony: ~ ``` -------------------------------- ### Isolate Environment Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Demonstrates the process of isolating an uninitialized environment to create an initialized one, allowing access to context instances. ```php // Given an uninitialized environment: $uninitialized = $handler->buildEnvironment($suite); // Isolate it to create initialized contexts: $initialized = $handler->isolateEnvironment($uninitialized); // Now you can get context instances: foreach ($initialized->getContextClasses() as $class) { $context = $initialized->getContext($class); // Use the context... } ``` -------------------------------- ### Bootstrap File Configuration Examples Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md Shows different ways to configure the bootstrap file, including explicit path, disabling auto-discovery, and using the default auto-discovery. ```yaml # Use explicit bootstrap file FriendsOfBehat\SymfonyExtension: bootstrap: tests/bootstrap.php ``` ```yaml # Disable auto-discovery FriendsOfBehat\SymfonyExtension: bootstrap: false ``` ```yaml # Use auto-discovery (default) FriendsOfBehat\SymfonyExtension: bootstrap: ~ ``` -------------------------------- ### Context Autoconfiguration Tagging Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/08-symfony-bundle.md Example of registering for autoconfiguration of Context classes, automatically tagging them with 'fob.context'. ```php $container->registerForAutoconfiguration(Context::class)->addTag('fob.context'); ``` -------------------------------- ### Get Driver Name Method Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Returns the name of the driver this factory creates, which is used by MinkExtension to identify the factory. The example shows how to retrieve and echo the driver name. ```php public function getDriverName(): string ``` ```php $factory = new SymfonyDriverFactory('symfony', new Reference('kernel')); echo $factory->getDriverName(); // symfony ``` -------------------------------- ### Common Mink Configuration Parameters Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/06-mink-integration.md Example YAML configuration for Behat's MinkExtension, including base URL, sessions, and default session settings. ```yaml Behat\MinkExtension: base_url: http://localhost javascript_session: chrome default_session: symfony sessions: symfony: symfony: ~ chrome: selenium2: wd_host: 'http://localhost:4444' show_cmd: open %s ``` -------------------------------- ### Example Suite Configuration in behat.yaml Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Demonstrates how to define contexts within a suite configuration in behat.yaml, supporting class names, service IDs, or arrays with service IDs. ```yaml default: suites: default: contexts: - App\Tests\Behat\MyContext # Class name - my_context_service_id # Service ID - { 'another_service': ~ } # Service ID in array ``` -------------------------------- ### Typical Bootstrap File Content Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md An example of what a typical bootstrap.php file might contain, including loading environment variables and pre-populating data. ```php loadEnv($envFile); } // Pre-populate database or fixtures require_once __DIR__ . '/fixtures/load_initial_data.php'; ``` -------------------------------- ### Accessing Behat Services in Symfony Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md Example demonstrating how a Symfony service can access Behat-specific services, such as Mink or the Behat container itself, after the KernelOrchestrator has performed its setup. This is crucial for integrating Behat and Symfony functionalities. ```php // In a Symfony service used by Behat: final class MyService { public function __construct(ContainerInterface $container) { // Access Behat services: $mink = $container->get('fob_symfony.mink'); $behatContainer = $container->get('behat.service_container'); } } ``` -------------------------------- ### Install SymfonyExtension with Composer (Symfony 6/7 Flex) Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md Use Composer to require the SymfonyExtension for Symfony 6/7 projects with Flex. ```bash composer require --dev friends-of-behat/symfony-extension:^2.0 ``` -------------------------------- ### RuntimeException for Missing BrowserKit Driver Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Illustrates the specific RuntimeException that occurs if `behat/mink-browserkit-driver` is not installed when `buildDriver()` is called for the Symfony driver. ```text RuntimeException: Install "behat/mink-browserkit-driver" in order to use the "symfony" driver. ``` -------------------------------- ### Kernel Environment Configuration Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md Sets the Symfony environment to 'test' for running Behat tests. This is the default behavior. ```yaml # Use test environment (default) FriendsOfBehat\SymfonyExtension: kernel: environment: 'test' ``` -------------------------------- ### Install Mink and Mink BrowserKit Driver Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md Use Composer to require the necessary packages for Mink integration and the BrowserKit driver. These packages provide the foundation for browser-like testing within Behat. ```bash composer require --dev behat/mink friends-of-behat/mink-extension behat/mink-browserkit-driver ``` -------------------------------- ### Symfony Services Configuration for Test Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md Example of configuring services for the test environment in `config/services_test.yaml`, including mocking external services. ```yaml # config/services_test.yaml services: _defaults: autowire: true autoconfigure: true # Autoload all Behat contexts App\Tests\Behat\: resource: '../tests/Behat/*' # Mock external services App\Service\ExternalApi: class: App\Tests\Mock\FakeExternalApi # Test-specific services App\Tests\Behat\Fixtures\DatabaseFixtures: public: true ``` -------------------------------- ### SymfonyExtension Configuration Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/README.md Example of configuring the SymfonyExtension within Behat's configuration. This sets up the base URL for the Mink driver. ```yaml imports: - "@SymfonyExtension/Resources/config/behat.yml" # Behat configuration behat: # Base URL for Mink driver base_url: http://localhost:8000 ``` -------------------------------- ### Register Context Initializer Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Registers a context initializer to perform setup on context instances before they are used. This is useful for injecting dependencies, setting up mocks, or configuring context state. ```php public function registerContextInitializer( Behat\Behat\Context\Initializer\ContextInitializer $contextInitializer ): void ``` ```php final class DatabaseInitializer implements ContextInitializer { private $connection; public function __construct(Connection $connection) { $this->connection = $connection; } public function initializeContext(Context $context): void { if ($context instanceof DatabaseAwareContext) { $context->setConnection($this->connection); } } } // Register it: $handler->registerContextInitializer(new DatabaseInitializer($conn)); ``` -------------------------------- ### Build Driver Method Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Builds a DI service definition for a SymfonyDriver instance. It checks for the BrowserKitDriver class and throws an exception if it's not installed. It returns a Definition for SymfonyDriver. ```php public function buildDriver(array $config): Definition ``` ```php $factory = new SymfonyDriverFactory('symfony', new Reference('fob_symfony.driver_kernel')); $definition = $factory->buildDriver([]); // Equivalent to this service definition: // fob_symfony_driver: // class: FriendsOfBehat\SymfonyExtension\Driver\SymfonyDriver // arguments: // - '@fob_symfony.driver_kernel' // - '%mink.base_url%' ``` -------------------------------- ### SymfonyExtension Kernel Lifecycle Events Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/11-architecture-overview.md Illustrates the sequence of kernel setup and teardown events managed by the KernelOrchestrator during Behat scenario execution to ensure isolation. ```text Scenario 1 starts → setUp(): Inject Behat container → Contexts execute → tearDown(): Shutdown, reboot, clear references Scenario 2 starts (fresh kernels) ``` -------------------------------- ### Get Service IDs from Uninitialized Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Retrieve an array of service IDs for all contexts managed by the `UninitializedSymfonyExtensionEnvironment`. This is useful for introspection. ```php $services = $uninitialized->getServices(); // ['app.tests.behat.search_context', 'app.tests.behat.database_context'] ``` -------------------------------- ### MinkParameters OffsetGet Retrieval Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/06-mink-integration.md Demonstrates retrieving a parameter value using `offsetGet`. Returns `null` if the key does not exist. This example also shows how to use the null coalescing operator. ```php public function offsetGet($offset): mixed ``` ```php $baseUrl = $params['base_url'] ?? 'http://localhost'; $missing = $params['nonexistent']; // null ``` -------------------------------- ### Initialize Environment with Suite Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Initializes the environment with a test suite. This is the first step in setting up the environment. ```php public function __construct(Behat\Testwork\Suite\Suite $suite) ``` ```php $suite = new GenericSuite('default', []); $initialized = new InitializedSymfonyExtensionEnvironment($suite); ``` -------------------------------- ### Kernel Orchestrator Setup Definition Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md This snippet shows how the KernelOrchestrator service is defined and registered within the Symfony container by the SymfonyExtension. It highlights the dependencies and tags applied to the service. ```php public function tearDown(): void ``` ```php $definition = new Definition(KernelOrchestrator::class, [ new Reference(SymfonyExtension::KERNEL_ID), new Reference(SymfonyExtension::DRIVER_KERNEL_ID), $container, // Behat container ]); $definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG); $container->setDefinition('fob_symfony.kernel_orchestrator', $definition); ``` -------------------------------- ### __construct Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Initializes the environment with a suite. ```APIDOC ## __construct(Suite $suite) ### Description Initializes the environment with a suite. ### Parameters #### Path Parameters - **suite** (Behat\Testwork\Suite\Suite) - Required - The test suite this environment belongs to ``` -------------------------------- ### KernelOrchestrator Event Mapping Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md Specifies the mapping between Behat events (like ScenarioTested::BEFORE) and the methods (like setUp) to be called, along with their priorities. Higher priorities ensure setup runs early and teardown runs late. ```php [ ScenarioTested::BEFORE => ['setUp', 15], ExampleTested::BEFORE => ['setUp', 15], ScenarioTested::AFTER => ['tearDown', -15], ExampleTested::AFTER => ['tearDown', -15], ] ``` -------------------------------- ### MinkParameters Get Iterator Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/README.md Implementation of the IteratorAggregate interface for iterating over Mink parameters. ```php public function getIterator(): Traversable { return new ArrayIterator($this->parameters); } ``` -------------------------------- ### MinkParameters Offset Get Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/README.md Implementation of the ArrayAccess interface for accessing Mink parameters by offset. ```php public function offsetGet($offset): mixed { return $this->parameters[$offset] ?? null; } ``` -------------------------------- ### Basic SymfonyExtension Configuration Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md Configure the SymfonyExtension with environment, kernel, and bootstrap path. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: kernel: environment: test bootstrap: tests/bootstrap.php ``` -------------------------------- ### Suite Configuration and Environment Initialization Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md The buildEnvironment() method extracts service IDs from the suite configuration and creates an uninitialized environment, holding class names and service IDs without instances. ```text Suite Configuration ↓ buildEnvironment() ├─ Extracts service IDs from suite ├─ Creates UninitializedSymfonyExtensionEnvironment └─ Holds class names and service IDs (not instances) ``` -------------------------------- ### Get SymfonyExtension Configuration Key Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/01-symfony-extension.md Retrieves the configuration key used for this extension in Behat configuration files. ```php public function getConfigKey(): string ``` ```php $extension = new SymfonyExtension(); echo $extension->getConfigKey(); // outputs: fob_symfony ``` -------------------------------- ### Get Registered Context Classes Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Retrieves an array of all registered context class names. This is useful for introspection or debugging. ```php public function getContextClasses(): array ``` ```php $classes = $initialized->getContextClasses(); // ['App\Tests\Behat\SearchContext', 'App\Tests\Behat\DatabaseContext'] ``` -------------------------------- ### Set Up Fixtures in Behat Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Implement FixtureContext to manage database fixtures, including clearing the database before scenarios and creating specific data using factories. ```php final class FixtureContext implements Context, ContextInitializer { public function __construct( private EntityManagerInterface $em, private UserFactory $userFactory, ) {} public function initializeContext(Context $context): void { if ($context instanceof NeedsFixtures) { $context->setFixtures($this); } } /** @Given there is a user with email :email */ public function createUser(string $email): void { $user = $this->userFactory->create(['email' => $email]); $this->em->persist($user); $this->em->flush(); } /** @Before */ public function clearDatabase(): void { // Reset database before each scenario $connection = $this->em->getConnection(); $connection->executeQuery('TRUNCATE TABLE users'); } } ``` -------------------------------- ### Sample Behat Feature File Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md A sample feature file to demonstrate checking the application's kernel environment. ```gherkin # features/using_symfony_extension.feature Feature: Using SymfonyExtension Scenario: Checking the application's kernel environment Then the application's kernel should use "test" environment ``` -------------------------------- ### Source Structure Overview Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/11-architecture-overview.md Illustrates the directory structure of the SymfonyExtension, highlighting key components like service containers, bundles, listeners, contexts, and drivers. ```text src/ ├── ServiceContainer/ │ └── SymfonyExtension.php # Main extension (Behat) ├── Bundle/ │ ├── FriendsOfBehatSymfonyExtensionBundle.php │ └── DependencyInjection/ │ └── FriendsOfBehatSymfonyExtensionExtension.php # Bundle extension ├── Listener/ │ └── KernelOrchestrator.php # Scenario lifecycle ├── Context/Environment/ │ ├── SymfonyExtensionEnvironment.php │ ├── UninitializedSymfonyExtensionEnvironment.php │ ├── InitializedSymfonyExtensionEnvironment.php │ └── Handler/ │ └── ContextServiceEnvironmentHandler.php ├── Driver/ │ ├── SymfonyDriver.php # Mink driver │ └── Factory/ │ └── SymfonyDriverFactory.php # Driver factory └── Mink/ ├── Mink.php # Wrapper (deprecated) └── MinkParameters.php # Configuration wrapper ``` -------------------------------- ### Basic Scenario Usage with Symfony Driver Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Demonstrates how to use the configured 'symfony' session in Behat scenarios to visit pages and assert content. Assumes no JavaScript execution. ```gherkin Feature: Product browsing Background: Given I am using the "symfony" session Scenario: View products When I visit "/products" Then I should see "Product List" And I should see "Product 1" Scenario: JavaScript required When I visit "/products/interactive" Then the interactive list should load # Will fail - no JS ``` -------------------------------- ### KernelOrchestrator Class Signature Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/00-index.md Manages the lifecycle of the Symfony kernel during Behat scenarios. It subscribes to scenario events for setup and teardown. ```php class KernelOrchestrator implements EventSubscriberInterface { public function __construct( KernelInterface $symfonyKernel, KernelInterface $driverKernel, ContainerInterface $behatContainer ) public static function getSubscribedEvents(): array public function setUp(): void public function tearDown(): void } ``` -------------------------------- ### initialize Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/01-symfony-extension.md Initializes the extension by registering the Symfony Mink driver with MinkExtension if it is available. This method is called by the Behat Testwork extension manager. ```APIDOC ## initialize ### Description Initializes the extension by registering the Symfony Mink driver with MinkExtension if it is available. ### Method public function initialize(ExtensionManager $extensionManager): void ### Parameters #### Parameters - **extensionManager** (Behat\Testwork\ServiceContainer\ExtensionManager) - Required - The extension manager used to find and configure other extensions. ### Behavior Checks if MinkExtension is available in the extension manager. If found, registers a `SymfonyDriverFactory` that creates a Mink driver backed by the isolated driver kernel. ``` -------------------------------- ### Minimal SymfonyExtension Configuration Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/00-index.md Use this minimal configuration to enable auto-discovery of the SymfonyExtension. Ensure Behat is installed and the extension is registered in config/bundles.php. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: ~ ``` -------------------------------- ### MinkParameters Constructor Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/06-mink-integration.md Initializes the `MinkParameters` wrapper with a Mink configuration array. This class provides array-like access to Mink extension configuration. ```php public function __construct(array $minkParameters) ``` -------------------------------- ### ContextServiceEnvironmentHandler Build Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/README.md Demonstrates building the Behat environment using the ContextServiceEnvironmentHandler, which maps Symfony services to contexts. ```php public function buildEnvironment(Suite $suite): Environment { $environment = new InitializedSymfonyExtensionEnvironment( $this->container->get(self::KERNEL_ID), // Main kernel $this->container->get(self::DRIVER_KERNEL_ID) // Driver kernel ); // Register context initializers foreach ($this->contextInitializers as $initializer) { $environment->registerContextInitializer($initializer); } return $environment; } ``` -------------------------------- ### Instantiate UninitializedSymfonyExtensionEnvironment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Create an instance of `UninitializedSymfonyExtensionEnvironment` before contexts are instantiated. This class holds service IDs and class names for contexts. ```php $suite = new GenericSuite('default', []); $contexts = [ 'app.tests.behat.search_context' => 'App\Tests\Behat\SearchContext', 'app.tests.behat.database_context' => 'App\Tests\Behat\DatabaseContext', ]; $delegatedEnv = /* ... */; $uninitialized = new UninitializedSymfonyExtensionEnvironment($suite, $contexts, $delegatedEnv); ``` -------------------------------- ### Get Delegated Environment from Uninitialized Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Access the delegated `ContextEnvironment` from `UninitializedSymfonyExtensionEnvironment`. This environment handles contexts not defined as Symfony services. ```php public function getDelegatedEnvironment(): ContextEnvironment { } ``` -------------------------------- ### Bootstrap File Parameter Substitution Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md Demonstrates using parameter substitution for the bootstrap file path, resolving against Symfony's ParameterBag. ```yaml FriendsOfBehat\SymfonyExtension: bootstrap: '%paths.base%/tests/bootstrap.php' ``` -------------------------------- ### Autowiring BrowserKit Client Classes Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/08-symfony-bundle.md Demonstrates how BrowserKit client classes can be autowired in Symfony services using aliases for the 'test.client' service. ```php final class HttpContext implements Context { public function __construct( KernelBrowser $client, // Autowired from test.client alias HttpKernelBrowser $browser, // Same as above Client $client2, // Legacy class name ) { // All three refer to the same test.client service } } ``` -------------------------------- ### Initialize ContextServiceEnvironmentHandler Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Initializes the handler with a Symfony kernel and a decorated environment handler. The kernel is used for accessing services, and the decorated handler is for delegating non-service contexts. ```php public function __construct( Symfony\Component\HttpKernel\KernelInterface $symfonyKernel, Behat\Testwork\Environment\Handler\EnvironmentHandler $decoratedEnvironmentHandler ) ``` ```php $kernel = new Kernel('test', true); $kernel->boot(); $decoratedHandler = /* original ContextExtension handler */; $handler = new ContextServiceEnvironmentHandler($kernel, $decoratedHandler); ``` -------------------------------- ### KernelOrchestrator Subscribed Events Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/03-kernel-orchestrator.md Defines the Behat events that the KernelOrchestrator listens to and the corresponding methods to execute. This allows the orchestrator to react to scenario and example lifecycles. ```php public static function getSubscribedEvents(): array ``` -------------------------------- ### Get All Context Class Names from Uninitialized Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Obtain a merged array of all context class names, including both service-based and delegated contexts, from the `UninitializedSymfonyExtensionEnvironment`. ```php $classes = $uninitialized->getContextClasses(); // ['App\Tests\Behat\SearchContext', 'App\Tests\Behat\DatabaseContext', ...] ``` -------------------------------- ### Missing test.client Service Error Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/10-configuration-reference.md This error indicates that the 'test.client' service is missing in the kernel configuration. Ensure the kernel is set to the 'test' environment or enable 'framework.test' in the configuration. ```text RuntimeException: Kernel "..." used by Behat with "test" environment and debug enabled does not have "test.client" service. ``` -------------------------------- ### Scenario End and Environment Cleanup Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md At the end of a scenario, the environment is discarded, the KernelOrchestrator shuts down the kernel, and the system prepares for the next scenario to start fresh. ```text Scenario End ├─ Environment discarded ├─ KernelOrchestrator shuts down kernel └─ Next scenario starts fresh ``` -------------------------------- ### ContextServiceEnvironmentHandler Class Methods Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/MANIFEST.txt Documentation for the public methods of the FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler class. ```APIDOC ## Class FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler ### Description Handles context resolution for services within the Symfony environment. ### Methods #### `supports(string $environment)` ##### Description Checks if the handler supports the given environment. ##### Signature `public supports(string $environment): bool` ##### Parameters - **environment** (string) - The environment name. ##### Return Value `bool` - True if the handler supports the environment, false otherwise. ##### Exceptions None documented. ##### Example ```php // Example usage not provided in source. ``` #### `getServices(string $environment)` ##### Description Gets the services for the given environment. ##### Signature `public getServices(string $environment): array` ##### Parameters - **environment** (string) - The environment name. ##### Return Value `array` - An array of service IDs. ##### Exceptions None documented. ##### Example ```php // Example usage not provided in source. ``` #### `getServiceArguments(string $environment, string $serviceId)` ##### Description Gets the arguments for a given service ID in the specified environment. ##### Signature `public getServiceArguments(string $environment, string $serviceId): array` ##### Parameters - **environment** (string) - The environment name. - **serviceId** (string) - The ID of the service. ##### Return Value `array` - An array of service arguments. ##### Exceptions None documented. ##### Example ```php // Example usage not provided in source. ``` #### `getServiceDefinitions(string $environment)` ##### Description Gets the service definitions for the given environment. ##### Signature `public getServiceDefinitions(string $environment): array` ##### Parameters - **environment** (string) - The environment name. ##### Return Value `array` - An array of service definitions. ##### Exceptions None documented. ##### Example ```php // Example usage not provided in source. ``` #### `getServiceDefinition(string $environment, string $serviceId)` ##### Description Gets the definition for a specific service ID in the given environment. ##### Signature `public getServiceDefinition(string $environment, string $serviceId): array` ##### Parameters - **environment** (string) - The environment name. - **serviceId** (string) - The ID of the service. ##### Return Value `array` - The service definition. ##### Exceptions None documented. ##### Example ```php // Example usage not provided in source. ``` ``` -------------------------------- ### process Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/01-symfony-extension.md Processes registered services after all extensions have loaded their definitions. This ensures that context initializers are correctly registered for scenario execution. ```APIDOC ## process ### Description Processes registered services after all extensions have loaded their definitions. ### Method public function process(ContainerBuilder $container): void ### Parameters #### Parameters - **container** (Symfony\Component\DependencyInjection\ContainerBuilder) - Required - The Behat service container builder. ### Behavior Registers all tagged context initializers with the context service environment handler so they can initialize contexts during scenario execution. ``` -------------------------------- ### Behat Context with Autowired Symfony Service Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Example of a Behat context class that utilizes dependency injection. The ProductRepository is automatically resolved and injected from the Symfony container. ```php namespace App\Tests\Behat; use Behat\Behat\Context\Context; use App\Repository\ProductRepository; final class ProductContext implements Context { public function __construct(private ProductRepository $repo) {} /** @When I search for products */ public function searchProducts(): void { // $repo is autowired from Symfony container $products = $this->repo->findAll(); } } ``` -------------------------------- ### Registering Context Initializers Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Illustrates how context initializers are registered via the Symfony container's tagged services. ```php foreach ($container->findTaggedServiceIds(ContextExtension::INITIALIZER_TAG) as $serviceId => $tags) { $definition->addMethodCall('registerContextInitializer', [new Reference($serviceId)]); } ``` -------------------------------- ### Initialize SymfonyDriver Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/02-symfony-driver.md Initializes the SymfonyDriver with a Symfony Kernel instance and an optional base URL. Ensure the kernel is booted and has a 'test.client' service. ```php public function __construct( Symfony\Component\HttpKernel\KernelInterface $kernel, ?string $baseUrl ) ``` -------------------------------- ### SymfonyDriver Reset Example Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/02-symfony-driver.md Calling the reset method on the driver. This action ensures that subsequent requests are made with a fresh browser instance, reflecting the latest kernel state. ```php $driver->reset(); // Creates new KernelBrowser instance // Subsequent requests will use the new browser with fresh kernel state ``` -------------------------------- ### Mink Configuration with SymfonyExtension Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Configure Mink to use the Symfony session for testing. This setup is useful for integrating Behat's web testing capabilities with your Symfony application. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: kernel: environment: 'test' Behat\MinkExtension: base_url: 'http://localhost' default_session: symfony sessions: symfony: symfony: ~ chrome: selenium2: wd_host: 'http://localhost:4444' suites: default: contexts: - App\Tests\Behat\WebContext features: features/ ``` -------------------------------- ### Enabling Test Environment for Kernel Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md Configure the SymfonyExtension to use the 'test' environment for the kernel (APP_ENV). This is a common setup for ensuring tests run in an isolated and predictable environment. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: kernel: environment: test ``` -------------------------------- ### Switching Drivers within a Context Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Shows how to programmatically switch between Mink drivers (Symfony and Selenium/Chrome) within a PHP Behat context class. Useful for testing different environments. ```php final class ProductContext implements Context { private $mink; public function __construct(Mink $mink) { $this->mink = $mink; } /** @When I view products without JavaScript */ public function viewProductsNoJs(): void { $this->mink->setDefaultSessionName('symfony'); $this->mink->getSession()->visit('/products'); } /** @When I view products with JavaScript */ public function viewProductsWithJs(): void { $this->mink->setDefaultSessionName('chrome'); $this->mink->getSession()->visit('/products'); } } ``` -------------------------------- ### Configure Kernel Path Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/01-symfony-extension.md Provide the path to the PHP file containing the kernel class definition if it's not autoloaded by Composer. This is typically needed for custom kernel setups. ```yaml fob_symfony: kernel: class: 'AppKernel' path: 'app/AppKernel.php' ``` -------------------------------- ### buildEnvironment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Builds an uninitialized environment for a suite by extracting service contexts and delegating others. It normalizes contexts to service IDs, checks for their existence in the Symfony container, and maps them to class names. Non-service contexts are handled by delegation. ```APIDOC ## buildEnvironment(Suite $suite): Environment ### Description Builds an uninitialized environment for a suite by extracting service contexts and delegating others. ### Method `buildEnvironment` ### Parameters #### Path Parameters - **suite** (Suite) - Yes - The suite to build an environment for ### Returns `UninitializedSymfonyExtensionEnvironment` ### Example ```php // Suite configured as: $suite->setSetting('contexts', [ 'App\Tests\Behat\SearchContext', // Service context 'App\Tests\Behat\DatabaseContext', // Service context ]); // buildEnvironment creates: $environment = $handler->buildEnvironment($suite); // $environment contains the uninitialized services ``` ``` -------------------------------- ### Set Test Environment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Configure the kernel environment to 'test' in behat.yaml to fix 'Missing test.client service' errors. ```yaml FriendsOfBehat\SymfonyExtension: kernel: environment: 'test' ``` -------------------------------- ### Accessing Mink Parameters in PHP Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/06-mink-integration.md Demonstrates how to access common Mink configuration parameters like base URL, JavaScript session, and default session from a PHP context using the MinkParameters object. ```php $baseUrl = $params['base_url']; // http://localhost $jsSession = $params['javascript_session']; // chrome $defaultSession = $params['default_session']; // symfony ``` -------------------------------- ### Behat Context Usage with SymfonyDriver Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/02-symfony-driver.md Example of a Behat context class that utilizes the Mink session configured with SymfonyDriver. It demonstrates visiting a URL and asserting text presence on the page. ```php use Behat\Behat\Context\Context; use Behat\Mink\Session; class WebContext implements Context { private $session; public function __construct(Session $session) { $this->session = $session; } /** * @When I visit the homepage */ public function visitHomepage(): void { $this->session->visit('http://localhost/'); } /** * @Then I should see :text */ public function shouldSee(string $text): void { $page = $this->session->getPage(); if (strpos($page->getText(), $text) === false) { throw new Exception("Text not found: $text"); } } } ``` -------------------------------- ### isolateEnvironment Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/04-context-environment-handler.md Initializes an uninitialized environment by instantiating services and calling initializers. It validates the environment type, creates an initialized environment, instantiates and initializes service contexts, and then isolates delegated environments. ```APIDOC ## isolateEnvironment(Environment $environment, $testSubject = null): Environment ### Description Initializes an uninitialized environment by instantiating services and calling initializers. ### Method `isolateEnvironment` ### Parameters #### Path Parameters - **environment** (Environment) - Yes - Must be a `UninitializedSymfonyExtensionEnvironment` - **testSubject** (mixed) - No - The test subject (usually null) ### Throws - **EnvironmentIsolationException** - If the environment is not a `UninitializedSymfonyExtensionEnvironment` ### Returns `InitializedSymfonyExtensionEnvironment` - with all contexts instantiated and initialized ### Example ```php // Given an uninitialized environment: $uninitialized = $handler->buildEnvironment($suite); // Isolate it to create initialized contexts: $initialized = $handler->isolateEnvironment($uninitialized); // Now you can get context instances: foreach ($initialized->getContextClasses() as $class) { $context = $initialized->getContext($class); // Use the context... } ``` ``` -------------------------------- ### Create a Basic Behat Context Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Define a Behat context class that extends Behat\Behat\Context\Context and injects application services like UserRepository. ```php users = $this->repo->findByName($name); } /** @Then I should find :count users */ public function assertUserCount(int $count): void { if (count($this->users) !== $count) { throw new \Exception("Expected $count users, got " . count($this->users)); } } } ``` -------------------------------- ### Explicit SymfonyExtension Configuration Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/00-index.md Provide explicit configuration for the SymfonyExtension, including the kernel class, environment, and debug mode. This is useful for custom kernel setups or specific testing environments. ```yaml default: extensions: FriendsOfBehat\SymfonyExtension: bootstrap: tests/bootstrap.php kernel: class: App\Kernel environment: test debug: true ``` -------------------------------- ### Custom Context Initialization Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/11-architecture-overview.md Implement the ContextInitializer interface to customize how contexts are initialized. This is useful for setting specific states or dependencies on your custom contexts before they are used. ```php final class CustomInitializer implements ContextInitializer { public function initializeContext(Context $context): void { if ($context instanceof MyContextInterface) { $context->setCustomState(...); } } } // Registered via tag: // services: // App\Tests\Behat\CustomInitializer: // tags: // - { name: behat.context_initializer } ``` -------------------------------- ### Extension Configuration Structure Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/09-types-and-interfaces.md Defines the expected structure for the extension's configuration, including bootstrap and kernel settings. ```php array { 'bootstrap': string|bool|null, 'kernel': array { 'class': string|null, 'path': string|null, 'environment': string|null, 'debug': bool|null, } } ``` -------------------------------- ### Configure Method Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Defines the configuration schema for the driver. Currently, this method is empty as there are no driver-specific configuration options for the Symfony driver. ```php public function configure(ArrayNodeDefinition $builder): void ``` ```yaml Behat\MinkExtension: sessions: symfony: symfony: ~ # No configuration here ``` -------------------------------- ### Run Tagged Scenarios Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Execute scenarios marked with specific tags. Multiple tags can be specified. ```bash vendor/bin/behat -t @slow ``` ```bash vendor/bin/behat -t @javascript ``` -------------------------------- ### Enable Autowiring for Services Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Enable autowiring and autoconfiguration for services in services_test.yaml to fix context autowiring issues. ```yaml services: _defaults: autowire: true autoconfigure: true ``` -------------------------------- ### Inject Mink Session and Router into Context Source: https://github.com/friendsofbehat/symfonyextension/blob/master/DOCUMENTATION.md Modify your context class to accept a Mink Session and a RouterInterface as constructor arguments. This allows you to interact with the browser and generate URLs within your tests. ```php use Behat\Behat\Context\Context; use Behat\Mink\Session; use Symfony\Component\Routing\RouterInterface; final class DemoContext implements Context { /** @var Session */ private $session; /** @var RouterInterface */ private $router; public function __construct(Session $session, RouterInterface $router) { $this->session = $session; $this->router = $router; } /** * @Then I visit some page */ public function visitSomePage(): void { $this->session->visit($this->router->generate('some_route')); } } ``` -------------------------------- ### SymfonyExtension XML Service Configuration: Before Upgrade Source: https://github.com/friendsofbehat/symfonyextension/blob/master/UPGRADE-2.0.md This XML snippet shows the service definitions in SymfonyExtension before the upgrade, illustrating the use of 'mink.default_session' and prefixed service arguments. ```xml %__behat__.mink.parameters% ``` -------------------------------- ### Accessing Other Contexts from Within a Context Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Demonstrates how a context can access other registered contexts via the environment. This is a common pattern for inter-context communication. ```php final class SearchContext implements Context { private $environment; public function __construct(private InitializedSymfonyExtensionEnvironment $env) {} /** @When I search and verify results */ public function searchAndVerify(): void { $this->search(); // Access another context: $resultContext = $this->env->getContext(ResultContext::class); $resultContext->verifyResults(); } } ``` -------------------------------- ### SymfonyExtension Context Resolution Process Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/11-architecture-overview.md Details the steps involved in Behat's environment building and isolation, from suite configuration to the creation of initialized contexts using Symfony services. ```text Suite Configuration (behat.yaml) ↓ buildEnvironment() ├─ Find service IDs in configuration ├─ Check if services exist in Symfony container ├─ Create UninitializedSymfonyExtensionEnvironment └─ Return with service classes (not instances) ↓ isolateEnvironment() ├─ Get actual service instances from container ├─ Call registered context initializers ├─ Create InitializedSymfonyExtensionEnvironment └─ Register initialized contexts ↓ Scenario Execution ├─ Behat calls step methods on contexts └─ Contexts use injected services ``` -------------------------------- ### Symfony Services Configuration for Contexts Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/08-symfony-bundle.md Shows how to configure Symfony services to automatically wire and discover Context classes, leveraging the 'fob.context' tag. ```yaml # config/services_test.yaml services: _defaults: autowire: true autoconfigure: true App\Tests\Behat\: resource: '../tests/Behat/*' # Contexts are automatically tagged as 'fob.context' and made public ``` -------------------------------- ### Run Single Scenario by Line Number Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/12-quick-reference.md Execute a specific scenario from a feature file by providing its line number. ```bash vendor/bin/behat features/product.feature:5 ``` -------------------------------- ### Register a Context Instance Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Registers an instantiated context in the environment. Contexts are stored internally by their class name for later retrieval. ```php public function registerContext(Behat\Behat\Context\Context $context): void ``` ```php $this->contexts[get_class($context)] = $context; ``` ```php $context = new SearchContext(/* ... */); $initialized->registerContext($context); ``` -------------------------------- ### getSuite Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Returns the suite this environment belongs to. ```APIDOC ## getSuite(): Suite ### Description Returns the suite this environment belongs to. ### Returns Behat\Testwork\Suite\Suite - The test suite this environment belongs to ``` -------------------------------- ### Registering the Bundle in app/AppKernel.php (Symfony 3) Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/08-symfony-bundle.md Demonstrates how to register the FriendsOfBehatSymfonyExtensionBundle in the app/AppKernel.php file for Symfony 3. This is an alternative registration method for older Symfony versions. ```php // app/AppKernel.php public function registerBundles() { $bundles = [/* ... */]; if ('test' === $this->getEnvironment()) { $bundles[] = new FriendsOfBehatSymfonyExtensionBundle(); } return $bundles; } ``` -------------------------------- ### registerContext Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/05-context-environments.md Registers an instantiated context in this environment. ```APIDOC ## registerContext(Context $context): void ### Description Registers an instantiated context in this environment. ### Parameters #### Path Parameters - **context** (Behat\Behat\Context\Context) - Required - The context instance to register ``` -------------------------------- ### Registering the Bundle in config/bundles.php Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/08-symfony-bundle.md Shows how to register the FriendsOfBehatSymfonyExtensionBundle in the config/bundles.php file for Symfony 6/7 environments. Ensure it's enabled for the 'test' environment. ```php // config/bundles.php return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], // ... other bundles FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true], ]; ``` -------------------------------- ### Registering SymfonyDriverFactory with MinkExtension Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/07-driver-factory.md Shows how the SymfonyDriverFactory is registered with MinkExtension during extension initialization. This enables the 'symfony' driver for Mink sessions. ```php private function registerMinkDriver(ExtensionManager $extensionManager): void { /** @var MinkExtension|null $minkExtension */ $minkExtension = $extensionManager->getExtension('mink'); if (null === $minkExtension) { return; } $minkExtension->registerDriverFactory( new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)) ); $this->minkExtensionFound = true; } ``` -------------------------------- ### Configure Bootstrap Path Source: https://github.com/friendsofbehat/symfonyextension/blob/master/_autodocs/01-symfony-extension.md Specify the path to a PHP file to be required before booting the Symfony kernel. Useful for setting up global state or environment variables. ```yaml fob_symfony: bootstrap: '%paths.base%/tests/bootstrap.php' ```