2013年2月28日木曜日

Cookieをaddして「続きからはじめる」

テスト作成中, ログインフォームをすっ飛ばして途中からテストを開始する準備がしたかったので

addCookieのちっちゃな落とし穴

ログイン情報を Cookieに持たせているので, 途中からはじめるなら
「addCookieとかあったよなー」
import org.openqa.selenium.Cookie;
  @Before
  public void setUp() throws Exception {
        driver.manage().addCookie(new Cookie(key, value));
なんてぼんやりaddしてたら
org.openqa.selenium.WebDriverException: Could not set the cookie (WARNING: The server did not provide any stacktrace information)
なんて怒られた.
どうやら「まだページ準備できてねーよどのページにCookie作る気だよ!щ(゚Д゚#щ)ゴルァ!」
とかいうことらしい.
なので
import org.openqa.selenium.Cookie;
  @Before
  public void setUp() throws Exception {
        driver.get(適当なページ);
        driver.manage().addCookie(new Cookie(key, value));
と, 何かログイン前に入れるトップページあたりを一度表示してやると addできる.
さすがに Googleトップとかに addしても意味無いけど.

これでaddCookieできますた.




Cookieよくわかんね('A`)

2013年2月27日水曜日

衝突を恐れない/考えない git merge

正直ちゃんとできているのかわからない('A`)

git (もちろんコンソールから)いじっている際, gitpushが ![reject]されたときの一連の流れの覚書
メモメモφ(・ω・ )

Git の 「! [rejection] 」への対処法


※あくまで自動マージで対処できる程度の衝突の際の流れです.
※本物の git初心者向けです. 

とりあえず commitしたものをあげましょう. 最初はmasterと緑なmasterですが…
git push
すると突如発生する ! [reject] から始まるエラー報告. どうやら他からも変更来てるよーってことらしい. ここで慌てると平気で1日つぶすようなパニックに見舞われます. 落ち着くことが大事です. まだここはこわくなーい.

Gitには幸い 自動マージ なるものがあり, 簡単な衝突なら自動でマージしてくれます.
まずはマージの準備
git fetch
だいぶ前にわからないと投げたコマンドを使う衝撃たるや('A`)
コイツはリモートの状態を, 別の作業用ブランチに持ってきてくれるコマンドだったらしい. すなわち先ほどの「他からのコード」をとりあえず別の場所に貰ってきてくれるらしい.
この時点で自分の書いてたコードと, fetchが持ってきてくれたブランチの2種類が存在する.
ここが一番混乱する…(・д・`)
ちなみに実行するとmasterと黄色くなっているかと.
git merge orign/master
これで 自分の書いていたコードのほうに, 持ってきたものを自動マージしてくれる. 問題はここで自動マージできていなかったとき. ファイルに差分を挿入してくれるらしいので, どれがぶつかったか確認して直しちゃいましょう. …改行コードの統一とかができていないとこれがとんでもない地獄になりますΣ(||゚Д゚)ヒィィィィ
マージが全て完了したら, おそらくmasterと緑に戻るかと.
もう一度
git push
すると今度はいってくれるはず.


…人数多いとマージ中とかに pushされるのよね…('A`)オマイラ…



2013年2月26日火曜日

fakeApplicationを使ってテストの初期値を作ろう

Selenium2でテストを続けるうちに出てきた問題.
DBの初期値やらリセットやらどうしよう…

前にjUnitでテストの段階わけのようなことができたので
「じゃぁ@Beforeでデータ入れて@Afterで消せばいっかなー(・з・)」
なんて考えてたら…

fakeApplication()で本体のメソッドを使う

当然本体ではDBにアクセス→参照やら挿入やらやってるもんだから, このメソッドもらえないかなーなんて考えてとりあえずテストの中で呼ぶ

→ There is no started application

…('A`)なんだこれ
どうやらテストは jUnit, 本体は Playの領分らしく, そのままではまたいで呼び出すことはできないらしい. あらめんどくさい. 呼び出せるアプリが起動していないから There is no started application(開始しているアプリはありません) ってことなのか?
そこで見つけたのが fakeApplication()など play.test.Helpersシリーズ. どうやら本体を仮に動かして中のメソッドをいじれるようにしてくれるっぽいという印象だけの理解('A`)
これ使えばわざわざテスト用に起動しなくていいのかも…
import static play.test.Helpers.fakeApplication;
import static play.test.Helpers.running;

running(fakeApplication(), new Runnable() {

      @Override
      public void run() {
         // 初期値作るメソッドやらなんやら
      }
    });
こんな感じ.

ただし今回は, confファイルで使うテーブルを指定しており, これをテスト用のテーブルを使う, と一緒に宣言を変えたいという追加設定.
最初は「別の confを宣言するのか?」なんて考えてまた迷走.
結局たどり着いたのが,
Map<String String> map = new HashMap<String String>();
map.put("confの中で使うテーブルを宣言している項目", "テスト用テーブルの設定");

running(fakeApplication(map), new Runnable() {
// 以下略
Mapを使ってアプリ起動時の application.confを一部書き換えて読み込む方法.
例えば db.default.driverなんていう, 使用する DBの Driverの宣言. これをテスト時には別のものに書き換えたい!なんてときは
map.put("db.default.driver", "別のドライバ")
としてやれば, fakeApplication()で呼ばれるアプリ中では "別のドライバ" を使ってくれる. まぁテスト時だけドライバ変えるのも珍しすぎる気はするけど… いい例えが思いつかなかった…
なお複数 putしていっぱい書き換えることも可能.
そして, 元になるのは通常起動時に読まれる application.confのはず.


そして git嫌い('A`)

OSによる分岐

いろいろいじってたSelenium2
共同開発でいじっていたので中にはMac等Win以外のユーザーもいるわけで.
それはいいのだけど
「chromedriver.exeとかMacじゃ動かないんだけど(・ω・ )っ/凵⌒☆チン」
「chromedriver.shにしてくんね?マダ-?(・ω・  )っ/凵⌒☆チン」

…ぉおぅ('A`)

というわけでOSによって呼び出すchromedriverを変えたいなー, というのが始まり

Java, OSの参照と分岐

chromedriverについてはこちらあたりで. 
特に難しいことはせず, シンプルにif文.
  public static void setChromeProperty() {
    if (SystemUtils.IS_OS_LINUX) {
      // Linux用処理
      return;
    }
    if (SystemUtils.IS_OS_MAC) {
      // Mac用処理
      return;
    }
    if (SystemUtils.IS_OS_WINDOWS) {
      // Windows用処理
      return;
    }
  }
ifの中身
SystemUtils
を参照する.
わりとわかりやすい名前で助かります.∩( ・ω・)∩

OSを判定し booleanが返ってくるのでそのまま ifに入れられるのもわかりやすい.

これだけ.

ちなみにこの SystemUtils. 結構細かいとこまで見てくれているらしく.
SystemUtils.IS_OS_WINDOWS_95
SystemUtils.IS_OS_WINDOWS_98
SystemUtils.IS_OS_WINDOWS_2000
SystemUtils.IS_OS_WINDOWS_ME
SystemUtils.IS_OS_WINDOWS_XP
などOSのバージョンまで見てくれたり.





…ここまでするアプリ作る予定は無いけどネ(・ω・`)

2013年2月25日月曜日

By.xpath中心のメモ

Selenium2でテスト作成時, 嫌でも使わなければならないものが findElement(By).
このByについてメモメモφ(・ω・ )

Byの指定

WebDriver.findElementは今開いているページからその引数で指定した要素( WebElement)を返すメソッド. なのでこの引数を正しく指定しないとエラーに泣くことになる.


By.id("id")
そのままidで要素を探す. なので必ずひとつで返るはず. 安定感は抜群.
By.className("class")
classで探すときは .class()ではなくこれ. っていうか .class()なんてない. 入力補完を使っていればまず無いけど, .id()等で考えが固まっているとつまらないミスでモニターとにらめっこすることになる.
By.name("name")
nameで探す. id以外は複数返る恐れがあるので注意. 複数あるはずなのに .findElement()で探した場合, ページソースを上から探して最初の要素だけ返ってくる. ちゃんと全部みたいなら
List<webdriver> elements = WebDriver.findElements(By by)
を使いましょう.
By.linkText("text")
ちょっと注意. 名前の通り<a>タグで囲まれたリンクのテキストだけを探す. ボタンの文字なんかは検索対象外なので注意.

By.xpath(String path)
この String pathの部分書き方が今回のメイン. たとえばこんなボタンが html上にあったとする.
<button class="btn" onclick='history.back()'>キャンセル</button>
なんてことは無いキャンセルボタン. ただidが振られておらず, classもありきたりな名前でもしかしたら複数取得されるかもしれない.
これを指定したいときは
WebElement element = driver.findElement(By.xpath("//button[@class='btn' and @onclick='history.back()']"));
となる
// → \\ではないので注意
button[条件] → 探したいのが<button>なのでbutton[条件]. もちろん<input>を探したいなら input[条件]となる.
@class='btn' → そのまま, <button>の中の要素 class="btn"を指す. @が無いとバグるので注意.
and → 複数の条件を設定する際に使う. すなおに and.
@onclick='history.back()' → メソッドだろうとお構いなしに条件に指定できる. まぁ文字列見てるとかなんだろうけど.
以降も and @~で条件をどんどん絞り込める.

これで指定できるはず. 一番いいのは idつけてやれば一意に定まるだろうけど, 自分じゃ修正に手が出せないときなんかはこれで. もちろん条件を増やせば絞り込めるけど, 特に classを複数設定しているような要素の場合, スペースや全半角でも条件がずれるので注意.



読みにくっ('A`)

2013年2月22日金曜日

Play起動時の覚書

シンプルに
play "run 9001"
と Playを runすると, デフォルトの9000ではなく指定したポートでPlayを走らせられる.(この場合 9001番ポート)

[run 指定ポート番号]を "" で囲むのがポイントらしい




それだけ(・ω・`)

参考

Selenium2のテスト時間短縮?

前々回あたりでSelenium2のテストを書き始めたが, 毎回毎回ブラウザを立ち上げては消すのがなんとも時間がかかる.
なのでせめて一つのテストファイルの中ではブラウザの立ち上げ→終了は1回にして, 同じウィンドウを使い回せないかと考えた.
これでいいんだろうか…('A`)


Selenium2のテストの余計な時間の短縮


正直8割 jUnit4による解決

  private static WebDriver driver;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    driver = new FirefoxDriver();
  }

  @Before
  public void setUp() throws Exception {
    driver.get(initUrl);
  }

  @After
  public void tearDown() throws Exception {
    driver.manage().deleteAllCookies();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    driver.quit();
  }

Firefox版. 単純にjUnitのアノテーションに頼れば何とかなんじゃね?というだけのお話.
アノテーションのおかげで

@BeforeClass → (@Before → @Test → @After) * n → @AfterClass

という順序で呼ばれるので

ブラウザ起動 → (初期状態作成 → テスト → 事後処理) * n → ブラウザ閉じる

とすればいい.
コード的にも前々回使ったコードがほとんど.
driver.manage().deleteAllCookies();
このメソッドで作られてしまったクッキーを削除しているくらい. これを@Afterで行なうことで各テストで作られたクッキーを削除してやる.
@Beforeのところでテストしたい画面の初期状態を作ってやれば, 一つのテストファイル中は同じウィンドウを使いまわしてテストができるはず.

これで毎回テストメソッドごとにブラウザ立ち上げては閉じるなんて時間が大幅にカットできる.
実際変更前のテストごとにウィンドウを開く方法だと6分かかっていたテストも, 3分強程度まで短縮できている.
せいぜい30~40程度ののテストでこれなのだからさらにテストが増えたときの差は大きいはず!
+(・ω・0)*



どうみてもSelenium2の問題ではありません. 本当にありがとうございましたorz

2013年2月20日水曜日

PlayのアプリをSelenium2でテスト

やられた…
PlayとSeleniumって仲ええんやん…
最初からPlayの中にSeleniumいてるんやん…orz
しかしいざ本体のプロジェクトの中で以前と同じようにテストを作る→jUnit Test

…なんか真っ赤になってるー

妙なエラー吐いてテストしてくれなくなりましたorz

Playのアプリ本体にテストを入れ込む

A. エラーの原因


要するに「テストプロジェクト」を別に立てずに一括で管理したいなー(チラッ という要望から入り込んだ今回の泥沼.. 冒頭の通りただ本体に放り込んだら…
java.lang.NoSuchMethodError: org.apache.http.conn.scheme.Scheme.<init>(Ljava/lang/String;ILorg/apache/http/conn/scheme/SchemeSocketFactory;)V
 at org.openqa.selenium.remote.internal.HttpClientFactory.getClientConnectionManager(HttpClientFactory.java:59)
 at org.openqa.selenium.remote.internal.HttpClientFactory.<init>(HttpClientFactory.java:48)
 at org.openqa.selenium.remote.HttpCommandExecutor.<init>(HttpCommandExecutor.java:117)
 at org.openqa.selenium.remote.service.DriverCommandExecutor.<init>(DriverCommandExecutor.java:46)
 at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:165)
 at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:107)
 at SampleTest.setUp(SampleTest.java:21)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

長い・・・
正直1行目しか読んでない.
「そんなメソッド知らねーよ( ・A・)=Cく ´Д`;)」とか言われたので何か足りないのかと考えて探し回った挙句たどり着いた答えがここの一番下の書き込み.
なんかダブって競合してんじゃね?
Playのバージョンに依るのかはわからないけど, Playプロジェクト作成時, なにやらファイルをいくつかダブらせてパスをお通しになるらしい.(尚この時点での使用verは2.1-RC1)
なのでビルドパスから外してやりましょう. ※1
外すのは
commocs-codec.jarの1.3
htmlclient.jarの4.0.1
httpcore.jarの4.0.1
もちろん他との兼ね合いも考慮すべきだろうけど, 今回はこの3つにverのこだわりは無いので古いほうをカット.

これでOK.

B-1. 実験(適当なPlayプロジェクトの作成)

実際に試してみた Playも最新2.1.0にアップデート
まずは適当にPlayプロジェクト作成→eclipseプロジェクトにする.
プロジェクトを作りタイところでcmdを開き
play new SeleniumTest
ちょっと長いけど前にまとめて?いるので今回はさらっと
SeleniumTestなる適当なプロジェクトを作成. cdコマンドかなんかで作ったプロジェクトに入ってから
play eclipse
eclipseプロジェクトとして認識してもらえるようにする.
ついでに
play run
して走らせておく. でないとテストできない(・ω・`)
これで localhost:9000 にPlayのチュートリアルを表示し続けるアプリが起動しているはず.
走らせたら今度は eclipseでプロジェクトを importする.

B-2. 実験(テスト作成)

importに成功したらまずやるのはビルドパスの修正. 上に述べたとおり余計なパスを削除する.
プロジェクトのビルドパスを開き,
commocs-codec.jarの1.3
httpclient.jarの4.0.1
httpcore.jarの4.0.1
の3つを探して Removeする. 数が多くて目が痛くなる…('A`)

削除したらテストコードの作成
testディレクトリなんて折角作ってくれているしここに入れましょう. (play testコマンドに反応するので注意)

テストコードはシンプルに
public class SampleTest {

  WebDriver driver;
  String url = "localhost:9000";

  @Before
  public void setUp() throws Exception {
    driver = new FirefoxDriver();
    driver.get(url);
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void test() {
    assertTrue(driver.getPageSource().contains("Welcome"));
  }
}

ただ localhost:9000をFirefoxで開いて 「Welcome」の文字列が表示されているかのテスト.

B-3. 実験(実行)

コードができたら 実行→jUnit test.

ようやっと走ってくれました.







無駄に遠回りしたのにまとめると実は3行でおkレベルだったときの疲労感…('A`)疲れた




※1 : 02/26追記 : だからといって全部が全部「ダブってんじゃね?」とか疑うのはやめましょう. まずはほんとに無いのか確かめましょう. 地獄を見ます('A`)

2013年2月12日火曜日

Selenium2使ってみた

Playで作ってるものも形になってきたのでいよいよテスト. そこで挙がった名前が

Selenium2

しかし「名前ちょっと聞いたことあるかなー」程度の知識だったのでイロイロ調べて簡単に使ってみた記録をメモメモφ(・ω・ )

Selenium2使ってみた

1. そもそもSelenium2って?

SeleniumはWebアプリケーションのUIテスト用フレームワーク. 簡単に言えば, 「ページ上でこう動いて欲しいなーなんて動きをコードで作って自動でテストしてくれる」ようなものを作れる. なんかニホンゴヘンダorz
2があるからには1があり, そのバージョンアップ. 具体的にはSimon Stwart氏作成の「WebDriver」をSelenium1に統合したものが2ということらしい. WebDriverの持つオブジェクト指向なAPIを取り込んでさらにできるようになったらしい. 1を知らないからなんとも言えないけど.
以上薀蓄

2. 言語と対応ブラウザ

言語は
javaC#RubyPython
の4種類. 1の時代にはPHPとかもあったらしいけどWebDriver統合時にWebDriverの方が対応していなかったため切り捨てられたとか(・ω・`)

また対応ブラウザは
Firefox
Google Chrome
IE
Opera
Apple iPhone
Android ブラウザ
Safari(ver2.21.0より)
となかなか豊富.BlackBerryは対応予定とだけ見たけど未確認. もう対応してるのかね('A`)
まぁ基本は上3つか.
ちなみにこれらはもちろんこのメモ書いてる時点でのお話.
この時点でのバージョンは2.29.0
マイナーチェンジしすぎだろ・・・(・ω・`)

3. Selenium-ServerとWebDriver

この辺正直よくわからないヽ('A`)ノ
Selenium-Serverは実際にブラウザを動かす係. これが無いとテストできない.
対応ブラウザにいっぱい書いたが, 実は標準ではIE と Firefox しかサポートしていないという事実. Opera/Chromeを使うなら別途サードパーティ製のServerが必要になるので注意. まぁ割と簡単な手順なんだけどね.
特にChromeに関しては比較的安心して使えるとかなんとか.
iPhoneとAndroid, Safariは未確認.

4-a. 入手

ここからまずは必要なファイルを入手.
必要なのは
Selenium-java-"ver".zip
Selenium-server-"ver".zip
の2つ. "ver"の部分にはもちろん数字が入ります.
他にも先に書いたとおり, Chromeでテストするにはこちらから
chromedriver_win_"ver".zip
が必要. "ver"の部分がバージョンじゃなかったらごめんなさい. この時点では26.0.1383.0. バージョンか?これ.

2014/01/24 追記
何やら場所が変わったみたいです
こちら
上記のページの 「Download chromedriver」 の先になります
追記・2
きちんと最新をもらってこないと、
unknown command 'waitforalltabstostoploading'
でググることになりそうです orz

4-b. 導入

必要なものを入手したら解凍, 今度はテストプロジェクトを作る.
プロジェクトにSelenium-javaおよびSelenium-serverに入っているsrcs以外のjarをとにかくパスを通す. 適当にぶち込んで設定から読み込んでやればOK. この時両方に「libs」ディレクトリがあるが, 中身は同じなのでどちらかひとつを入れればいい.
具体的には
selenium-java-"ver".jar
Selenium-server-"ver".jar
Selenium-server-standalone-"ver".jar
libsディレクトリの中身全部
を全部通す.
すっごいにぎやかになります.
ついでにどこかにchromedriver.exeも放り込んでおこう. なるべくコード中でパスがわかりやすいところに.(自分はパスすっごい苦手なので直下に「selenium」ディレクトリ作って全部放り込む始末orz)
これで準備はOK.

5. 簡単なコード1

ためしに簡単なコードで動きを見る. ちなみにもちろんJava. 他の言語書けない(・ω・`) テスト対象はPlayのWebアプリケーションなので, 事前に play runしておく.
public class Example {
  public static void main(final String[] args) {
    WebDriver driver = new FirefoxDriver();
    driver.get("http://localhost:9000");
    driver.quit();
  }
}
まだローカルでplayアプリを走らせている状態. 懐かしきmain関数.
3行目で使用するブラウザを選択. 今回はFirefoxでやってみる. これがWebDriver統合の強み?
4行目で立ち上げたブラウザにURLを入力, getしてもらう. このgetメソッド, ブラウザにきちんと表示されるまで先に処理が進まないので注意. 逆に言うとこのメソッドが終わった時点で画面は表示されているものとしてこの先の処理を書いていける. 実にありがたい.
5行目はブラウザの終了メソッド. これをしないといつまでもブラウザが居座り続けます. 今はいいけどテストがの量が増えたときは・・・Σ(||゚Д゚)ヒィィィィ

これを実行→JavaApplicationで実行するとFirefox起動→アプリ表示!→終了!!となる. まだテストには程遠い・・・
なお今回はPlayで作ったアプリのテストなので localhost:9000 だけど,  http://www.google.co.jpにするとグーグルのトップを開いて即終了します

6. 簡単なコード2

こんどはChromeでテストがしたい. ので4-b. にあるとおりドライバを用意しましょう.
コードもjUnitTestcaseを使用. jUnit4で.

@Test
public class Example {
  public static void main(final String[] args) {
    System.setProperty("webdriver.chrome.driver", "selenium/chromedriver.exe");
    String strURL = "localhost:9000/";
    WebDriver driver = new ChromeDriver();
    driver.get(strURL);
    WebElement element = driver.findElement(By.id("id"));
    element.sendKeys("id");
    element = driver.findElement(By.id("password"));
    element.sendKeys("pass");
    element.submit();
    assertThat(driver.getTitle(), is("ホーム"));
    driver.quit();
  }
}
ほぼまんまiUnit.  importするのは
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
のあたり. なんか isみたいに打ち消し線出るけど大丈夫なのだろうか….

なおこのアプリは localhost:9000 を入力すると, idと パスワードを入力してログインするだけの簡単なページに出る.

4行目が拾ったchromedriverの宣言. これが無いとChromeではテストができない. まだ直下/seleniumにしまってあるorz
6行目で今度は WebDriverは ChromeDriverで newする.
7行目で getしたらいよいよテスト.
8行目,  findElement()は引数の条件に一致する, 現在開いているHTMLの中で最初に見つかった要素を返す.
引数の By.id("id")は, HTMLタグの id のこと. 他にも name等でも検索できる. がそのHTML中に該当するものが無ければエラーが返るので注意. ここでログイン idを入力するフォームを探している.
9行目 sendKey()は引数の値(文字列)を, 指定したフォームに入力するメソッド. この場合 8行目で見つけた idの入力フォームに "「id」 と入力する, というだけの動き.
この時も element が入力を受け付ける要素ではない場合エラーが返る.
10, 11行目も同様に, こんどはログインパスワードの入力フォームを取得 → 「pass」と入力.
12行目の submit()で elementのある formを submitする. この場合は最後に elementにはパスワード入力フォームが入っているので, これを子要素に持つ formがあればそれを submitする. やっぱりそんなものが無ければエラー. 何かとエラーが返ってくる.
13行目がいよいよチェック. ここまでの入力でログインが済んだはずなので, タイトルは ホーム になっているはず, というテスト.

これを今度は 実行→jUnitTestCaseで実行.
おなじみのウィンドウが登場し, テストの進行状況と結果を表示してくれるはず.

他にも, HTML文の中に指定の文字列が含まれているか探す
driver.contains()などもある.

とりあえずここまでで "それっぽく" Selenium2は動かせるはず.






次はどこをテストするかだなー(・ω・`)

2013年2月6日水曜日

SyntaxHighligterの導入方法(振り返り)

一個前の記事を書いている際
・・・あれ?JavaScriptの設定してない・・・?Σ(・д・`)


という事実の発覚により入れなおし
忘れかけていたのでメモメモφ(・ω・ )

SyntaxHighlighter設定

もちろん対象はBlogger.

1. コード生成

コードとか言うとアレだけど要はリンクの生成.
ここから生成できます.
決める項目は二つ
ひとつはテーマ. これはお好みで. こことかカタログチックになってて選びやすいかと. こーいうところあると助かります.
もうひとつが使用言語. これはブログ中でSyntaxHighlighterに載せたい/載せる予定の言語を選ぶ. あんま選びすぎると重いとか聞いた気がしたけど未確認. おそらく自分の趣味の範囲とかと相談か.
二つ設定したら Generate.
すると次のページにテキストエリアにリンクやらスクリプトやらいっぱいのタグが出たはず.
これが生成されたリンク. 全部コピーしておきましょう.

2. 設定

設定というかリンクの埋め込みというか.
Bloggerのマイブログからテンプレート→HTMLの編集へ
選択しているテンプレートのHTMLなのかがずらっと出てくるけど, 用があるのは<header>.
わかりやすいように</header>の直前あたりを選ぶといい. ctrl + F から検索をかけるとだいぶ楽になるハズ.
選んだ場所に1. で生成したコードを埋め込む. もろコピペ. てゆーかいじっちゃダメ.


これで準備はOKなはず.
なおテンプレートを変えると全部消えてしまうので, 変えるときは一緒に設定のしなおしが必要.


3. 実際に使用

これはシンプル.
投稿作成を開いてHTMLで記入するモードに変更.
普通にHTMLを書くように
<pre class="brush:使用言語ごとのブラシ名">ハイライトしたいコード</pre>
と書き込んでプレビューすると, あら不思議.


なおオプションで
・左の行数表示のカスタム
・コードのコピーなどのツールボックス
なんてのも設定できるらしい



気が向いたらやってみる(´・ω・`)イツニナルカワカラナイガナ

スクリプトでcheckboxの一括選択/解除

Playでページ作っていく際に
テーブルの中にある複数のチェックボックスを一括で選択/解除できるチェックボックスが欲しいなー
って事で
意外とテーブルの中なんかで起こりやすい「一つのformタグにまとめられない状況」の例が見当たらなかったのでこれ幸いにとメモメモφ(・ω・ )


checkbox一括選択/解除

なおjQuery使います. var. 1.9.0

といってもたいしたコードでもないのでさくっと

function allHoge{
    $(".childHoge").prop("checked", $("#parentHoge").is(":checked")));
}

一行でしたorz
parentHogeを全選択/解除のキーとなるチェックボックスやボタンに id として設定.
childHogeを上に影響されるチェックボックス全てに class として設定
もちろん名前は適当なのでお好みで
最後にparentHogeを設定した同じところにでも
onclick="allHoge()"
と設定してやるとOK.
ボタンかチェックボックスか全選択/解除をクリックするごとに
childHogeと設定したチェックボックスが切り替わる.

以下簡単に内容
$("#parentHoge").is(":checked")
jQueryの is( )メソッド.
引数内の要素を持っているか否かでtrue か falseを返す.
この場合は
:checked
を持っているか否か, すなわちチェックされているか否かをtrue/falseで取得する.
ここで全選択/解除のどちらが選ばれたかを取得する

$(".childHoge").prop("checked", true/false);
ちょっと置き換えて見やすく(?)
jQueryの prop()メソッド
引数内のマップで操作を行なう
この場合は checked要素の値を true/falseに変更する
という操作
これを組み合わせて
「子に指定したチェックボックスのチェック状態を親に指定したチェックボックスの状態と同じものに切り替える」
となる

ただこの .prop
似たようなものに .attrというものがある.
こちらを使うと最初の1回だけ同じように動いてくれるが, 2回目以降は全選択ができなくなる.
おそらくだがHTML上だけ書き換えてプロパティとしては反映されていない感じ
何というトラップ・・・('A`)

こことか参考になるかと








雪やまないかなぁ・・・('A`)


AWS CDKで立てたEC2インスタンスのTimeZoneとかいじりたかった話

EC2を立てることはできたけど、立てたインスタンスは UTCのままだし設定ファイルとかいちいちscpしてくるのはダルい。 当初UserDataでなんとかしようとしたものの、「書く量がヤバいしメンテしにくい」と悩んでいたところ見かけたのが  AWS::CloudFormation:...