miau's blog?

document.evaluate の評価って一回きり?

※勘違いによって書かれたエントリーです。末尾に追記しているので、そちらもあわせてご覧ください。

今やってる案件で「ラジオボタンが切り替わったら現在日付が自動入力される」みたいな画面がありまして。これを Selenium IDE でテストしようとして、

|click|radio_button||
|assertElementNotPresent|//input[@id='datetime_field' and @value='']||

みたいなケースを作ったんですが、これが通らない。どうも @value が JavaScript での変更前の値になっている様子。

検索ワードが悪いのか、ググってもこの辺の情報がなかなか見当たらなくて。なんか常識だったり検証方法が間違ってたりするかもしれませんが、簡単に検証してみました。




■検証用ページ

xpath_test.html

ソースはこんな感じです。

<html>
<head>
<title>XPath Test</title>
<!--[if IE]>
<script type="text/javascript" src="http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest.js"></script>
<![endif]-->
</head>
<body>
<input type="text/javascript" id="hoge" value="before">
<script>
alert(document.evaluate("//input/@value", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.nodeValue);
document.getElementById('hoge').value = 'after';
alert(document.evaluate("//input/@value", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.nodeValue);
</script>
</body></html>

(1) 元々 before と表示しているフィールドがある
(2) 元の値を表示する
(3) JavaScript でフィールドの値を書き換える
(4) 書き換え後の値を表示する
という流れですね。

IE の場合だけ JavaScript-XPath を使うようにしてます。たぶん <!--[if IE]>〜<![endif]--> で囲まなくても javascript-xpath のほうでうまいことやってくれるんでしょうけど、自信がなかったので念のため。

■結果

・Firefox 3.0.8、Opera 9.6.4、Safari 3.1.1、Chrome 2.0.174.0(最新じゃなくて、手元にあった適当なバージョンです)
 →before / before
・IE 6.0.3790.3959 SP2
 →before / after

みたいな感じ。組み込みの XPath を使っている場合は、JavaScript で値を書き換えても XPath からは書き換え前の値が取得されてしまうと。

まあ、XPath の本来の用途を考えれば当たり前の動作かもしれないんですが、Selenium でテストを書く場合はちゃんと内容が書き換わってくれたほうが嬉しいですね・・・。で、この辺のアイテム に書いた「Seleinium IDE から JavaScript-XPath が使えるようになれば嬉しい」みたいな話につながる・・・と思いきや、よく考えたら JavaScript-XPath は組み込みの XPath がある場合は(たぶん)何もしないわけで。強制的に JavaScript-XPath のほうを使うようなオプションが必要なのかもしれませんね。

■とりあえずの対処

今回は

|assertElementNotPresent|//input[@id='datetime_field' and @value='']||



|assertNotValue|datetime_field||

と書けばいいだけの話なのでいいんですが。たまに XPath じゃないとチェックしにくいような箇所が出てくるのでちょっと困ります。

XPath の再評価(キャッシュを削除?)する方法でもあればいいんですけど・・・そういうのあるんでしょうか?


(2009-04-23 追記)

はてブ でさっそくご指摘が。ありがとうございます。

amachang: XPath 式がキャッシュされていることが原因ではなく、
input.value = 'hoge'; だと属性値が変わらないことが原因だと思います。
input.setAttribute('value', 'hoge'); を試してみてください。

とのこと。そういえばそんな話あったー。

試してみると・・・

xpath_test2.html

ちゃんと Firefox、Opera、Chrome なんかでも before/after になりました。XPath がキャッシュされているわけではないと。

今回は値を指定している箇所が自作の JavaScript だから、ここを書き換えれば対応できますよと。Selenium の type の処理はどうなってるんだったかな・・・。(さらに追記するかも。)


ちなみに「そんな話あった」と書いたけど、これまた勘違いでした。

IE の getAttribute / setAttribute: Days on the Moon

IE だけうまくいっていたのがこれと関係あるのかなと思ったんですけど、別の話ですね。うーん。ちゃんと理解できてない。
posted at 12:42:53 on 2009-04-22 by miau - Category: General No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。