読者です 読者をやめる 読者になる 読者になる

within で対象を絞る

requesut spec で検証対象を絞る場合には within メソッドを使用する。
「"hoge"が表示されている」という検証は

page.should have_content("hoge")

とするが、これだとページ全体で検索するのでどこかに"hoge"があればOKになってしまう。
そこで登場するのが within 。セレクターで検証するエリアを決めてその中で検証する。

within(:xpath, "//table/tbody/tr[1]/td[1]") do
  page.should have_content("hoge")
end

これでテーブルの1つ目のtrの1つ目のtdの中に"hoge"があるという検証になる。
セレクターは css でも可能。

within のネストもできる。ただ、ネストしたところのセレクターにはちょっと注意が必要。
例えば…

within(:xpath, "//table/tbody/tr[1]/td[1]") do
  find(:xpath, "//input[@type='checkbox']").set(true)
end

これは within 内のチェックボックスをオンにするというもの。 check メソッドでチェックできるので
この方法はあまり使わないと思うが。
"//input[@type='checkbox']" としているので within の中で探すかと思ったら "//..." なのでページ全体
で検索しに行ってしまった。これではまった…。なので正しくは

within(:xpath, "//table/tbody/tr[1]/td[1]") do
  find(:xpath, ".//input[@type='checkbox']").set(true)
  find(:css, "input[type=checkbox]").set(true) # css セレクタ
end

とすればOK。単なる XPath の知識不足か。
css セレクタを使ったほうがいいかも。親を見る場合は xpath のほうが便利。