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

Mink Bundle Laravel Package

behat/mink-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require --dev behat/mink-bundle

Add the bundle to config/bundles.php:

return [
    // ...
    Behat\MinkBundle\MinkBundle::class => ['test' => true],
];
  1. Configure config/packages/test/mink.yaml (Symfony 4+):

    mink:
        base_url: 'http://localhost:8000'
        browser_name: 'goutte'  # Default for headless testing
        goutte: ~
        selenium2: ~
    
  2. First Use Case: Inject Mink into a test class and use it to interact with pages:

    use Behat\Mink\Mink;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    
    class ExampleTest extends WebTestCase
    {
        private Mink $mink;
    
        protected function setUp(): void
        {
            $this->mink = static::createClient()->getContainer()->get('mink');
        }
    
        public function testHomepage()
        {
            $this->mink->visit('/');
            $this->assertEquals('Welcome', $this->mink->getPage()->getTitle());
        }
    }
    
  3. Key Classes to Know:

    • Mink (main interface)
    • Session (e.g., goutte, selenium2)
    • Page (represents a page, methods like getTitle(), find())
    • Element (interact with DOM elements, e.g., click(), fillField()).

Implementation Patterns

Common Workflows

1. Basic Page Interaction

// Visit a page
$this->mink->visit('/dashboard');

// Assert content
$this->assertEquals('Dashboard', $this->mink->getPage()->getTitle());

// Find and interact with elements
$link = $this->mink->getSession()->getPage()->find('link', ['text' => 'Profile']);
$link->click();

2. Form Submission

$page = $this->mink->getPage();
$page->fillField('email', 'user@example.com');
$page->fillField('password', 'secret123');
$page->pressButton('Login');

3. Switching Drivers Dynamically

Configure multiple drivers in mink.yaml and switch via setDefaultDriver():

mink:
    drivers:
        goutte: ~
        selenium2:
            wd_host: 'http://localhost:4444/wd/hub'
// In test
$this->mink->setDefaultDriver('selenium2'); // Switch to Selenium2
$this->mink->visit('/');

4. Reusable Page Objects

Create a Page class to encapsulate interactions:

class DashboardPage
{
    private $mink;

    public function __construct(Mink $mink)
    {
        $this->mink = $mink;
    }

    public function open()
    {
        $this->mink->visit('/dashboard');
    }

    public function getUserName(): string
    {
        return $this->mink->getSession()->getPage()->find('css', '.username')->getText();
    }
}

5. Integration with PHPUnit

Use setUp() and tearDown() to manage the Mink instance:

protected function setUp(): void
{
    $this->mink = static::createClient()->getContainer()->get('mink');
    $this->mink->start();
}

protected function tearDown(): void
{
    $this->mink->stop();
}

6. Handling JavaScript with Selenium2

Configure Selenium2 in mink.yaml:

mink:
    drivers:
        selenium2:
            wd_host: 'http://localhost:4444/wd/hub'
            capabilities: { 'browserName': 'chrome' }

Use in tests:

$this->mink->setDefaultDriver('selenium2');
$this->mink->visit('/');
$this->assertEquals('Dynamic Title', $this->mink->getPage()->getTitle());

Integration Tips

Laravel-Specific Tips

  1. Service Container Integration: MinkBundle is designed for Symfony, but you can manually integrate it into Laravel by:

    • Binding Mink and Session to the Laravel container.
    • Example:
      $this->app->bind('mink', function () {
          return new Mink(new \Behat\Mink\Driver\Goutte\Driver());
      });
      
  2. Testing Laravel Routes: Use visit() with Laravel’s URL generator:

    $this->mink->visit(route('dashboard'));
    
  3. Artisan Commands: Create a custom command to run Mink tests:

    use Behat\Mink\Mink;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class RunMinkTests extends Command
    {
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $mink = $this->getContainer()->get('mink');
            // Run tests...
        }
    }
    
  4. Parallel Testing: Use parallel_lint or custom scripts to run tests in parallel, as MinkBundle doesn’t natively support it.


Gotchas and Tips

Pitfalls

  1. Deprecated Package:

    • The package is archived (last release in 2014) and lacks modern Symfony/Laravel support.
    • Workaround: Use mink (standalone) + symfony/mink-bundle (if available) or migrate to modern alternatives like:
  2. Selenium2/Zombie Bugs:

    • The README mentions a "bug" in Zombie and Selenium drivers. Avoid these unless you’ve patched them.
    • Tip: Stick to goutte for headless testing or selenium2 with a stable WebDriver setup.
  3. Configuration Overrides:

    • Parameters in parameters.yml do not override config_test.yml by default. Use:
      # config/packages/test/mink.yaml
      mink:
          base_url: '%env(MINK_BASE_URL)%'
      
      Then set the env var:
      MINK_BASE_URL="http://staging.example.com" php artisan test
      
  4. Session Management:

    • Mink sessions are not automatically reset between tests. Manually call:
      $this->mink->getSession()->reset();
      
      or use start()/stop() in setUp()/tearDown().
  5. CSS Selector Quirks:

    • Goutte’s CSS selectors may behave differently than browser DevTools. Use XPath for complex queries:
      $element = $this->mink->getSession()->getPage()->find('xpath', '//*[@id="dynamic-id"]');
      
  6. JavaScript Limitations:

    • Goutte does not execute JavaScript. Use Selenium2 for JS-heavy apps, but expect slower tests.

Debugging Tips

  1. Enable Verbose Output: Configure Mink to log requests/responses:

    mink:
        goutte:
            client:
                options:
                    debug: true
    
  2. Inspect the DOM: Dump the current page HTML for debugging:

    $html = $this->mink->getSession()->getPage()->getContent();
    file_put_contents('debug.html', $html);
    
  3. Selenium2 Logs: Enable WebDriver logs:

    mink:
        selenium2:
            wd_host: 'http://localhost:4444/wd/hub'
            capabilities: { 'browserName': 'chrome', 'loggingPrefs': { 'browser': 'ALL' } }
    
  4. Handle Stale Elements: Use wait() to handle AJAX-loaded content:

    $this->mink->getSession()->wait(5000, "page contains 'Expected Content'");
    

Extension Points

  1. Custom Drivers: Extend Behat\Mink\Driver\DriverInterface to create a custom driver (e.g., for a headless Chrome instance).

  2. Event Listeners: Attach listeners to Mink events (e.g., Mink\Event\BeforeScenarioEvent) for pre/post-test hooks.

  3. Mocking Sessions: For unit testing, mock the Session interface:

    $mockSession = $this->createMock(Session::class);
    $mockSession->method('getPage')->willReturn($this->create
    
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.
codifyo/ts-generator-bundle
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