# End-to-End Test

Automatisierte End-to-End Tests sollen ganze Aktionen des Endusers simulieren und sind somit die Testart der geringsten Abstraktionsebene.
Sie können genutzt werden um ganze Workflows zu testen, wie z.B. Einkauf eines Produkts im Onlineshop.

# Laravel Dusk

Laravel bietet auch für End-to-End Tests ein Tool, namens Dusk (opens new window). Dies nutzt einen (headless) Browser unter der Haube. Es können Chrome und Firefox genutzt werden (opens new window).

# Dusk Chrome Plugin

Um die Test noch einfacher anfertigen zu können, gibt es ein Browserplugin für Chrome (opens new window), mit welchem man Aktionen aufzeichnen und sich anschließend als Dusk-Code ausgeben lassen kann.

# Magic Test for Laravel (ausgesetzt)

Als eine Alternative zu dem Dusk Chrome Plugin kann auch das Package Magic Test for Laravel (opens new window) genutzt werden.

⚠️ Da Magic Test momentan noch nicht zuverlässig funktioniert, wird es vorerst nicht genutzt.

# Debug Dusk Tests

Laravel Dusk ist ein mächtiges Tool für Browser-Testing, kann aber manchmal frustrierend zu debuggen sein. Dieser Guide hilft dir dabei, die häufigsten Probleme zu identifizieren und zu lösen.

# Allgemeine Debugging-Strategien

# 1. Screenshots bei Fehlern aktivieren

Füge automatische Screenshots bei Test-Fehlern hinzu:

// In deinem DuskTestCase oder einzelnen Tests
protected function tearDown(): void
{
    if ($this->hasFailed()) {
    $this->browse(function (Browser $browser) {
    $browser->screenshot('failure-' . date('Y-m-d-H-i-s'));
    });
    }
    
    parent::tearDown();
}

# 2. Browser-Console-Logs abrufen

// Console-Logs ausgeben
$browser->driver->manage()->getLog('browser');

// In deinem Test verwenden
$logs = $browser->driver->manage()->getLog('browser');
foreach ($logs as $log) {
    echo $log['message'] . "\n";
}

# 3. Sichtbare Browser-Session

Teste mit sichtbarem Browser (nicht Headless):

// config/dusk.php oder DuskTestCase
$options = (new ChromeOptions)->addArguments([
    '--disable-gpu',
    '--no-sandbox',
    '--window-size=1920,1080',
    // '--headless', // Entferne diese Zeile
]);

# Dusk - Häufige Probleme und Lösungen

# Element nicht gefunden

Problem: Facebook\WebDriver\Exception\NoSuchElementException

Lösungsansätze:

// 1. Längere Wartezeiten
$browser->waitFor('@submit-button', 10);

// 2. Warten bis Element sichtbar ist
$browser->waitUntilVisible('@modal');

// 3. Auf Text warten
$browser->waitForText('Success message');

// 4. JavaScript-Rendering abwarten
$browser->pause(2000);

// 5. Explizite DOM-Checks
$browser->whenAvailable('@dynamic-content', function ($browser) {
    $browser->click('@action-button');
});

# Element ist nicht interaktiv

Problem: Element is not clickable at point

Lösungen:

// 1. Scrollen zum Element
$browser->scrollTo('@element');

// 2. JavaScript-Click verwenden
$browser->script('document.querySelector("[dusk=\'submit-button\']").click()');

// 3. Warten bis Element klickbar ist
$browser->waitUntilEnabled('@submit-button');

// 4. Modals/Overlays prüfen
$browser->waitUntilMissing('@loading-overlay');

# Timing-Probleme

Problem: Tests sind instabil und schlagen manchmal fehl

Lösungen:

// 1. Implizite Waits erhöhen
$browser->driver->manage()->timeouts()->implicitlyWait(10);

// 2. Auf AJAX-Requests warten
$browser->waitForReload();

// 3. Auf CSS-Animationen warten
$browser->waitFor('.fade-in.show');

// 4. Custom Wait Conditions
$browser->waitUsing(5, 100, function () use ($browser) {
    return $browser->element('@status')->getText() === 'Complete';
});

# Authentifizierung-Probleme

Problem: Login funktioniert nicht oder Session wird verloren

Lösungen:

// 1. Expliziten Login verwenden
$browser->loginAs(User::factory()->create());

// 2. Cookie-basierte Auth
$browser->visit('/login')
    ->type('email', 'user@example.com')
    ->type('password', 'password')
    ->press('Login')
    ->waitForLocation('/dashboard');

// 3. Session-Persistenz prüfen
$browser->assertAuthenticatedAs($user);

# Datenbankzustand-Probleme

Problem: Tests beeinflussen sich gegenseitig

Lösungen:

