Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Behat Laravel Package

ibexa/behat

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev ibexa/behat --no-scripts --no-plugins
    composer sync-recipes ibexa/behat --force -v
    

    Ensure you have a running Ibexa DXP instance (v5.x or v4.x) and Behat installed (behat/behat).

  2. Configure Behat: Copy the default configuration files from the package:

    php vendor/bin/ibexa-behat init
    

    This generates:

    • behat.yml (main config)
    • features/ (test scenarios)
    • src/Behat/ (custom context classes)
  3. First Test Case: Create a feature file (features/content_creation.feature):

    Feature: Content Creation
      Scenario: Create a basic page
        Given I am on the Ibexa admin interface
        When I create a new content item of type "article"
        And I fill in the title field with "Test Article"
        And I publish the content
        Then the content should be published successfully
    

    Run the test:

    vendor/bin/behat features/content_creation.feature
    
  4. Key Files to Review:

    • doc/getting_started.md (official docs)
    • src/Behat/Context/ (pre-built contexts like IbexaContext, ContentContext)
    • config/behat_ibexa_headless.yaml (headless browser config)

Implementation Patterns

Core Workflows

  1. Context-Driven Testing:

    • Extend IbexaContext or ContentContext for custom logic:
      // src/Behat/Context/CustomContext.php
      namespace App\Behat\Context;
      
      use Ibexa\Behat\Context\IbexaContext;
      
      class CustomContext extends IbexaContext {
          /**
           * @Given I verify the content has a specific field value
           */
          public function assertContentFieldValue(string $fieldIdentifier, string $expectedValue) {
              $content = $this->getContent();
              $value = $content->getFieldValue($fieldIdentifier);
              if ($value !== $expectedValue) {
                  throw new \Exception("Field '$fieldIdentifier' has value '$value', expected '$expectedValue'");
              }
          }
      }
      
    • Register the context in behat.yml:
      default:
        contexts:
          - Ibexa\Behat\Context\IbexaContext
          - App\Behat\Context\CustomContext
      
  2. Data Setup/Teardown:

    • Use BeforeScenario hooks to initialize data:
      /**
       * @BeforeScenario
       */
      public function setupContent() {
          $this->createContent('article', ['title' => 'Test Article']);
      }
      
    • Leverage IbexaContext::createContent() or updateContent() methods.
  3. Admin UI Automation:

    • Pre-built steps for common admin actions:
      Given I am on the "Content" section of the admin interface
      When I click on the "Create" button
      And I select the "article" content type
      
    • Use IbexaContext::navigateToAdmin() and IbexaContext::clickAdminButton().
  4. Headless Testing:

    • Configure behat_ibexa_headless.yaml for Selenium-based tests:
      default:
        extensions:
          Ibexa\Behat\Extension\HeadlessExtension:
            selenium_server_url: "http://localhost:4444/wd/hub"
            browser: "chrome"
      
    • Run headless tests:
      vendor/bin/behat --config=behat_ibexa_headless.yaml
      
  5. Integration with Ibexa Services:

    • Access Ibexa services via IbexaContext:
      $contentService = $this->getService('content_service');
      $locationService = $this->getService('location_service');
      
    • Useful for testing business logic (e.g., workflows, permissions).

Advanced Patterns

  1. Custom Step Definitions:

    • Create reusable steps in a context:
      /**
       * @Given I publish the content with ID :contentId
       */
      public function publishContentById(int $contentId) {
          $content = $this->getContentService()->loadContent($contentId);
          $this->getContentService()->publishVersion($content->versionInfo);
      }
      
  2. Environment-Specific Configs:

    • Override configs per environment (e.g., behat.local.yml):
      default:
        extensions:
          Ibexa\Behat\Extension\HeadlessExtension:
            browser: "firefox"
      
  3. Tagging and Filtering:

    • Tag scenarios for selective execution:
      @smoke
      Scenario: Smoke test for content creation
      
    • Run tagged tests:
      vendor/bin/behat @smoke
      
  4. Database Transactions:

    • Use IbexaContext::beginTransaction() and rollback() to isolate tests:
      /**
       * @BeforeScenario
       */
      public function beginTransaction() {
          $this->beginTransaction();
      }
      
      /**
       * @AfterScenario
       */
      public function rollbackTransaction() {
          $this->rollback();
      }
      
  5. Custom Fixtures:

    • Load fixtures before tests using IbexaContext::loadFixtures():
      /**
       * @BeforeScenario
       */
      public function loadFixtures() {
          $this->loadFixtures(['path/to/fixtures']);
      }
      

Gotchas and Tips

Common Pitfalls

  1. Database Connection Issues:

    • Problem: Early database initialization fails (fixed in v5.0.2).
    • Solution: Ensure IBEXA_SITEACCESS and IBEXA_DB_* env vars are set. Use .env.behat:
      IBEXA_SITEACCESS=admin
      IBEXA_DB_DATABASE=ibexa_behat
      
  2. Selenium/Browser Quirks:

    • Problem: Headless tests flaky due to timing issues.
    • Solution:
      • Add waits explicitly:
        $this->waitForElementVisible('.some-selector', 10);
        
      • Use behat_ibexa_headless.yaml to adjust timeouts:
        extensions:
          Ibexa\Behat\Extension\HeadlessExtension:
            wait_for_timeout: 15
        
  3. Context Loading Order:

    • Problem: Custom contexts not loaded due to incorrect behat.yml order.
    • Solution: List contexts in dependency order (e.g., base IbexaContext first).
  4. Content Not Found:

    • Problem: ContentNotFoundException when loading content.
    • Solution: Verify the content exists and the siteaccess is correct:
      $content = $this->getContentService()->loadContent($contentId, ['siteaccess' => 'admin']);
      
  5. Permission Denied:

    • Problem: Tests fail with "Access Denied" errors.
    • Solution: Use a user with admin privileges in fixtures or set up permissions via:
      $this->getPermissionResolver()->setPermission('content', 'publish', true);
      

Debugging Tips

  1. Enable Verbose Output:

    vendor/bin/behat -v
    
    • Useful for seeing context initialization logs.
  2. Dump Services:

    /**
     * @Given I dump the content service
     */
    public function dumpContentService() {
        dump($this->getService('content_service'));
    }
    
  3. Screenshots on Failure:

    • Configure headless extension to capture screenshots:
      extensions:
        Ibexa\Behat\Extension\HeadlessExtension:
          screenshot_path: "%paths.base%/var/behat_screenshots"
      
  4. Slow Tests:

    • Cause: Database queries or UI waits.
    • Fix: Optimize queries or reduce wait times in behat_ibexa_headless.yaml.

Extension Points

  1. Custom Extensions:
    • Create a custom Behat extension by implementing Behat\Testwork\Extension\ExtensionInterface:
      namespace App\Behat\Extension;
      
      use Behat\Testwork\Extension\ExtensionInterface;
      
      class CustomExtension implements ExtensionInterface {
          public function getConfigKey() { return 'custom'; }
          public function initialize(ExtensionConfiguration $extensionConfig) {}
          public function configure(ContainerBuilder $container) {}
          public function load(ContainerBuilder $container, Config $config) {}
      }
      
    • Register in behat.yml:
      default:
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views