4395


Pagination のテストのために、最初は以下のようなコードを書いていたのですが、一つのページ内に複数のPagination
を表示するページなので、一番上のブロックのみを確認することにしました。

[code]

    find("//*[@class='pagination']//a[text()='2']").click
    expect(page.status_code).to eq(200)
    
[/code]

これに、以下のように `*[@class='pagination']` の末尾に `[1]` を追加したのですが
`Capybara::ElementNotFound` になってしまいます。

[code]

    find("//*[@class='pagination'][1]//a[text()='2']").click
    expect(page.status_code).to eq(200)
    
[/code]

Test 環境ではなく Development 環境になりますが、既に Pagination
の2ページ目が存在する環境で以下のようにすれば要素を取得できることが確認できました。

[code]

    doc = Nokogiri::HTML(open "http://localhost:3000/")
    doc.xpath("//*[@class='pagination'][1]//a[text()='2']")
    
[/code]

Capybara が採用している XPath と Nokogiri の XPath にはなにか違いがあるのでしょうか？

### `click`メソッドを呼び出さないなら使える

[code]

    expect(page).to have_xpath("//*[@class='pagination'][1]//a[text()='2']")
    
[/code]

という風に呼び出す場合ならエラーになりませんでした。


CC BY-SA 3.0
2015-01-10T16:45:38.590
4384
2015-01-12T19:34:09.190
2015-01-12T05:37:11.870
3271
3271
question
ruby rspec capybara xpath
Capybara で XPath を用いて n 番目の要素を見つけられない


XPathを使わなくても `all` を使うと簡潔に書けます。

[code]

    all('.pagination')[1].click_link('2')
    
[/code]

`all`は指定したクラスに合致する全ての要素を配列して返します。なので、`[1]`を指定すると、2番目の pagination を取得できます。

あとは、その中にある「2」のリンクをクリックすればOKです。

試してみてください。

ちなみに僕の経験上、Capybaraを使ったテストではXPathはほとんど使いません。  
Capybara標準のAPIを駆使するか、テストしやすいようにview側にclassを追加することの方が多いです。  
ご参考までに。

**EDIT**

XPathでうまくいかない原因がわかりました。  
デフォルトはCSSで検索しようとするので、オプション引数でXPathを使うことを明示する必要があります。

[code]

    find(:xpath, "//*[@class='pagination'][1]//a[text()='2']").click
    
[/code]

おそらくエラーメッセージには以下のように書かれていたはずです。

[code]

    Capybara::ElementNotFound: Unable to find css "//*[@class='pagination'][1]//a[text()='2']"
    ./spec/features/users_spec.rb:61:in `block (2 levels) in <top (required)>'
    -e:1:in `<main>'
    
[/code]

"Unable to find
css"というのが、原因を特定するヒントになっているので、エラーメッセージ全体を載せてもらうともう少し早く解決できたかもしれません。

参考までにCapybaraのFinder APIのリンクを載せておきます。

<http://www.rubydoc.info/github/jnicklas/capybara/Capybara/Node/Finders>


CC BY-SA 3.0
2015-01-11T05:54:39.373
4395
2015-01-12T19:34:09.190
2015-01-12T19:34:09.190
85
85
4384
answer