2012年3月27日火曜日

WebDriverとプロキシ

プロキシを通してWebDriverを起動して自動でWebモジュールを起動する方法の覚書

String PROXY = "localhost:8080";

【IE】

DesiredCapabilities capabilities = new DesiredCapabilities();
Proxy proxy = new Proxy();
proxy.setHttpProxy(PROXY);
capabilities.setCapability(CapabilityType.PROXY, proxy);

WebDriver driver = new InternetExplorerDriver(capabilities);

【Chrome】
ChromeOptions option = new ChromeOptions();
option.addArguments("--proxy-server=http://" + PROXY);
WebDriver driver = new ChromeDriver(option);

ChromeOptionsのaddArgumentsはその名前の通りchorome起動時の引数がそのまま使用可能
だから、
http://yuichi.tea-nifty.com/blog/2008/12/googlechrome-c0.html
とか
http://chrome.half-moon.org/43.html
とかがそのまま利用できる。

【FireFox】
FirefoxProfile profile = new FirefoxProfile();

Proxy proxy = new Proxy();
proxy.setHttpProxy(PROXY);
profile.setProxyPreferences(proxy);

WebDriver driver = new FireFoxDriver(profile);

か、もっと正確な設定をしたければ、
https://developer.mozilla.org/ja/Mozilla_Networking_Preferences

profile.setPreference("network.proxy.type", 1);
profile.setPreference("network.proxy.http", "localhost");
profile.setPreference("network.proxy.http_port", 3128);
とかして設定するのもよい。
(もしくはProxyのsetProxyTypeメソッドを使うか)


こんな感じでOK。わざわざ起動前に設定を変更しなくても大丈夫。
これと組み合わせて、jscoverageと組み合わせ、カバレッジを取得したりできる。

2012年3月26日月曜日

FireFoxの機動設定

FirefoxProfileという便利なクラスが存在する。

使い方は

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 0);
driver = new FirefoxDriver(profile);

こんな感じ。起動時の設定を行うことが出来る。

で、その設定内容は
https://developer.mozilla.org/ja/Download_Manager_preferences
とか
general.useragent.override
とか、そのまま利用できるみたい。

便利ですね。ダウンロードファイルの比較も可能なんですね。

chromedriver.exeへのパス

webdriverでchromeを起動する際

System.setProperty("webdriver.chrome.driver","chromedriver.exeのパス");


と記述しなければならないのは周知の事実だが、この値は実は定数がきられている。

ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY

いやはや、お恥ずかしい限り。

2012年3月23日金曜日

ctrlやshift、altとの同時押し

ActionsクラスにkeyDown等のメソッドがあるのだが、ctrlボタンを押下するように実装すると
『そんなメソッドねーよ』といわれて怒られる。思いのほか理不尽。

で、長い間実装方法が不明だったのだが、今しがた判明。

例)ctrl+vを押下する場合
driver.findElement(By.id("text_id")).sendKeys(Keys.CONTROL + "v");

同様にshiftやaltも実装できる。
やっほい。

2012年3月6日火曜日

executeScriptの引数

(公式のまんまだけど、、、覚書として)

((JavascriptExecutor)driver).executeScriptには引数をいくつも指定することができる。



 List<WebElement> labels = driver.findElements(By.tagName("label"));
List<WebElement> inputs = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);

こんな感じ。
ちょうどjavascriptのargumentsのように引数を設定出来る。
戻ってきた値を WebElementに変換もできる。まじやばい。

webdriverでのalert検証方法

Alert al = driver.switchTo().alert();
と記述すると画面上にalert、及びconfirm等が表示されている場合にオブジェクトを取得できる。

alert、及びconfirmが表示されていない場合、NoAlertPresentExceptionが発生する(chromeの場合はchromedriver.exeを使用しているため、WebDriverExceptionも発生する)ため、例外処理を行わなければいけない。

また、chromeの場合は alertが表示されていないのに、driver.switchTo().alert()を実行すると『No modal dialog is showing』とSystem.errに出力されてしまう。(非常に不細工)
これもchromedriver.exeを使用しているためである。

なので、これが嫌なら一旦
Selenium selenium=new WebDriverBackedSelenium(driver,baseUrl);
selenium.isAlertPresent()
と実行し、alertが表示されているかどうか確認してから、driver.switchTo().alert()を実行すればいい。

ただし、新しめのブラウザではSeleniumクラスはまともに動作しない可能性があるので注意。
また、selenium2 ver2.20から実行出来るようになった
Alert al = (new WebDriverWait(driver, time)).until(ExpectedConditions.alertIsPresent())
という方法は、FireFoxなどで設定した秒数(time)分だけ待機してくれない現象がある(?)ので
要注意。
selenium.isAlertPresent()で確認してから実行するが吉、かと思いきや、alertが表示されている時に
isAlertPresent を実行すると、alert表示されてるからjavascript実行出来ないよ的な
SeleniumExceptionが発生する。なんだそりゃ。

org.openqa.selenium.internal.seleniumemulation.AlertOverrideを使用すれば、もっといろいろできるかもしれない。

webdriverを使っての実行環境取得

selenium-webdriverを使った時の実行環境情報
・OS
・ブラウザ種別
・ブラウザバージョン
・プロキシの設定
etc...
を取得する方法がある。

いままで出来るんじゃないかなぁとずっと思っていたけど、わからなくて
独自実装(navigator.userAgentとかjavascriptで投げてた)して取得していたのが
あほみたいになる。

こんな感じ
Capabilities cap = ((RemoteWebDriver) wd).getCapabilities();
でCapabilitiesクラスを取得するあとは
cap.getBrowserName() でブラウザ種別
cap.getVersion() でブラウザバージョン
cap.isJavascriptEnabled() でjavascript有効確認
内部にマップも持っていて、プロキシの設定などはそこに入っている模様。
そのあたりは
 org.openqa.selenium.remote.CapabilityTypeの変数呼び出し先を見たら詳しくわかる。