2012年11月24日土曜日

seleniumの2.26になってかわったこと その2



事前に検証することは大事である。ちゃんとやっておけば
「ワンセグ見れる5万のタブレットを買ったものの、
 お風呂までワンセグの電波が届かない。
こんなことならNEXUS買っときゃよかった」
なんてことにはならない。


2.26で出来るようになったことの続き

1.Platformクラスのwindows8対応
 OSの情報を取得できるPlatformクラスがWindows8に対応した。
 [使い方]
        for(String inf:Platform.getCurrent().getPartOfOsName()){
            System.out.println(inf);
        }
        Windows8環境上記メソッドを実行すると
     
      Windows Server 2012
      windows 8
      win8
   
    って出力される

2.プロキシ自動設定、https、socksプロキシに対応
 
 [使い方]
        Proxy proxy = new Proxy();
        FirefoxProfile profile = new FirefoxProfile();

    //自動設定の場合
        proxy.setProxyAutoconfigUrl("http://192.168.0.10/proxy.pac");

   //socksの場合
        proxy.setSocksProxy("hostname.com:1234")
             .setSocksUsername("user")
             .setSocksPassword("pass");

    //httpsの場合
        proxy.setHttpsProxy("hostname:1234");

        profile.setProxyPreferences(proxy);
        WebDriver driver = new FirefoxDriver(profile);

3.Colorクラスでカラーを文字で指定可能に
 [使い方]
        Color clr = Color.fromString("SILVER");
        System.out.println(clr.asRgb());
    指定できる文字はColorsクラスが保持している

その他
・driverのCapabilitiesを使用するコンストラクタのDeprecatedが消えた、なぜに

seleniumの2.26になってかわったこと その1

 
3DSドラゴンクエスト7に求めること
・職業レベルがMAXになって、早く転職したいのに、急に世界から隔離されて、
 ダーマ神殿に行けなくなるタイミングがある。
・マリベルがいい感じに賢者に転職できた頃に強制離脱するシナオリオ
・操作キャラクターが5人いるのに、つれて歩けるのが4人まで。
 中途半端なので一人減らすか、馬車などの一緒に連れていく方法を増やしてほしい。
・特技『怒涛の羊』の威力はそのままで。

それはさておき、去年まで2回/月だったseleniumのバージョンアップが
2、3ヶ月に1回になった。
ただし、いまだにIE対応は躓くところが多いのか、IEDriverのみ
バージョンアップを繰り返すことがおおい。
コツとしては、新バージョンのselenium動作検証あと、1、2週間まって、
IEDriverの世間での安定性を確認すればいいかなと。

2.26で出来るようになったことを一通り。

1.Architectureクラス
 新規追加クラス。クライアントのCPU情報などを取得してくれる。
 [使い方]
  String myArch = Architecture.getCurrent().toString();
    System.out.println(myArch);//x86って出力される。

2.kyesクラスがunicodeに対応した
   unicodeを指定して、キーオブジェクトを取得することが出来るようになった。
 [使い方]
  ①Keys.getKeyFromUnicode('\uE008');  
  ②Keys.getKeyFromUnicode(Keys.SHIFT.charAt(0));
  ①と②は同じキーオブジェクトを返却する。

3.ActionsクラスcontextClickメソッド(引数無しバージョン)追加
  Actions.contextClick()で、その場で右クリックしてくれるようになった。
  以前からも Actions.contextClick(null)で同じことは出来たけれども


その他
・DatabaseStorageクラスがDeprecatedアノテーションくらった
  (使ってる人、少ないと思うけど、、)
・IEから useLegacyServerオプションが完全に撤去された。
  これからはIEDriverを使いましょう
・毎度のログ周りの大きな変更
・毎度のsafari周りの大きな変更


続きはまた今度。
  


2012年11月4日日曜日

待ったことをアピールしてみる

フランスっていいよね。

3ヶ月ぶりにseleniumがVerUpしたので、久々に燃料投下。

ざっと見た感じ2.25から2.26への主な変更点は
1.共通ライブラリが一気に更新(operadriverとか)
2.IE、FireFoxでの安定化(FireFox15、16のnativeイベント対応)
3.プロキシurl自動設定、https、socksプロキシに対応
4.ログまわりの大きな変更
5.kyesクラスのunicode対応
6.名前からcolorクラスを生成可能に
7.safari操作系統がっつり変更


という感じ。
結論から言えば、あげるといいと思うよというところ。
IEでのhover不具合なども直っており、1と2だけでも結構なお得だとおもったり。

詳細な実装方法とかはまた今度。

2012年9月10日月曜日

DWRのオプションで速度改善

DWRの仕様を確認するために、公式サイトを見てみる。

内容をかいつまむと
・メーリスみろよ
・ヘルプみろよ
・トラブルシューティングみろよ
って書いてある。ようは自分で調べろってことで。

