am 1. Oktober 2009
Heute will ich mal erklären wie ich mit PHP (und natürlich noch weiteren Hilfsmitteln) meinen Browser fernsteuern kann. Das kann ganz nützlich sein, wenn man Workflows automatisieren will und dies dann mit PHP triggern möchte. Euch fallen bestimmt noch andere Schweinereien ein, die man damit machen kann. Wir wollen hier und heute nur die technische Grundlage legen.
Ich habe ja gerade schon angekündigt, dass wir noch außer PHP andere Tools benötigen. Natürlich ist Selenium, die Browser-Allzweckwaffe eines davon. PHPUnit (zumindest Teile davon) werden wir auch noch verwenden. Zuerst mal brauchen wir eine Instanz des Selenium Remote Control auf einem PC installiert, der den Browser beheimatet, den wir fernsteuern wollen. Als nächstes schnappen wir uns das PHPUnit Paket und da eigentlich nur den SeleniumDriver (sollte bei neueren PHPUnit Versionen vorhanden sein). Jetzt kann es eigentlich schon losgehen. Wir brauchen jetzt nur eine Instanz des Treibers, diesen müssen wir noch konfigurieren und dann können wir schon loslegen und das in fast der ganzen Mächtigkeit wie es Selenium kann.
$selenium = new PHPUnit_Extensions_SeleniumTestCase_Driver( );
$selenium->setBrowser( '*firefox' );
$selenium->setHost( '<IP des Selenium RC>' );
$selenium->setBrowserUrl( 'http://www.example.com' );
$selenium->start( );
...
$selenium->stop( );
Da müsste eigentlich schon alles sein. Die drei Punkte können wir jetzt ersetzen mit den Dingen die wir tatsächlich tun wollen. Das einfachste wäre zum Beispiel eine Seite aufzumachen, auf einen Link zu klicken und danach einen Screenshot zu machen. Das würde dann zum Beispiel so aussehen:
$selenium->open( '/index.php' );
$selenium->click( 'link=Impressum' );
$selenium->captureEntirePageScreenshot( 'screenshot.png' );
Wenn ihr auch nicht sicher seid, welche Befehle Selenium so beherrscht, dann schaut euch entweder mal die Treiberklasse an oder spiel ein wenig mit dem Selenium Firefox Plugin rum. Wenn ihr dort nämlich einen Export nach PHP macht, dann habt ihr schon die meisten Befehle gesehen. In den meisten der Fälle ist es eh nur ein 1:1 Mapping.
Jetzt muss ich erstmal in Deckung gehen, bevor ich weiterschreibe … einen Moment … so in Sicherheit. Und zwar habe ich den Code, den ihr oben findet noch nicht getestet, da ich auf dem System, dass ich gerade verwende, noch eine alter Version von PHPUnit drauf habe und das im Moment auch nicht ändern kann. Vielleicht spielt heute noch ein wenig Faulheit rein, aber auf jeden Fall gebe ich keine Garantie, dass alles was ich als Code stehen habe auch klappt. Wer Interesse an dem alten PHPUnit Ansatz hat, dem schicke ich natürlich gerne auch den alten (funktionierenden) Code zu. Aber eigentlich bin ich mir ziemlich sicher, dass es klappen wird, denn außer der Auslagerung des Treibers hat sich nicht viel geändert.
Ach ja, versprochen, dass dieses blinde Programmieren nicht häufig vorkommen wird.