ヘッドレスChromeとヘッドレスFirefoxをphp-webdriverで試す

投稿日:

恋は永遠 愛はひとつ
(銀杏Boyz 恋は永遠)

ここらへんに得も言われぬ感情がそっと隠されているような気がする今日このごろです。

というわけでヘッドレスChromeヘッドレスFirefoxをphp-webdriverで試してみました。
※ php-webdriverはPHPでSelenium WebDriverをラップしているライブラリ(Facebook製)です

参考にした記事はこちらです。

ヘッドレスChromeは結構前からざわざわしていた気がするけどFirefoxもヘッドレス出たんですね。
では、いってみましょー。

前提条件

  • java
  • selenium-server-standalone
    • 現時点で最新のバージョン(3.7.1.jar)を用意してください
  • facebook/php-webdriver: A php client for webdriver.
  • chromedriver
    • 現時点で最新のバージョン(chromedriver 2.33)を用意してください
  • geckodriver
    • 現時点で最新のバージョン(geckodriver v0.19.1)を用意してください

が必要です。

ヘッドレスChrome

ソース

百聞は一見にしかずなのでソースから。

  • example_chrome_headless.php
require_once 'vendor/autoload.php';

use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;

// java -Dwebdriver.chrome.driver=$CHROME_DRIVER_PATH -jar selenium-server-standalone-3.7.1.jar

/*
 |------------------------------------------------------------------------------
 | ChromeOptions
 |------------------------------------------------------------------------------
 */
$options = new ChromeOptions();

// headless
$options->addArguments(['--headless']);

// change window size
// set window-size=width,height
$width = 414;
$height = 736;
$options->addArguments(["window-size={$width},{$height}"]);

// UserAgent
$ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
$options->addArguments(['--user-agent=' . $ua]);

/*
 |------------------------------------------------------------------------------
 | DesiredCapabilities
 |------------------------------------------------------------------------------
 */
$capabilities = DesiredCapabilities::chrome();

/*
 |------------------------------------------------------------------------------
 | Set ChromeOptions to DesiredCapabilities
 |------------------------------------------------------------------------------
 */
$capabilities->setCapability(ChromeOptions::CAPABILITY, $options);

/*
 |------------------------------------------------------------------------------
 | Create WebDriver
 |------------------------------------------------------------------------------
 */
$driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities);

/*
 |------------------------------------------------------------------------------
 | test
 |------------------------------------------------------------------------------
 */

// URL
$url = 'https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr';

// 指定URLへ遷移 (Google)
$driver->get($url);

// 検索Box
$findElement = $driver->findElement(WebDriverBy::name('q'));
// 検索Boxにキーワードを入力して
$findElement->sendKeys('Hello');
// 検索実行
$findElement->submit();

// 検索結果画面のタイトルが 'Hello - Google Search' になるまで10秒間待機する
// 指定したタイトルにならずに10秒以上経ったら
// 'Facebook\WebDriver\Exception\TimeOutException' がthrowされる
$driver->wait(10)->until(
	WebDriverExpectedCondition::titleIs('Hello - Google Search')
);

// Hello - Google Search というタイトルが取得できることを確認する
if ($driver->getTitle() !== 'Hello - Google Search') {
	throw new Exception('fail');
}

// ブラウザを閉じる
$driver->close();

試す

上記ソースを適当に用意したら以下コマンドでseleniumを起動させます。

$ java -Dwebdriver.chrome.driver=$CHROME_DRIVER_PATH -jar selenium-server-standalone-3.7.1.jar

※-Dwebdriver.chrome.driver= のところはPATHが通っていれば設定しなくても大丈夫です

起動させたら、実行してみます。

$ php example_chrome_headless.php

どうでしょうか、ヘッドレスで動いたと思います。

ポイント

こいつのポイントは、

// headless
$options->addArguments(['--headless']);

の箇所です。ここでヘッドレスモードを指定します。
※こいつをコメントアウトすればブラウザが立ち上がると思います

ヘッドレスFirefox

では続いてヘッドレスFirefoxを試してみましょー。

ソース

