2012年4月12日木曜日

selenium 2.21はいろんな意味でやばい

2.20がでてしばらく音沙汰がなかったので、googleの天才方はサボっているのかなと思いきや、やはりいい仕事をしていたようです。というよりガッツリ変わりすぎ。

大きな変更点としてはFireFoxの安定化と、ついにきたsafari対応(マジデキターーー)
その他こまごまとしたものがいっぱい。

①今までと同じ通りWebDriver driver = new SafariDriver();でいける。
windowsでもmacでも起動するようなので、早くmacで試したい。

②FireFoxの安定化の要因はポートの制御にあるようで。中身を見ていると大きく仕様が変わっている。
まれにFireFoxで動作していると「portが既に使用されていて接続できません」的なエラーが出ていたので、これで直るかもしれない。やっほい。

③WebElementのclickメソッドについて。コメント部分だけが変わっていただけなので、なんともいえないが、
**********************************************************************************
2.20以前:webeleをクリックしてロードする場合、ページは待機する。そのときに何もやっちゃだめよ。
2.21から:クリックされた後、こちら側の操作をブロックするから、安全になったよ(とくにIEとFireFoxで)
**********************************************************************************
ということらしい。
英語が詳しい人、もうちょっといい感じに訳してくれたらうれしいです。
でも、IEやFireFoxでclickメソッドが実行されないから、sendkeys("\n")で代用してるんだよな、今回から動くのかな、、、

④FireFoxDriverにkillメソッド追加。強制プロセス停止用らしい。最悪これで切れということなのか。

⑤RemoteWebDriverのfindElementとfindElementsにsetFoundByというなぞメソッドが追加されている。どうやらエレメントの情報を文字列かするために内部的に保存しているようだ。
何かあったときのログ出力に便利ですね。

⑥WebDriverにmaximizeメソッドが追加。独自実装していた部分を置換できますな。こんな感じでできる

driver.manage().window().maximize();

後は
・ChromeDriverService(chromeを連続で起動して試験するにはこのクラスを使えば速度が早いですよというクラス)の起動ロジックの変更とログ出力の設定メソッドの追加
・AndroidDriverにgetStatusメソッド追加(なに取得すんのかわからないけど)
・IEドライバでよくわからないけどバグってるからコメントアウトするねっていう笑いを誘うメッセージ

ぐらい。

乗るしかないだろ、このビッグウェーブに。

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を使用すれば、もっといろいろできるかもしれない。