Weave 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

Sahi Client Laravel Package

behat/sahi-client

PHP client/driver for controlling the Sahi JS test automation tool remotely. Start a browser, navigate pages, find and interact with elements (links, headers, etc.), and stop the session—useful for browser automation and acceptance testing.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel Integration

  1. Install Sahi Server:

    • Download and configure Sahi on your machine or a dedicated server.
    • Ensure Sahi is running and accessible (default: http://localhost:9999).
  2. Install the Package:

    composer require behat/sahi-client:^1.2
    
  3. Basic Usage in Laravel: Create a test class (e.g., tests/Feature/SahiTest.php) and use the client:

    use Behat\SahiClient\Client;
    use Illuminate\Foundation\Testing\TestCase;
    
    class SahiTest extends TestCase
    {
        protected $sahiClient;
    
        protected function setUp(): void
        {
            $this->sahiClient = new Client();
            $this->sahiClient->start('firefox'); // Start Sahi with Firefox
        }
    
        public function testBasicInteraction()
        {
            $this->sahiClient->navigateTo('http://your-laravel-app.test');
            $link = $this->sahiClient->findLink('Login');
            $link->click();
            $this->assertEquals('Dashboard', $this->sahiClient->findHeader(1)->getText());
        }
    
        protected function tearDown(): void
        {
            $this->sahiClient->stop(); // Stop Sahi session
        }
    }
    
  4. Configure Laravel Testing: Add a setUp()/tearDown() method in your test case or use Laravel’s TestCase traits to manage the Sahi client lifecycle.


Implementation Patterns

Workflows for Daily Use

1. Test Setup and Teardown

Use Laravel’s TestCase to manage the Sahi client lifecycle:

use Behat\SahiClient\Client;
use Illuminate\Foundation\Testing\TestCase;

class SahiTestCase extends TestCase
{
    protected $sahi;

    protected function setUp(): void
    {
        $this->sahi = new Client();
        $this->sahi->start('firefox');
    }

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

2. Form Interaction

Submit forms and validate responses:

public function testFormSubmission()
{
    $this->sahi->navigateTo('/login');
    $this->sahi->type('username', 'testuser');
    $this->sahi->type('password', 'secret');
    $this->sahi->submitForm('login-form');
    $this->assertEquals('Welcome', $this->sahi->findHeader(1)->getText());
}

3. Dynamic Element Handling

Use Sahi’s dynamic locators to handle elements that change frequently:

public function testDynamicElement()
{
    $this->sahi->navigateTo('/dashboard');
    $element = $this->sahi->find('//div[contains(@class, "alert")]');
    $this->assertEquals('Success!', $element->getText());
}

4. Waiting for Conditions

Use Sahi’s wait method to handle AJAX-heavy applications:

public function testAJAXInteraction()
{
    $this->sahi->navigateTo('/ajax-page');
    $this->sahi->click('load-data');
    $result = $this->sahi->wait('//div[@id="result"]', 10);
    $this->assertNotNull($result);
}

5. Integration with Laravel Features

Combine Sahi tests with Laravel’s feature testing:

public function testLaravelFeatureWithSahi()
{
    $response = $this->get('/api/data');
    $this->assertEquals(200, $response->status());

    // Use Sahi to verify UI changes
    $this->sahi->navigateTo('/dashboard');
    $this->assertEquals('Updated', $this->sahi->findHeader(1)->getText());
}

Integration Tips

1. Service Provider for Global Access

Register the Sahi client as a Laravel service for easy access in tests:

// app/Providers/SahiServiceProvider.php
namespace App\Providers;

use Behat\SahiClient\Client;
use Illuminate\Support\ServiceProvider;

class SahiServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('sahi', function () {
            return new Client();
        });
    }
}

Then inject it into your tests:

use Illuminate\Support\Facades\App;

public function testWithServiceProvider()
{
    $sahi = App::make('sahi');
    $sahi->navigateTo('/');
    // ...
}

2. Custom Test Traits

Create reusable traits for common Sahi interactions:

// tests/Traits/SahiTrait.php
trait SahiTrait
{
    protected $sahi;

    public function setUpSahi()
    {
        $this->sahi = new Client();
        $this->sahi->start('firefox');
    }

    public function tearDownSahi()
    {
        $this->sahi->stop();
    }

    protected function sahiFind($locator)
    {
        return $this->sahi->find($locator);
    }
}

Use it in your test cases:

use Tests\Traits\SahiTrait;

class DashboardTest extends TestCase
{
    use SahiTrait;

    protected function setUp(): void
    {
        $this->setUpSahi();
    }

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

    public function testDashboard()
    {
        $this->sahi->navigateTo('/dashboard');
        $this->assertEquals('Dashboard', $this->sahiFind('h1')->getText());
    }
}

3. CI/CD Configuration

Ensure Sahi Server is available in your CI environment:

# .github/workflows/tests.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      sahi:
        image: sahipro/sahi:latest
        ports:
          - 9999:9999
    steps:
      - uses: actions/checkout@v2
      - run: composer install
      - run: php artisan test --env=testing

Gotchas and Tips

Pitfalls

  1. Sahi Server Dependency:

    • Issue: The package requires Sahi Server to be running separately, which adds complexity to your infrastructure.
    • Solution: Use Docker to containerize Sahi Server for consistency across environments.
      # Dockerfile.sahi
      FROM sahipro/sahi:latest
      EXPOSE 9999
      
  2. Browser Compatibility:

    • Issue: Sahi primarily supports Firefox, and compatibility with other browsers may vary.
    • Solution: Test thoroughly with your target browsers. If needed, use Sahi’s cross-browser features or consider alternatives like Playwright.
  3. Legacy PHP Support:

    • Issue: The package is designed for PHP 5.3–7.x and may not work seamlessly with PHP 8.x.
    • Solution: Run tests in a PHP 7.x environment or use a compatibility layer like php-compat to mitigate issues.
  4. Flaky Tests:

    • Issue: Sahi’s reliance on a visible browser instance can lead to flaky tests due to network latency or Sahi Server instability.
    • Solution:
      • Increase timeouts in your tests.
      • Use Sahi’s wait method to handle dynamic content.
      • Implement retry logic for critical tests.
  5. No Native Laravel Integration:

    • Issue: The package lacks built-in support for Laravel’s testing tools (e.g., Pest, PHPUnit listeners).
    • Solution: Create custom wrappers or service providers to bridge the gap (as shown in the implementation patterns).
  6. Error Handling:

    • Issue: Error messages from Sahi may not be user-friendly, making debugging difficult.
    • Solution: Wrap Sahi calls in try-catch blocks and log detailed error messages:
      try {
          $this->sahi->click('submit');
      } catch (\Exception $e) {
          $this->fail('Sahi error: ' . $e->getMessage());
      }
      

Debugging Tips

  1. Enable Sahi Logging: Configure Sahi Server to log detailed interactions for debugging:

    # sahi-user.properties
    log4j.logger.com.sahi=DEBUG
    
  2. Check Sahi Server Status: Verify Sahi Server is running and accessible:

    curl http://localhost:9999/_sahi/
    

    Should return a Sahi response (e.g., _sahi_ script status).

  3. **Inspect DOM with Sahi

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style