Reputation: 391
Below javascript code fetches the id and inner text of all the div elements starting with "opt1". I am doing this with javascript because this divs are invisible and webdriver doesn't support accessing invisible elements.
The below code works fine when executing on irb but fails with a "JavaScript error" when I run the whole script. I also executed the javascript code on the IE Console to make sure that javascript is correct and their were no errors.
mn = $browser.execute_script <<-JS
var eles = window.frames[1].document.getElementsByTagName('div');
var dom = [];
for ( var i = 0; i < eles.length; i++) {
if (eles[i].id.indexOf("opt1_") === 0) {
dom.push(eles[i].id + "--" + eles[i].innerText);
}
}
return dom;
JS
Can anyone help me on this.
Thanks in advance..
Upvotes: 2
Views: 760
Reputation: 46836
The problem is likely with the way that Selenium handles frames. It looks like the Javascript error will occur when trying to do anything with a frame - ie the error occurs due to:
window.frames[1].document
Solution - Execute Javascript in context of the frame
One solution is to run the Javascript in the context of the frame.
Assuming that the main page is using iframes (though similar can be done with frames):
<html>
<body>
<iframe src="test.htm"></iframe>
<iframe src="frame_content.htm"></iframe>
</body>
</html>
And the frame_content.htm has some visible and non-visible divs:
<html>
<body>
<div>irrelevant content</div>
<div id="opt1_visible">visible content</div>
<div id="opt1_hidden" style="display:none;">hidden content</div>
</body>
</html>
Then in Watir, you can execute the script (modified to remove window.frames[1]
) against the frame object (instead of the browser):
frame = browser.iframe(:index => 1) # Use .frame if the page is using frames instead
mn = frame.execute_script <<-JS
var eles = document.getElementsByTagName('div');
var dom = [];
for ( var i = 0; i < eles.length; i++) {
if (eles[i].id.indexOf("opt1_") === 0) {
dom.push(eles[i].id + "--" + eles[i].innerText);
}
}
return dom;
JS
p mn
#=> ["opt1_visible--visible content", "opt1_hidden--hidden content"]
Solution - Using just Watir
While Watir cannot perform actions on invisible elements, you can still inspect them. The only difficult one is getting the text since Element#text only returns visible text. The workaround is to use Element#attribute_value
instead.
You can get the same results as the Javascript approach by doing:
frame = b.iframe(:index => 1) # Use .frame if the page is using frames instead
mn = b.divs(:id => /^opt1_/).map do |div|
"#{div.id}--#{div.attribute_value('innerText')}"
end
p mn
#=> ["opt1_visible--visible content", "opt1_hidden--hidden content"]
Note that .attribute_value('innerText')
works in IE. If you are using Firefox you will need to do .attribute_value('textContent')
instead. I believe Chrome supports both attributes.
Upvotes: 2