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.
Install Sahi Server:
http://localhost:9999).Install the Package:
composer require behat/sahi-client:^1.2
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
}
}
Configure Laravel Testing:
Add a setUp()/tearDown() method in your test case or use Laravel’s TestCase traits to manage the Sahi client lifecycle.
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();
}
}
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());
}
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());
}
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);
}
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());
}
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('/');
// ...
}
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());
}
}
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
Sahi Server Dependency:
# Dockerfile.sahi
FROM sahipro/sahi:latest
EXPOSE 9999
Browser Compatibility:
Legacy PHP Support:
php-compat to mitigate issues.Flaky Tests:
wait method to handle dynamic content.No Native Laravel Integration:
Error Handling:
try {
$this->sahi->click('submit');
} catch (\Exception $e) {
$this->fail('Sahi error: ' . $e->getMessage());
}
Enable Sahi Logging: Configure Sahi Server to log detailed interactions for debugging:
# sahi-user.properties
log4j.logger.com.sahi=DEBUG
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).
**Inspect DOM with Sahi
How can I help you explore Laravel packages today?