多重アクセス時の速度改善に役に立ちそうな情報としてはweb.xmlのオプションで
・maxWaitingThreads(同時ブラウザ最大接続数:デフォルト100)
・maxHitsPerSecond(同時処理数:デフォルト40)
・scriptCompressed(dwrに関するjsの圧縮:デフォルトfalse)
このあたりを変更すればいいかもね。




2012年8月26日日曜日

JsTestDriverでDOM操作を行うための妄想(その2)

妄想に取り付かれると、無敵のキラ様に殺されたりする。

さっきの続き。

JsTestDriverでDOM操作のテストを実行するには
・DOM API(docment.~とかJQueryのものとか)をつかう。
・ 【/*:DOC foo = <div><p>foo</p></div>*/】って擬似DOMにアクセスする
の2パターン存在する。
その他のjs単体テストモジュールと違い、静的なhtmlファイルを参照したりすることは
できない(あくまで現時点では)。
オプションでいかにも静的なhtmlを参照できるかのような物が存在するが、
あれは非同期通信の時などに参照するためのものであって、決して
DOMテスト用ではない。引っかからないように。

まだきちんと試せたわけではないが、後者はthisの扱いがちょっとおかしい。
理由として、jsでthisといえば、
・イベントが発生している時はその発生もとのコンポーネント
・そうでないときは自分自身(クラスとか)
だったりするが、JsTestDriver的にはthisは【:DOC foo】で指定した要素を指してしまう
ので、挙動がおかしかったりする。

そんな感じで怖いから、前者を使いたい。

とはいうものの、今度はそのDOM APIがめんどくさくなってくる。
解決方法としては、seleniumと連携して、htmlを取得し、そのhtmlを解析してDOM APIに置換。
testjs自体に結果をインサートして使用するとかになるのかな。

そんなめんどくさいことしなきゃ

JsTestDriverでDOM操作を行うための妄想(その1)

仕事(がうまくいくためにどうすればいいかを妄想するの)が好き。

Seleniumを使って自動テストをするのはいいけれど、世の中うまい話には裏がある。
ネックとしては
・実行時間
・環境の構築
この2点。

どうしても実際の通信、およびブラウザ動作を行うSeleniumは実行するのに
時間がかかるし、DBやHTTPサーバーといった環境も含めて
運用を考えないといけないから手間もかかる。

この2点をクリアできるのが単体テストであり、有名どころとしては
javaでいうとJUnit。javascriptでいうとJsTestDriverだったりする。

理想的な住み分けとしては
・カバレッジやデグレ防止のためのテストケースを増やしたりしたりするには
 出来る限り単体テストで。
・単体テストで無理な部分(業務的な処理フロー等)は画面テストで行い、
 実行時間を短くする
のがいいのかなと現時点では思っている。

で、そこで今度問題になってくるのが単体テストにおける擬似操作データ、
および擬似通信になってくる。
画面テストにおいては、実際にブラウザも立ち上げ、データベースや
アプリケーションサーバーも存在するから、環境さえ用意してしまえば、
「どのように動かすか」を設定してあげればいいだけ。
だけど単体テストはそうも行かない。あくまで「単体」だから、いわゆるMock的な物が
必要になってくる。

具体的な物の一つに、JsTestDriverでいうところのDOMの操作を行うテストが
当てはまる。

2012年8月25日土曜日

JMeterでDWR通信

ところがどっこい、そういうわけにはいかない。

JMeterでDWR通信を行う際に気をつけなければいけないことがある。
1.httpSessionId
2.scriptSessionId
3.URLパラメータ区切り文字


1.httpSessionId
2.scriptSessionId

JMeter自身が積んでるエンジンでJavascriptが実行できるが、
独自関数は実行できないため、Javascriptを実行して各idを取得することは
出来ない。
なので、これらはレスポンスから正規表現を駆使し、取得する必要がある。

3.が結構なはまりどころ。
JMeterには自身をプロキシサーバーにしたて、http通信を傍受し、テストケースを
作成する機能がある。
いかんせん便利すぎるこの機能の落とし穴。JMeterが取得したhttpリクエストは
各パラメータが半角スペースで区切られており、このままだとサーバーサイドで
パラメータを認識できず、下記のようなエラーが帰ってくる。

********************************************************************

throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
if (window.dwr) dwr.engine.remote.handleBatchException({ name:'java.lang.IllegalArgumentException', message:'Failed to find parameter: scriptSessionId' });
else if (window.parent.dwr) window.parent.dwr.engine.remote.handleBatchException({ name:'java.lang.IllegalArgumentException', message:'Failed to find parameter: scriptSessionId' });
********************************************************************