百聞は一見にしか(ry

  • example_firefox_headless.php
require_once 'vendor/autoload.php';

use Facebook\WebDriver\Firefox\FirefoxDriver;
use Facebook\WebDriver\Firefox\FirefoxProfile;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverDimension;
use Facebook\WebDriver\WebDriverExpectedCondition;

// java -Dwebdriver.gecko.driver=$FIREFOX_DRIVER_PATH -jar selenium-server-standalone-3.7.1.jar -enablePassThrough false

/*
 |------------------------------------------------------------------------------
 | FirefoxProfile
 |------------------------------------------------------------------------------
 */
$profile = new FirefoxProfile();

// UserAgent
$ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
$profile->setPreference('general.useragent.override', $ua);

/*
 |------------------------------------------------------------------------------
 | DesiredCapabilities
 |------------------------------------------------------------------------------
 */
$capabilities = DesiredCapabilities::firefox();

// headless
$capabilities->setCapability('moz:firefoxOptions' , ['args' => '-headless']);

/*
 |------------------------------------------------------------------------------
 | Set FirefoxProfile to DesiredCapabilities
 |------------------------------------------------------------------------------
 */
$capabilities->setCapability(FirefoxDriver::PROFILE, $profile);

/*
 |------------------------------------------------------------------------------
 | Create WebDriver
 |------------------------------------------------------------------------------
 */
$driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities);

// change window size
$width = 414;
$height = 736;
$dimension = new WebDriverDimension($width, $height);
$driver->manage()->window()->setSize($dimension);

/*
 |------------------------------------------------------------------------------
 | test
 |------------------------------------------------------------------------------
 */

// URL
$url = 'https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr';

// 指定URLへ遷移 (Google)
$driver->get($url);

// 検索Box
$findElement = $driver->findElement(WebDriverBy::name('q'));
// 検索Boxにキーワードを入力して
$findElement->sendKeys('Hello');
// 検索実行
$findElement->submit();

// 検索結果画面のタイトルが 'Hello - Google Search' になるまで10秒間待機する
// 指定したタイトルにならずに10秒以上経ったら
// 'Facebook\WebDriver\Exception\TimeOutException' がthrowされる
$driver->wait(10)->until(
	WebDriverExpectedCondition::titleIs('Hello - Google Search')
);

// Hello - Google Search というタイトルが取得できることを確認する
if ($driver->getTitle() !== 'Hello - Google Search') {
	throw new Exception('fail');
}

// ブラウザを閉じる
$driver->close();

試す

上記ソースを適当に用意したら以下コマンドでseleniumを起動させます。

$ java -Dwebdriver.gecko.driver=$FIREFOX_DRIVER_PATH -jar selenium-server-standalone-3.7.1.jar -enablePassThrough false

※-Dwebdriver.gecko.driver= のところはPATHが通っていれば設定しなくても大丈夫です
※-enablePassThrough false はつけてください

-enablePassThrough false をつけないと

Fatal error: Uncaught exception 'Facebook\WebDriver\Exception\UnrecognizedExceptio
nException' with message 'args is not an array
Build info: version: '3.7.1', revision: '8a0099a', time: '2017-11-06T21:07:36.161Z
'

こんな感じで怒られます。理由は

When using Selenium server 3.5 and newer with some remote end clients (eg. Firefox with Geckodriver), you MUST disable so called “pass-through” mode, so that remote browser’s protocol is translated to the protocol supported by php-webdriver (see issue #469):

java -jar selenium-server-standalone-#.jar -enablePassThrough false

W3C WebDriver protocol support · Issue #469 · facebook/php-webdriver
だそうです。

起動させたら、実行してみます。

$ php example_firefox_headless.php

どうでしょうか、ヘッドレスで動いたと思います。

ポイント

こいつのポイントは、

// headless
$capabilities->setCapability('moz:firefoxOptions' , ['args' => '-headless']);

の箇所です。ここでヘッドレスモードを指定します。
※こいつをコメントアウトすればブラウザが立ち上がると思います
※参考: https://github.com/mozilla/geckodriver#capabilities-example

まとめ

どうでしょうかphp-webdriverを使って簡単にヘッドレスモードを試せたと思います。
これでChromeとFirefoxに関しては裏でこっそりテストを回すことが可能になりました。めでたしめでたし。

おまけ

https://github.com/shimabox/screru
以前書いたこちらも、上記のヘッドレスモードに対応してみましたのでもしよかったら使ってみてください。

上記内容で動作しないケースがあったら

こちらの記事を参考にして頂けると解決するかもしれません。
php-webdriverのラッパーライブラリ”screru”のバージョンをあげた – Shimabox Blog

作成者: shimabox

Web系のプログラマをやっています。 なるべく楽しく生きていきたい。

2件のコメント

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください