Watir WebDriver の browser.execute_script コマンドを使用して特定の JavaScript スニペットを実行する際に問題があります。
問題のJavascriptは次のとおりです。
var bodyFrame = document.getElementsByName("BodyFrame")[0];
var bodyFrameDoc = bodyFrame.contentDocument || bodyFrame.contentWindow.document;
var mainFrame = bodyFrameDoc.getElementById("MainFrame");
var mainFrameDoc = mainFrame.contentDocument || mainFrame.contentWindow.document;
var row = mainFrameDoc.getElementById("DETAIL_1");
var rowNodes = row.childNodes;
var index;
for (index = 0; index < rowNodes.length; index++) {
if (rowNodes[index].firstChild.id === 'ID1') {
rowNodes[index].firstChild.value = 'ACCRUL';
}
if (rowNodes[index].firstChild.id === 'ID2') {
rowNodes[index].firstChild.value = 'OP';
}
if (rowNodes[index].firstChild.id === 'ID3') {
rowNodes[index].firstChild.value = 'Z';
}
if (rowNodes[index].firstChild.id === 'ID4') {
rowNodes[index].firstChild.value = 'FIRST';
}
if (rowNodes[index].firstChild.id === 'ID5') {
rowNodes[index].firstChild.value = 'AUT';
}
if (rowNodes[index].firstChild.id === 'ID6') {
rowNodes[index].firstChild.value = 'AU1000';
}
if (rowNodes[index].firstChild.id === 'ID7') {
rowNodes[index].firstChild.value = 'm tax m entity m jc';
}
if (rowNodes[index].firstChild.id === 'ID8') {
rowNodes[index].firstChild.value = 'MR5001100';
}
if (rowNodes[index].firstChild.id === 'ID9') {
rowNodes[index].firstChild.value = 'T';
}
if (rowNodes[index].firstChild.id === 'ID10') {
rowNodes[index].firstChild.value = '453.36';
}
}
なぜ私はそのような残虐行為を使わなければならないのですか?まあ、私がテストを開発している製品はそれほど悪いからです。各セルは同じ id 属性を使用するため、ドキュメント内のオブジェクトに直接ゾーンインすることはできません。さらに悪いことに、ドキュメントの深さは 2 フレームです。フレームセプション。
明らかな解決策 (watir-webdriver の API を使用) を使用することは、32 のグリッド行を埋めるタスクが半分になるため、現実的ではありません!! 1時間の。
上記の Javascript を取得して、ブラウザーの開発者ツールで実行できます。(この製品でサポートされているブラウザーは、互換モードの IE8、9 のみです。) jQuery や派手な JavaScript ライブラリーにアクセスできません。この JavaScript を使用すると、ほぼ瞬時に行が埋められます。
browser.execute_script コマンドを使用してこれを実行すると、
Selenium::WebDriver::Error::JavascriptError: JavaScript error
不思議なことに、私がちょうど使用した場合
return document.getElementsByName("BodyFrame")[0];
次に、Net::HTTP ライブラリでエラーが発生します。これは、Selenium がスタック上のどこかでコマンドをブラウザに送受信するために使用されます。(具体的には: ERRNO::ERRCONNREFUSED)
ヘルプ?
編集:これは、コードを実行するために使用している直接のスクリプトです(そして、Javascriptの小さなビットを生成します):
def quick_fill(data = {})
reference_element.focus;
quick_filler = ->(element_id, value) {
"if (rowNodes[index].firstChild.id === '#{element_id}') {
rowNodes[index].firstChild.value = '#{value}';
}"
}
row_id = row.attribute(:id)
element_ids = Hash[data.keys.map { |key| [key, send("#{key}_element").attribute(:id)] }]
javascript = <<-JAVASCRIPT
var bodyFrame = document.getElementsByName("BodyFrame")[0];
var bodyFrameDoc = bodyFrame.contentDocument || bodyFrame.contentWindow.document;
var mainFrame = bodyFrameDoc.getElementById("MainFrame");
var mainFrameDoc = mainFrame.contentDocument || mainFrame.contentWindow.document;
var row = mainFrameDoc.getElementById("DETAIL_1");
var rowNodes = row.childNodes;
var index;
for (index = 0; index < rowNodes.length; index += 1) {
#{element_ids.map { |method, element_id| quick_filler.call(element_id, data[method]) }.join("\n") }
}
JAVASCRIPT
puts javascript
sleep(0.500)
browser.execute_script(javascript)
end
このメソッドの data 引数はキーと値のペアのハッシュです。キーはページ オブジェクト アクセサーに提供されるメソッドの名前で、値は入力しようとしている値です。中間プロセスの一部として、ページ オブジェクト要素から id 要素を取得します (これは、各要素の識別子として提供されます)。
ページ クラスの設定方法には、少し特殊な構造があります。基本的な考え方は次のとおりです。
class MyPage
include PageObject
table(:some_table, ...)
def add_line_item(data = {})
GridRow.new(some_table_element.last_row, browser).quick_fill(data)
end
class GridRow
include PageObject
#page object accessors
text_field(:my_field) { row.text_field_element(id: 'ID1') }
#etc
def quick_fill(data = {})
#see above
end
def initialize(row, browser, visit = false)
@row = row
super(browser, visit)
end
end
end
したがって、呼び出しの例は次のようになります (きゅうりのテストから)
on_page(MyPage) do |page|
page.add_line_item(:my_detail => 'myValue')
end
これに加えて、このページに到達するためにいくつかの 'attach_window' 呼び出しが必要であるという不幸な問題があります (ページが一種のモーダル ダイアログにあるため)。この問題は、この相互作用に大きく関係している可能性があります。これが問題を引き起こすと私が考えることができる唯一のことです。
このSOの質問のポイントは、明らかなエラーを除外できる2番目の目を持っていることを願っています. 採用を計画している別の回避策があります。