これを解決するには半角スペースを全て改行コードに置換してやる必要がある。
お勧めとしてはユーザー定義変数を作成意思、名前に【RN】、
値に【${__javaScript("\r\n",)}】と設定する。

その後、パラメータの空白部分に${RN}と設定すれば、通信パラメータが改行で区切られることになり、無事通信が走るようになる。

JMeterの正規表現

乱数を使って色違いミュウツーを取る簡単なお仕事です。

日ごろから(ポケモン的に)乱数を駆使して、いい思いをしているが、
今回は足元を救われた例。

JMeterという便利ツールがこの世には存在する。(詳細はググっておください)
で、このJMeter、httpレスポンスから正規表現を駆使して値を取得し、
変数に格納することができ、その値を使って以降のhttpリクエストに
使用したりすることができる。

で、その正規表現の設定がなんともいえない。

参照名:変数名称を記述する。
正規表現:レスポンスから値を取得するための正規表現を記述する。
テンプレート:複数取得時の番号を指定する。
一致番号:無視してok
初期値:初期値を記述する。

ってな感じでどこぞのHPに書いてあったので、そのとおりに設定していたが、
いかんせんうまくいかなかった。

原因は一致番号の設定内容。
空白のままだとなんとランダムで正規表現の内容を引っ張ってくるらしい。(詳細不明)

具体的には、DWR3の通信内容からScriptSessionIdなるものを取得しようとして、
出来るときと出来ないときがあった。(2日つぶした、、)

無視していい設定なんてないんだね、よかったね。

(人やDWRと)通信することはむずかしい。

シロのおうとうには答えていきたかったりする。


DWRがブラウザとの通信を行う際、httpパラメータに【http session id】なるものと【script session id】なるものを保持しており、このパラメータをつかって、APサーバーとの通信してる。

なので、純粋にjmeterでhttp通信を捕まえて動作をエミュレートさせようとしても、捕まえた時点でのセッションidをそのまま使用しているため、まともに動作できない。

なので、jmeterのテストケース内で動的にパラメータを取得し、編集する必要がある。

【DWR2の場合】
engine.jsの応答データから正規表現で引っ張ってくればいい。
【DWR3の場合】
ページロードリクエスト(リクエストパスに《__System.pageLoaded.dwr》と設定されている)の
応答データから正規表現で引っ張ってくればいい。

DWR3の方法がどこにも書いていなくて、あせったりした。
でも本当にあせったのはjmeterの正規表現仕様だったりする。

visualVMのアドオン実装

一昔前はライブラつかって
『ねんがんのオニオンソードをてにいれたぞ!』
が実行できた。
今はvisualVMつかってcpu使用率やheap量とか取得できる。

ただしグラフで表示されたりするだけで、正確な数字をログにして記録したりしようと思ったら、
独自にアドオンを開発しなきゃいけない。

開発環境の構築や取っ掛かりはIT Proに任せるとして、詰まったところをメモ書き程度に書いておく。

//まず前提から、こんな感じで書くと、jvmの現在のステータスがわかる
MonitoredDataオブジェクトを取得できる。


        MonitoredDataListener monitoredDataListener = new MonitoredDataListener() {
            @Override
            public void monitoredDataEvent(final MonitoredData data) {
                final long time = System.currentTimeMillis();
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        //ここに書く命令が、一定秒数ごとに実行される
                        hogehoge(data, time)
                    }
                });
            }
        };


//jvmの稼働時間
data.getUpTime()
//cpu経過時間
data.getProcessCpuTime()
//javaマシンの情報を取得したり
Jvm jvm = JvmFactory.getJVMFor(application);
//cpuモニターサポート状況取得方法(boolean)
jvm.isCpuMonitoringSupported();
//javaマシンのプロセッサ数取得(int)
JvmMXBeansFactory.getJvmMXBeans(JmxModelFactory.getJmxModelFor( application ))
              .getOperatingSystemMXBean().getAvailableProcessors();

上記のメソッド組み合わせて、cpu使用率とか取れたりする。メモリはもっと簡単
//最大ヒープサイズ
data.getGenCapacity()[0];
//使用ヒープサイズ
data.getGenUsed()[0];
//最大メモリサイズ
data.getGenMaxCapacity()[0];



そろそろタグ管理したほうがいいかな、、、、

2012年8月4日土曜日