// 1. DatabaseTransactions verwenden
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends DuskTestCase
{
    use DatabaseTransactions;
}

// 2. Explizite Database-Resets
protected function setUp(): void
{
    parent::setUp();
    $this->artisan('migrate:refresh');
}

// 3. Isolierte Test-Daten
$browser->visit('/users/' . User::factory()->create()->id);

# Erweiterte Debugging-Techniken

# Browser-Entwicklertools nutzen

// Browser pausieren für manuelle Inspektion
$browser->pause();

// Breakpoint mit Ausgabe
$browser->dump(); // HTML-Quellcode
$browser->ddConsole(); // Console-Logs

# Custom Debugging-Methoden

// In deiner DuskTestCase Klasse
protected function debugElement(Browser $browser, string $selector): void
{
    echo "=== Debugging Element: {$selector} ===\n";
    
    // Element-Existenz prüfen
    $exists = $browser->element($selector) !== null;
    echo "Element exists: " . ($exists ? 'Yes' : 'No') . "\n";
    
    if ($exists) {
    // Element-Eigenschaften
    $element = $browser->element($selector);
    echo "Visible: " . ($element->isDisplayed() ? 'Yes' : 'No') . "\n";
    echo "Enabled: " . ($element->isEnabled() ? 'Yes' : 'No') . "\n";
    echo "Text: " . $element->getText() . "\n";
    echo "HTML: " . $element->getDomProperty('outerHTML') . "\n";
    }
    
    echo "=== End Debug ===\n";
}

# Logging konfigurieren

// config/logging.php - Dusk Channel hinzufügen
'channels' => [
    'dusk' => [
    'driver' => 'daily',
    'path' => storage_path('logs/dusk.log'),
    'level' => 'debug',
    ],
],

// In Tests verwenden
Log::channel('dusk')->info('Test step completed', [
    'url' => $browser->driver->getCurrentURL(),
    'title' => $browser->driver->getTitle(),
]);

# Performance-Optimierung

# Browser-Konfiguration optimieren

// config/dusk.php
$options = (new ChromeOptions)->addArguments([
    '--no-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
    '--disable-web-security',
    '--disable-features=VizDisplayCompositor',
    '--disable-extensions',
    '--disable-plugins',
    '--disable-images', // Für schnellere Tests
    '--window-size=1920,1080',
]);

# Parallele Test-Ausführung

# Tests parallel ausführen
php artisan dusk --parallel

# Anzahl Prozesse definieren
php artisan dusk --parallel --processes=4

# Troubleshooting-Checkliste

Wenn deine Dusk-Tests fehlschlagen, arbeite diese Checkliste ab:

  • [ ] Browser-Version kompatibel? ChromeDriver Version prüfen
  • [ ] Selektoren korrekt? Dusk-Selektoren mit @ verwenden
  • [ ] Timing-Probleme? waitFor() statt pause() verwenden
  • [ ] JavaScript-Errors? Browser-Console prüfen
  • [ ] Authentifizierung? Login-Status validieren
  • [ ] Datenbankzustand? Transaktionen oder Refresh prüfen
  • [ ] Screenshots gemacht? Visueller Debugging-Check
  • [ ] Headless-Modus? Temporär deaktivieren für Debugging
  • [ ] Network-Requests? AJAX-Calls abwarten
  • [ ] CSS-Animationen? Vollständig abgeschlossen?

# Nützliche Dusk-Methoden für Debugging

// Informationen sammeln
$browser->dump();    // HTML ausgeben
$browser->ddConsole();      // Console-Logs ausgeben
$browser->screenshot('debug');       // Screenshot machen
$browser->pause();      // Browser pausieren

// Element-Debugging
$browser->scrollTo('@element');     // Zu Element scrollen
$browser->mouseover('@element');    // Hover-Effekte testen
$browser->rightClick('@element');   // Rechtsklick-Menüs

// Status prüfen
$browser->assertSee('Expected text');
$browser->assertDontSee('Unexpected text');
$browser->assertPathIs('/expected/path');
$browser->assertRouteIs('route.name');

# Fazit

Das Debuggen von Laravel Dusk-Tests erfordert Geduld und systematisches Vorgehen. Die wichtigsten Prinzipien:

  1. Verwende explizite Waits statt fixer Pausen
  2. Sammle Debugging-Informationen (Screenshots, Logs, Console)
  3. Teste schrittweise mit kleineren, fokussierten Tests
  4. Nutze die richtigen Selektoren und Dusk-Attribute
  5. Verstehe das Timing deiner Anwendung

Mit diesen Strategien wirst du die meisten Dusk-Probleme erfolgreich lösen können.

# übergeordnetes Thema

2.7 Tests

Last Updated: 9/25/2025, 2:13:26 PM