2012-05-11 17 views
6

Ho cercato in giro StackOverflow (e altre risorse) su come caricare i file su Selenium WebDriver con PHP in remoto. Ho letto questo http://saucelabs.com/blog/index.php/2012/03/selenium-tips-uploading-files-in-remote-webdriver/ e si dice che è necessario utilizzare un metodo "setFileDetector" in qualche modo per cambiare il modo in cui funziona la libreria di WebDriver che si sta utilizzando.Caricamento di file da remoto su Selenium WebDriver utilizzando PHP

Questo dovrebbe funzionare bene se stavo usando Ruby o Java. La maggior parte dei framework PHP, d'altra parte, non ha questo metodo.

Qualcuno può dirmi come farlo in PHP? In particolare, sto utilizzando la libreria phpwebdriver http://code.google.com/p/php-webdriver-bindings/

risposta

9

mi è stato in grado di determinare che il JsonWireProtocol per caricare un file sarebbe /session/<sessionId>/file controllando il registro crudo sul post SauceLabs.com blog (https://saucelabs.com/jobs/1a408cf60af0601f49052f66fa37812c/selenium-server.log) in modo, con questo, mi creato questa funzione per aggiungere-in al php-WebDriver-binding libreria:

/** 
* Send a file to your Remote WebDriver server 
* This will return the local URL of the file you uploaded, which will then 
* let you use sendKeys in file input elements 
* @params String $value - a local or remote file to send 
* @return String $resopnseValue - the local directory where the file resides on the remote server 
*/ 
public function sendFile($value) { 
    $file = @file_get_contents($value); 

    if($file === false) { 
     return false; 
    } 

    $file = base64_encode($file); 
    $request = $this->requestURL . "/file"; 
    $session = $this->curlInit($request); 
    $args = array('file' => $file); 
    $postargs = json_encode($args); 
    $this->preparePOST($session, $postargs); 
    $response = trim(curl_exec($session)); 

    $responseValue = $this->extractValueFromJsonResponse($response); 
    return $responseValue; 
} 

aggiungere questo al file WebDriver.php.

da usare, basta fare qualcosa di simile:

... 
$file_location = $webdriver->sendFile('http://test.com/some/file.zip'); 
$file_input = $webdriver->findElementBy(LocatorStrategy::id, 'uploadfile'); 
$file_input->sendKeys(array($file_location)); 

Spero che questo vi aiuterà altri sviluppatori, ha trascorso come 3 ore alla ricerca di una risposta a questo.

Aggiornamento:

ho dovuto cambiare questo a causa di questo errore:

Expected there to be only 1 file. There were: 0 

Speriamo che mettere questo qui sarebbe ottenere risultati di Google (Ho provato a cercare per il messaggio di errore su Google e gli unici risultati potrebbe trovare i riferimenti al codice sorgente su Google Code).

Per risolvere questo problema, sono stato in grado di dedurre che il file inviato in realtà deve essere zippato. Quindi ho aumentato il codice sorgente per utilizzare la libreria ZipArchive di PHP. Terrò il vecchio codice in cima per la tenuta dei registri, ma si prega di utilizzare il nuovo codice qui:

public function sendFile($value, $file_extension = '') 
{ 
    $zip = new ZipArchive(); 

    $filename_hash = sha1(time().$value); 

    $zip_filename = "{$filename_hash}_zip.zip"; 
    if($zip->open($zip_filename, ZIPARCHIVE::CREATE) === false) { 
     echo 'WebDriver sendFile $zip->open failed\n'; 
     return false; 
    } 

    $file_data = @file_get_contents($value); 
    if($file_data === false) { 
     throw new Exception('WebDriver sendFile file_get_contents failed'); 
    } 

    $filename = "{$filename_hash}.{$file_extension}"; 
    if(@file_put_contents($filename, $file_data) === false) { 
     throw new Exception('WebDriver sendFile file_put_contents failed'); 
    } 

    $zip->addFile($filename, "{$filename_hash}.{$file_extension}"); 
    $zip->close(); 

    $zip_file = @file_get_contents($zip_filename); 
    if($zip_file === false) { 
     throw new Exception('WebDriver sendFile file_get_contents for $zip_file failed'); 
    } 

    $file = base64_encode($zip_file); 

    $request = $this->requestURL . "/file"; 
    $session = $this->curlInit($request); 
    $args = array('file' => $file); 
    $postargs = json_encode($args); 
    $this->preparePOST($session, $postargs); 
    $response = trim(curl_exec($session)); 

    return $this->extractValueFromJsonResponse($response); 
} 

Aggiornamento: scopre, è necessario impostare due parametri sulla $ archivio zip> addfile() metodo. Modificato il codice sopra riportato per riflettere le modifiche.

+0

grazie. TANTO per questo. Non è dove nella pagina JSON Wire Protocol (Command + F non ha ottenuto nulla) –

+0

@ K-RAN, la funzione non fa ufficialmente parte di JSONWireProtocol. La soluzione è una sorta di reverse engineering da come le associazioni linguistiche ufficiali lo fanno. È un peccato, no? – David

+0

Questo codice può essere utilizzato per applicare patch/unione ai binding PHP. C'è il numero 35 per questo nella pagina del progetto. Mi unisco quando ci arrivo. – David

Problemi correlati