希望を見出しても、重力に魂を引かれたエゴに押しつ(以下略


希望を持つことはいいことです。

seleniumの2.25から複数のCapabilitiesクラスを指定することができるようになった。

今までは
new FirefoxDriver( );
new FirefoxDriver( DesiredCapabilities.firefox() );
new FirefoxDriver( new FirefoxBinary(), new FirefoxProfile(), DesiredCapabilities.firefox());
new FirefoxDriver( DesiredCapabilities.firefox() );
こんな感じでFirefoxを起動していたものが、

  Capabilities cap = DesiredCapabilities.firefox();
  Capabilities cap2 = DesiredCapabilities.firefox();

new FirefoxDriver(  cap   ,  cap2   );
new FirefoxDriver( new FirefoxBinary(), new FirefoxProfile(),  cap ,  cap2 );


こんな感じにできるようになった。
ごっそり変わったソースの変化がデグレを予感させるが、googleさんはデグレなんかしませんよね。

もともとCapabilitiesクラスは起動設定を保持するクラス(プロキシとか、起動オプションとか)
であり、最近はChromeOptionsとかFirefoxProfileが台頭してきて、
ただでさえここ最近は居場所がない状態だった。
関係するコンストラクタもdeprecatedされまくってた。

なぜゆえに、時代に逆行するようなことが起こったのか、起動設定をひとつのブラウザで
複数指定できるようにしてあるのか、いまいち要領が得ない。
多分Firefox14以降の仕様にあわせた感じなんだろうけど。

で、肝心のソースの中身なんだけど、前者のCapabilitiesは希望的な位置づけで
後者のCapabilitiesは必須的な位置づけらしい。

何のこっちゃようわからん。一応Firefoxdriver内では2つのCapabilitiesをマージして
FirefoxProfileに変換し、設定を読み込んでいる。


だったら最初から
  new FirefoxDriver( new FirefoxBinary(), new FirefoxProfile())
これ使えって話じゃないかと思ったりする。今後何か意味が出てくるんだろうか。

なお、CapabilityType.ENABLE_PROFILING_CAPABILITYは希望Capabilitiesに
セットさせて動作させておく模様。



2012年7月29日日曜日

IEDriverServerの起動設定


2.25からIE起動時に詳細な設定が出来るようになった。

今までが

WebDriver driver  = new InternetExplorerDriver();
WebDriver driver  = new InternetExplorerDriver(DesiredCapabilities.internetExplorer());
こんな感じで

2.25以降が

WebDriver driver  = new InternetExplorerDriver(InternetExplorerDriverService.createDefaultService());
WebDriver driver  = new InternetExplorerDriver(InternetExplorerDriverService.createDefaultService(),DesiredCapabilities.internetExplorer());
こんな感じ。

でもこれだけだと恩恵受けられない。いい感じにするには

InternetExplorerDriverService is = new InternetExplorerDriverService.Builder()
 .usingPort(0)//0ポートを使用してみたり
 .usingAnyFreePort()//やっぱりあいてるポート使ってみたり
 //ドライバーを指定してみたり
  .usingDriverExecutable(new File("C:\\IEDriverServer"))                          //ログファイルを仕込んでみたり    
  .withLogFile(new File("C:\\IELOG.log"))
  //ログレベルしこんでみたりして
  .withLogLevel(InternetExplorerDriverLogLevel.DEBUG).
  .build();

  WebDriver driver  = new InternetExplorerDriver( is ));//起動してみたりする。

こんな感じ。出てくるログの内容はしらない。出してみた人は、どんなんでるのかおしえてくんろ。

2012年7月20日金曜日

Androidに特化した(ドヤッ


FireFoxの14が動作しない現象に悩まされたと思ったら、あっけなくseleniumが
対応して、はや2日。
やんごとなき更新内容ログを見てみると、selenium2.25はFireFox17まで
対応しているとのこと。
未来を生きるgoogleさまは違います。

FireFox14はAndroidに特化しているらしい、その影響か、FirefoxDriverにも
大きな仕様変更が。
まぁその辺は後ほど。

とりあえず、2.25の最大の機能は最新版のFireFoxが動作するところにある。
まぁ、機能といっていいのか、当たり前のことだけれども。

その他細かな修正がいろいろと。

1.IEDriverServerのログ出力機能がついた
2.InternetExplorerDriverにInternetExplorerDriverServiceを指定できる
コンストラクタ追加されて、いろいろ細かく設定できるようになった
3.nativeEvents設定なるものが追加された
4.FirefoxDriverにCapabilitiesが複数指定できるようになった(なんで?)
5.unhandled alerts(アドオンが発する予期せぬエラー的な、、)の制御が出来るようになった
6.BASIC認証とDIGEST認証がどうのこうのといいだした。その影響で出来たと思われる
UserAndPasswordっていう謎の構造体クラスが出現した。

上に書いたものについてはおいおい実装方法なども紹介していきたい。


後はどうでもいいけど
SeleneseCommandExecutorのブラウザ判定が変更したり、
「JavascriptExecutor#executeAsyncScriptに変な引数わたすな!」って書いてあったり、
「WebElement#clearにマウスやキーボードイベントを発生させることは期待するな。
backspaceやtabのsendKeysを考慮しろ」って書いてあったり、
FatalChromeException・InternetExplorerElement・FirefoxWebElementがもうすぐなくなったり、
SafariDriverにようやくCapabilitiesが指定できるようになったり、
「driver.manage().window().setSize(new Dimension(400,400))」で落ちるバグがなくなったり、
firefoxのsubmitが安定したり、
WebElement#getCssValueに注意書き(仕様変更?)があって、これからはrgbaの時代だぜって
いってたり(そのおかげでまさかのColorクラスに大幅な仕様変更)、

AlertクラスにauthenticateUsingっていうよくわからないメソッド追加されてたり、
俺は2.26からはIEDriverServer.exeを使用しないで起動することをやめるぞーーーーっていってたり、
ChromeDriverServiceでchromedriverの保持方法変わったりとか。

おなかいっぱいですわ。

2012年6月11日月曜日

hudsuckr.exe

Selenium-Webdriverを使用してブラウザのプロキシ設定を行い起動する方法は
3つある

1.WebDriverインスタンス生成時の起動オプション(ChromeOption、FirefoxProfileなど)を
使用する
→詳細は過去記事を参照。
2.別手段でプロキシの設定をしておく
2-1.IEのオプションから事前に設定する
手動でIEの設定を変更してから、Selenium-WebDriverを実行する
2-2.起動時にのみ設定を書き換える
Selenium-WebDriver実行前にbatやvbsでオプションを変更する。
終了した後は、元に戻しておくのが吉
ex)http://d.hatena.ne.jp/tanamon/20090417/123993594



