タイトル通りの内容です。 フィーチャーテストをする際に、dd, dtの値を関連づけて取ることでテストをわかりやすく、書きやすくしたいと思いました。
問題
<dl> <dt id="family-name" class="label">f_name</dt> <dd class="data--string">family</dd> <dt id="given-name" class="label">g_name</dt> <dd class="data--string">given</dd> <dl>
上のfamilyと言う<dd>の値をラベルf_name経由で取得したい。Capybaraであれば、find("dd.data--string")で取得可能ですが、該当するものが2つあり(更に表示が増える可能性も今後ある)、find_all("dd.data--string").firstとかで順番を指定して取るのも可読性が低いと思うので、f_nameラベルの隣の要素として取得できないかと思いました。
解決
find("dt#family-name", text: "f_name").find("+dd").text # =>"family" find("dt#family-name", text: "f_name").first(:xpath, './following-sibling::dd').text # => "family"
上のどちらでも希望通りの値が取得可能です。
余談ですが、こちらで紹介した、CapybaraのJavaScriptのテスト時では前者の+を用いた手法はエラーになって使えないので注意。
sibling()
siblingと言うメソッドも用意されていて、find("dt#family-name", text: "f_name").sibling("dd")といった形で使います。しかし、このメソッドはfind()見つけた要素と横並びになっている(兄弟?)タグを探索します。ですので、今書いたコードを最初のhtmlに使用すると、ddが2つ見つかってしまいエラーになるので注意。(find()の仕様と同じ。詳しくはリファレンスで)