海よりも深い事情のため導入方法より先に使い方を書きます。
導入方法は後で気が向いたら書きます。→ 気が向きました。
概要
以下で紹介する各種コマンドは、promise を返す。
promise はコマンドが実行されることで resolved (解決)される。
promise 達は 内部で勝手に 連結されていくので、
我々が .then などで連結していく必要は無い。
イメージとしては、activeObject パターンに近い。
describe "top page", ->
c = (n) -> console.log n
url = (path) -> "#{browser.baseUrl}#{path}"
beforeEach ->
c 1
browser.get(url "/top").then -> c 2
c 3
browser.waitForAngular().then -> c 4
c 5
it "LOGIN ボタンを押すと ログイン ページへ遷移する", ->
c 6
button = By.id("LOGIN").then (elm) -> c 7; elm
c 8
button.click().then -> c 9
c 10
expect(browser.getLocationAbsUrl().then (actual) -> c 11; actual).toEqual url "/login"
c 12
上記のテストを実行すると、ログには
1,3,5,2,4,6,7,8,10,12,9,11
の順に表示される(6,7,8 の並びに注意)。
実行順序としては、
- (1,3,5)… beforeEach の各種 コマンドが「登録される」(実行はされない)
- (2,4)… beforeEach で登録したコマンドが実行される
- (6,7,8,10,12)… it 内のコマンドが登録される。ただし、DOM の取得はその場で行われる
- (9,11)… it 内で登録したコマンドが実行される
コマンド覚書
使うたび追加していく感じで。
browser
browser.get someUrl
someUrl へアクセスする(というコマンドを登録する。以下「〜というコマンドを登録する」省略)
browser.waitForAngular()
angular による画面のレンダリングが終わるのを待つ
browser.getLocationAbsUrl()
現在の URL を取得する
By
本当は小文字の by というグローバル変数も用意されているが、by は CoffeeScript の予約語なので、大文字の By の方を使う。使い方は全く同じ。
By の各要素は関数であり、基本的には locator と呼ばれるオブジェクトを返す。あとで説明する element という関数にこの locator を渡すことで、該当する DOM 要素を検索し、それに対していろいろな指示を出すことが可能となる。
locator = By.id "hoge"
hoge = element locator
# つなげて書くと、
hoge = element By.id "hoge"
document.elementById に似ているので覚えやすい。
By.id someId
someId を使って要素を検索する(という locator を返す)
element
locator を受け取って、ElementFinder クラスのインスタンスを返す。
ElementFinder のインスタンスは再び element という要素を持ち、 子要素に絞って検索することが出来る。
parent = element By.id "parent"
child = parent.element By.id "child"