1が一番お手軽。
2は、テスト以外のブラウザを介した通信もプロキシ経由になってしまうため、
その他の業務に支障が出る可能性がある。

しかしながら1を実装しようとした際、FireFox、Chromeは大丈夫なものの、
IEはhudsuckr.exeという外部実行モジュールが必要になる。
このモジュール、ChromedriverやIEServerDriverと違い、自由に配置場所を設定することが
出来ない。
どうやらSeleniumの中に含まれているWindowProxyManagerかFileHandlerクラスと同じ階層にhudsuckr/hudsuckr.exeという決まった形式でファイルを配置する必要がある。
要はjarの中に埋め込まないといけない。

おとなしく2の方法を選んだほうが賢いような気がする。

2012年6月10日日曜日

>>1さん

別にスレ立てした人のことを指してるわけじゃない。

金曜日に引き続き、またもseleniumの安定新バージョンがアップされた。
その名もselenium2.23.1
何だよ、『.1』って。その1には何がこめられているのか。

変更ログにも何にも書いてない。ちょっと前にもスモールスモールバージョンが
アップされたことがあったけど、本当につまらないことしか変わってなかった。
そして今回も、使わなくなったどうしようもない、そしてどうでもいい
publicメソッド(*)を1つ消しただけだった。
なんてこった。

最近、selenium小芝居(アップグレード詐欺)に踊らされてる。
当分は2.22のままで大丈夫な予感。
無料なだけに、文句が言えない。ただより高いものはない。

*FirefoxProfileクラスのisRunnungメソッドというクラス。
 内部的には起動中のFireFoxのプロファイルディレクトリに存在するparentlockという
 ファイルを参照し、動作中かどうか判断する機能を持っている。
 2.23で廃止された、実行中は永久待機する不具合を発生させるメソッドからコールされていた。
 今はもう、どこからも参照されていない。

2012年6月9日土曜日

selenium2.23は見ちゃ駄目


たぶん出すのが早すぎたんでしょう。
先週に引き続き、新たなselenium安定バージョンが出荷された。
バージョン番号は2.23、

ソース比較したけど、お粗末様な部分を急遽修正した感じ。


一番大きいのはFireFoxの挙動。
処理中かどうか判断するために、ローカルのロックファイルを参照するが、
それが存在している場合、永久待機を命じられる部分が削除された。当たり前だ。

あんたFireFox13に対応すましたと言いたいだけちゃうんかと。

2.22以下のバージョンを使っていて、たまにFireFoxが止まったり、操作不能になったり、
フリーズしたりするって人はアップデートしてもいいかもしれない。

あと、起動時の処理も変わっているけど、起動オプションから余計なものを
削除しているだけなので、こっちはあんまり気にしないでいいと思う。
どんな実装したら、この修正の恩恵を受けれるかわからないぐらい、
どうでもいい部分。


あとはSafariDriverにはっきりとBetaのアノテーションがつきました。
いや、わかってるから。いまさら言われてもという感じ。
不具合報告掲示板(issues)がsafariの声で盛り上がっているから、その処置だと思う。
そんなこと言い出したら、selenium自体がBetaだろうよ。

まじかよクソ箱売ってくる。

2012年6月2日土曜日

seleniumの2.22(その6 イベント方式)

WebDriverにはイベント方式の概念として下記の2つが存在する


