8

PHPを使用してSelenium WebDriverにファイルをリモートでアップロードする方法について、StackOverflow(およびその他のリソース)を検索してきました。私はこれを読んだhttp://saucelabs.com/blog/index.php/2012/03/selenium-tips-uploading-files-in-remote-webdriver/、そして「setFileDetector」を使用する必要があると述べていますメソッドを使用して、使用している WebDriver ライブラリの動作を変更します。

Ruby または Java を使用している場合、これは正常に機能するはずです。一方、ほとんどの PHP フレームワークにはこのメソッドがありません。

PHPでこれを行う方法を誰か教えてもらえますか? 具体的には、phpwebdriver ライブラリhttp://code.google.com/p/php-webdriver-bindings/を使用しています。

4

1 に答える 1

10

/session/<sessionId>/fileファイルをアップロードするための JsonWireProtocol は、SauceLabs.com ブログ投稿 ( https://saucelabs.com/jobs/1a408cf60af0601f49052f66fa37812c/selenium-server.log )の生ログをチェックアウトすることで判断できました。この関数を作成して、php-webdriver-bindingsライブラリに追加しました。

/**
 * 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;
}

これをWebDriver.phpファイルに追加します。

使用するには、次のようにします。

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

これに対する答えを探すのに 3 時間ほど費やした他の開発者に、これが役立つことを願っています。

アップデート:

このエラーが発生したため、これを変更する必要がありました。

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

これをここに置くと、Google の結果が得られることを願っています (Google でエラー メッセージを検索してみましたが、Google Code のソース コードへの参照しか見つかりませんでした)。

この問題を解決するには、送信するファイルを実際に圧縮する必要があると推測できました。そこで、PHP のZipArchiveライブラリを使用するようにソース コードを拡張しました。記録のために古いコードを一番上に置いておきますが、ここでは新しいコードを使用してください。

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);
}

更新: $zip->addFile() メソッドで 2 つのパラメーターを設定する必要があることが判明しました。変更を反映するために上記のコードを編集しました。

于 2012-05-12T00:20:42.120 に答える