synthesized events
Javascriptを使って一連のイベントを合成し、あたかもユーザーがその操作をしたのと
同じように動作させる概念

Native events
ユーザがWebアプリケーションに対する操作を正確にエミュレートするという概念


当然前者は実際に操作するわけではないから、本当の意味でテストできているわけではない。
selenium2.21まででいうとFireFoxはNativeで動作していたが、IEはsynthsizedで動作していた。
IEが他のブラウザよりselenium実行速度が遅いのはこれが原因の一つでもある。
2.22からIEもNativeで動作しているので、本当の意味で『エミュレート』出来ていることとなる

IEをあえてsynthsizedで動作させたいときは
DesiredCapabilities capability = DesiredCapabilities.internetExplorer();
capability.setCapability("enableNativeEvents",false);
WebDriver driver = new InternetExplorerDriver(capability);
とすればいい、やる意味ないけど。




2012年6月1日金曜日

seleniumの2.22(その5 スクショとか色とか)

エラー発生時に自動的にスクショを取得することが出来る。
独自実装でも可能だが、すきにして。

やり方
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability("webdriver.remote.quietExceptions",true);
CommandExecutor executor = new SeleneseCommandExecutor(
                                           new DefaultSelenium("localhost",
                                           4444,
                                           "*safari",
                                           "http://localhost"));
 WebDriver driver = new RemoteWebDriver(executor, capabilities);

http://code.google.com/p/selenium/wiki/DesiredCapabilities
ここにも記述してあるが、どうやらRemoteWebDriver限定らしい。

あと、画面に表示されている色情報も取得できる。
 WebElement ele = driver.findElement(By.id("id"));
 Color iro = Color.fromString(ele.getCssValue("background-color"));
 iro.asRgb();//rgb取得   rgb(10, 100, 200)
 iro.asHex();//16進数取得 #000000

便利な世の中ですね。

2012年5月31日木曜日

seleniumの2.22(その4 DriverService)

差分が発生しているjavaファイルを開き、著作権表記のみが
変わっていることを確認する簡単なお仕事です。

さてさて、Chromeだけではなく、本バージョンから新たにIEにも
DriverServerが出現した。

Chromeの時は特に動作速度に問題がなかったためスルーした
(というよりも勝手にChromeDriverがDriverServerを使用する)が、
IEは遅いため、使用してもいいかもしれない、というより、
使用しないとエラーになる。

以下やり方

System.setProperty( InternetExplorer DriverService.IE_DRIVER_EXE_PROPERTY,
                            "c:\\IEDriverServer.exe");

WebDriver driver = new InternetExplorerDriver()

こんな感じ、これでIEの起動が完了する。
IEDriverServer.exe自体はseleniumと同じ場所からダウンロードできる。
32bit版と64bit版のDriverが存在するので、ロジック内で
System.getProperty("os.arch")
を実行し、戻り値によって、セットするDriverを変更させればいい感じだと思う。


今までどおり、DriverServer無しで起動したい場合は


DesiredCapabilities capability = DesiredCapabilities.internetExplorer();
capability.setCapability("useLegacyInternalServer",true);
WebDriver driver = new InternetExplorerDriver(capability);

でOK。
ただし、イベント発生概念の関係からオススメはしない。


実行速度って重要ですから、終いにはFireFoxDriverServerとか出るかもしれない。
DriverServer怖い。

seleniumの2.22(その3 FileDetector)

ChromeやIE、FireFoxを含む全てのWebDriverにsetFileDetectorというメソッドが
実装された。
結果的にはExceptionを吐くだけだが、RemoteWebDriverを使用した
リモート起動の場合のみ、サーバー側のファイルを指定して、
ブラウザからのファイルアップロード動作を行うことができるようになる。

実装方法

生成したRemoteWebDriverクラスのsetFileDetectorメソッドを使い、

rdriver.setFileDetector(new LocalFileDetector())

でFileDetectorをセットした後、

rdriver.getFileDetector.getLocalFile({アップロードファイルパス})

でok

直接起動するDriverたちには不要なものなので、ほっといていい。


seleniumの2.22(その2 ライブラリ)

GoogleブログのエディターがなぜかChromeよりFireFoxのほうがきちんと動作する。
GoogleブログなのにデバッグやテストはFireFoxで行っているのだろうか。
そんなことで世界の情報を統合できるのか。
Googleの天才はやることが違う。


 とりあえずjavaの6に対応したというのを大きく歌っているものの、何が違うのかわからん。
詳しい人はコメント求む。

selenium2.21に比べ、参照されている外部jarで新しくなっているものは下記の3つ
  1.  guava(11.0.1→12.0)
  2.  operadriver(v0.11→0.14)
  3.  webbit(0.4.6-full→0.4.8-SNAPSHOT)

guavaはjavaのライブラリ、他のgoogleプロジェクトでもよく使われている、ググればよく出てくる。
http://d.hatena.ne.jp/mtoyoshi/20100725/1280040233
ここに詳しく書いている、痒いところに手が届く素敵なライブラリ。個人的にも使っていきたい。

webbitなんかはサーバークライアントの通信部分。現在(2012/05)公開されているのは0.4.7。
一番がっつり変わったoperadriverの現在の最新版は0.13

公開されていないjarをふんだんに使うgoogle素敵過ぎ。




seleniumの2.22(その1 大まかな変更点)

きたか…!! 


  ( ゚д゚ ) ガタッ 
  .r   ヾ 
__|_| / ̄ ̄ ̄/_ 
  \/    / 


とまぁ件名の通りです。
なにやらソースもがっつり変化して、その辺もいつもどおりです、もう驚きません。


主な不具合対応はSafariDriverの機能追加(*1)何だけれども、ほかのDriverでは
既に出来ていたものなので、そんなに目新しくなかったり。
というよりSafariDriver中身変わりすぎ(コマンドを実行して、ブラウザのイベントを発生させる、
Driverの基幹部分) 
リッピングしてるから問題ないんだろうけど、
運用乗っけてたら、バージョンアップを考えるレベル。まだ使うのは時期早々かね。 


あとはframe配下での最大化やalertの不具合修正、FireFoxの動作安定性
(xhtml対応、クリーンアップ対応)等々。


ソース差分を見ていたけれど、著作権表記が全ソースで書き換えられていて、
winmergeが大変反応されまして、大仕事になっています。やだやだ。


他にも、いっぱい変更箇所あるんですよ、これが。
一番大きなところはIEDriverServerではなかろうか。
Chromeのように別ファイルが必要になるっぽい。


長くなるし、眠いのでまた次回。


(*1)
  •  スクショ取れるようになったり
  •  フレームきりかえれるようになったり
  •  javascript実行できるようになったり

2012年5月29日火曜日

SafariDriverの動作性

2.21から実装されたSafariDriverは、いかんせん動作に不具合が多いようで。

javascriptでwindow.openが使用できないという致命的なものから、スクショがうまく取れないという(windowのサイズを変更しないと、viewpointが表示されないとか、、、)ものまで幅広く。

windowsとmacでのsafariの仕様差を吸収仕切れていないのか、わからんけど。なんかエンジン違うらしいね。知らんけど。

他のブラウザと違って毎回プレーンで起動しない(前回起動時のクッキーとか残っちゃう)なども問題。キャッシュとかも残っているのかも。
現状は起動時の引数でプレーンで起動することを明示的に指定するしかない。

DesiredCapabilities capability = DesiredCapabilities.safari();
capability.setCapability("ensureCleanSession",true);
WebDriver driver = new SafariDriver(capability);
こんな感じ。
何にせよ、これからの物。

2012年5月4日金曜日

InternetExplorerをselenium-webdriverで操作する方法


InternetExplorerをselenium-webdriverで操作すると、

org.openqa.selenium.WebDriverException: Unexpected error launching Internet Explorer. Protected Mode must be set to the same value (enabled or disabled) for all zones. (WARNING: The server did not provide any stacktrace information)


というエラーが発生し、動作がストップしてしまう。
これを回避するには、
http://code.google.com/p/selenium/issues/detail?id=1795
に記述されているようにセキュリティの設定を変更しなければ行けない。

ただし、それ以外にもプログラム側で設定を変更することによって、設定を変更する手間を削減することが出来る。


DesiredCapabilities capability = DesiredCapabilities.internetExplorer();
capability.setCapability(
              InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,         true);
WebDriver webdriver = new InternetExplorerDriver(capability);

こんな感じ。
普段からIEを使用していて、テストのたびに設定を変更したくない人は考慮してもいい。

//追記
2.22以降でIEDriverServerを使用する場合は上記設定を行わなくても大丈夫。

2012年5月3日木曜日

LoggingHandler

またもやorg.openqa.selenium.loggingパッケージのお話。

Selenium2はブラウザとの通信ログを取得することが出来る。

具体的には

WebDriver driver  = new FirefoxDriver();
Iterator<LogEntry> it = driver.manage().logs().get("logType").iterator();

こんな感じでログの内容をそのまま保持することも出来るし、LoggingHandlerクラスを使用すれば、ログをアタッチすることも可能。

LoggingHandler.getInstance().attachTo(Logger logger, Level level);

仕様としてログ情報が1000件超えたら自動的に削除されるので、それまでに読み取るか、ファイルに吐くかして保持しなければならない。その辺は注意。



LoggingPreferences

selenium-webdriverにはorg.openqa.selenium.loggingというパッケージが存在する。
具体的にはその名の通り、ブラウザ自動実行時のログを出力する機能が実装されている。

その中にはLoggingPreferencesというクラスが存在し、その名の通り、ログ出力に関係する設定を行うことが出来る。 が、見たところ、Chrome、IE、Safariには対応しておらず、FireFoxでしか使用できない(なぜゆえに、、)

実装方法は

  DesiredCapabilities caps = DesiredCapabilities.firefox();
  LoggingPreferences logs = new LoggingPreferences();
  logs.enable(LogType.DRIVER, Level.INFO);
  caps.setCapability(CapabilityType.LOGGING_PREFS, logs);

  WebDriver driver = new FirefoxDriver(caps);

とすれば、ログが出力される。
「LogType.DRIVER」と記述しているが、LogType.DRIVERしか現在存在しないので、おまじない的に記述する。
下記はブラウザとの対応表(2.21)現在
ドライバ名称 実装可能かどうか 不可能な理由
FireFoxDriver -
ChromeFoxDriver DesiredCapabilitiesに対応するコンストラクタが非推奨
InternetExplorerDriver × 非推奨でないDesiredCapabilitiesに対応するコンストラクタが存在するものの、CapabilityType.LOGGING_PREFSに対応する設定が存在しても無視している(プロキシの設定しか見ていない、、、)
SafariDriver × DesiredCapabilitiesに対応するコンストラクタが存在すらしていない

なので、使用する際は各ブラウザのリッピングされた~Driverコンストラクタではなく、RemoteWebDriverコンストラクタに起動ブラウザをセットして使用する方法をとるといい。 ちょっと残念。

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

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の変数呼び出し先を見たら詳しくわかる。

2012年2月28日火曜日

2.20がでたよ

今回は大幅に変わりましたね。

1)pageLoadTimeoutってメソッドがwebdriverクラスに追加された
独自実装していた部分ロードの最大待機時間部分をwebdriverベースに切り替えることが出来る。やっほい。
こんな感じ
 driver.manage().timeouts().pageLoadTimeout()


2)org.openqa.selenium.support.ui.ExpectedConditionsっていうクラスにalertIsPresentっていうメソッドが
 追加された。これで同じく独自実装してたalertの表示チェックが代替できる
こんな感じ
Alert al = (new WebDriverWait(driver, time)).until(ExpectedConditions.alertIsPresent())

速く変更せねば、、、


以下、補足。
Sleeper.sleepTightっていうスリープしてくれるメソッドを発見。当たり前だが、これも代替する。

org.openqa.selenium.lift.match配下の表示確認関数軍発見、これも使えるかも。

2012年2月11日土曜日

Color

seleniumにバージョン2.19が出ました。
が、FireFoxの既存のバグが潜んでいるようなので、いったん使うのは控えようかと考え中。

あとよくわからないクラスを発見。

package org.openqa.selenium.support.Color

なにやってんの?と思って中身を見てみたら、rgbで色の情報を保持する、色情報を保存するクラスでした。
いったい何に使うんだろうか、よくわからん。中からも呼ばれてないし。

でも、なにかに使ってみたい。今日この頃。

2012年1月24日火曜日

chromedriver.exeのプロセス

webdriverでchromeのテストを実行する際、chromedriver.exeが必要になる。
問題は終了時に

WebDriver.close();
とするだけでは chromedriver.exeのプロセスが終了されず、残ってしまう。
きちんと
WebDriver.quit();
も実行しましょう。(てかどのサイトにもそう書いてる、、、)

2012年1月10日火曜日

ChromeOptions

selenium2.16で追加された新しい機能(クラス)にChromeOptionsというものがある。

FireFoxDriverと同じようにアドオンのパスを指定して同時起動出来るようになる。

例)

 ChromeOptions options = new ChromeOptions()
 options.addExtensions(new File("/path/to/extension.crx"))
 options.setBinary(new File("/path/to/chrome"));

 // For use with ChromeDriver:
 ChromeDriver driver = new ChromeDriver(options);
 
以前話に上がったScriptCoverと同時起動して、jsのカバレッジを調べたり出来るようになる。
 

2012年1月4日水曜日

idがついていないコンポーネントのエレメントを指定する方法

driver.findElements(new ByChained(By.id("hoge"), By.Name("hogehoge")));
 
上のようにすると要素をチェーンできる。これでidのついていない、特定できない要素をちょっと特定して取得できる。
面白かったのはソースの中身
public class ByChained extends By {

  private By[] bys;

  public ByChained(By... bys) {
    this.bys = bys;
  }
}
こう書けば可変引数を渡せるのね。

for (By by : bys) {
stringBuilder.append((first ? "" : ",")).append(by);
   first = false;
}
こうすれば配列をfor文にそのまま使える。
しらなんだ。
人のソースって勉強になりますね。