...<frameset rows="100%,0,0,0" onload="gotoUrl('/here_is_the_url',null)"> <frame frameborder="0" name="frame1" src="about:blank"> <html> <head>...</head> <body> <div id="divID">...</div> </body> </html> </frame> <frame scrolling="no" noresize="" frameborder="0" name="frame2" src="about:blank">...</frame> <frame scrolling="no" noresize="" frameborder="0" name="frame3" src="about:blank">...</frame> <frame scrolling="no" noresize="" frameborder="0" name="frame4" src="about:blank">...</frame> <noframes> <body bgcolor="#FFFFFF"> <p>your browser does not handle frames</p> </body> </noframes></frameset>...In my case, I want to find the div element byID. I tried:
Browser frame = Manager.ActiveBrowser.Frames["frame1"];Element divEle = frame.Find.byId("divID");but I get a FindException. I debugged and I noticed that the DOM root element of the frame1 is null. Any DOM refresh had no effect. I tried to refresh root browser an all frames containing.
I used Firefox 3.5.16 and WebAii 2010.3.1213.0
How can I get the div element?
9 Answers, 1 is accepted
As I understand the HTML specification, it is not legal to have anything but a <frame> element or another <frameset> element inside of a <frameset> element. Thus your example with other HTML tags embedded inside of a <frameset> looks like illegal HTML to me and no our framework does not work with this illegal structure.
If you put your embedded HTML into a separate document and reference that document in the src of a <frame> the you can reference the HTML the way you expect.
Cody
I tested same website with an older version of the webaii framework. I was able to get full DOM tree of the seperate frames inside. And I expected that newer versions doesn't support less functionality.
Maybe we're looking at it somewhat differently. Agreed the HTML specification allows the child elements: <frame>, <frameset> and <noframes> but nothing else. So my question is, is this piece of HTML contained within your frameset.html file or is it actually contained within a referenced src file such as a referenced.html file?
<html> <head>...</head> <body> <div id="divID">...</div> </body> </html>It is my understanding that the above HTML may not be placed inside of a <frameset> or <frame> element within a frame.html file. As a test I created a set of files to show what does happen when I try. I have attached my test file set. I used this code to try to access elements in it the frameset file and the referenced frames files.
{ Element divF1 = ActiveBrowser.Find.ById("divF1"); Element divF2 = ActiveBrowser.Find.ById("divF2"); ActiveBrowser.Frames["frame_a"].RefreshDomTree(); ActiveBrowser.Frames["frame_b"].RefreshDomTree(); ActiveBrowser.Frames["frame_c"].RefreshDomTree(); ActiveBrowser.Frames["frame_d"].RefreshDomTree(); ActiveBrowser.Frames["frame_e"].RefreshDomTree(); Element divA = ActiveBrowser.Frames["frame_a"].Find.ById("divA"); Element divB = ActiveBrowser.Frames["frame_b"].Find.ById("divB"); Element divC = ActiveBrowser.Frames["frame_c"].Find.ById("divC"); Element divD = ActiveBrowser.Frames["frame_d"].Find.ById("divD"); logValue(divF1); logValue(divF2); logValue(divA); logValue(divB); logValue(divC); logValue(divD); Log.WriteLine(ActiveBrowser.Frames["frame_e"].ViewSourceString);}private void logValue(Element value){ Log.WriteLine(value == null ? "null" : value.ToString());}My resulting log shows this:
'2/9/2011 5:31:34 PM' - 'Pass' : 1. Navigate to : 'C:\Users\gibson\Documents\My Web Sites\FrameSets.html''2/9/2011 5:31:34 PM' - LOG: null'2/9/2011 5:31:34 PM' - LOG: null'2/9/2011 5:31:34 PM' - LOG: [Element: 'div:0' (id=divA)]'2/9/2011 5:31:34 PM' - LOG: [Element: 'div:0' (id=divB)]'2/9/2011 5:31:34 PM' - LOG: [Element: 'div:0' (id=divC)]'2/9/2011 5:31:34 PM' - LOG: [Element: 'div:0' (id=divD)]'2/9/2011 5:31:34 PM' - LOG: <HTML><HEAD></HEAD><BODY></BODY></HTML>'2/9/2011 5:31:34 PM' - 'Pass' : 2. [MyCustomStep] : MyCustom Step Description------------------------------------------------------------'2/9/2011 5:31:34 PM' - Overall Result: Pass'2/9/2011 5:31:34 PM' - Duration: [0 min: 1 sec: 42 msec]------------------------------------------------------------'2/9/2011 5:31:35 PM' - Test completed!The clincher is that the source string for frame_e is empty, which is just what I'd expect it to be given a src="about:blank" setting.
Regards,
Cody
/here_is_the_url". Okay, I did not write exactly.The referenced HTML site is loaded with the combination "
onload="gotoUrl('/here_is_the_url',null)" and it is displayed in the first frame row. With Firebug I can see the loaded elements in the DOM tree, but WebAii don't see them.I tried to load the referenced HTML site in a seperate browser
:
Browser.NavigateTo("domain/here_is_the_url");
then I get the div element. But the whole website doesn't work correctly without surrounding frames.Is there any workaround to get elements inside dynamically loaded frames?
Maybe all we need is a simple Refresh like this:
Browser frame = Manager.ActiveBrowser.Frames["frame1"];frame.RefreshDomTree();Element divEle = frame.Find.ById("divID");Cody
Browser.RefreshDomTree();Browser.Frames.RefreshAllDomTrees();Browser.Frames["frame"].RefreshDomTree();But the DOM root element of the frame is still null.
Ok, I see. Please send me a set of test files I can run locally to reproduce this problem (you can put them into a .zip file and attach it to a forum post) or point me to a publicly accessible website I can use to study this problem.
Kind regards,Cody
Thank you for the set of test files. I used your files with this test code and had no problems.
public void MyCustomStep(){ ActiveBrowser.Frames["frame_a"].RefreshDomTree(); ActiveBrowser.Frames["frame_b"].RefreshDomTree(); ActiveBrowser.Frames["frame_c"].RefreshDomTree(); ActiveBrowser.Frames["GoTo"].RefreshDomTree(); Element divA = ActiveBrowser.Frames["frame_a"].Find.ById("divA"); Element divB = ActiveBrowser.Frames["frame_b"].Find.ById("divB"); Element divC = ActiveBrowser.Frames["frame_c"].Find.ById("divC"); Element divD = ActiveBrowser.Frames["Goto"].Find.ById("divD"); logValue(divA); logValue(divA.InnerText); logValue(divB); logValue(divB.InnerText); logValue(divC); logValue(divC.InnerText); logValue(divD);}private void logValue(Object value){ Log.WriteLine(value == null ? "null" : value.ToString());}My log output was this:
Overall Result: Pass------------------------------------------------------------'3/1/2011 4:00:26 PM' - Starting execution....'3/1/2011 4:00:27 PM' - Detected custom code in test. Locating test assembly: TestProject1.dll.'3/1/2011 4:00:27 PM' - Assembly Found: C:\Users\gibson\Documents\Visual Studio 2010\Projects\TestProject1\TestResults\gibson_GIBSON 2011-03-01 16_00_25\Out\TestProject1.dll'3/1/2011 4:00:27 PM' - Loading code class: 'TestProject1.FrameSet'.------------------------------------------------------------'3/1/2011 4:00:28 PM' - 'Pass' : 1. Navigate to : 'C:\Users\gibson\Documents\Support Issues\248881_FrameSetsFiles_onload\FrameSets.html''3/1/2011 4:00:28 PM' - LOG: [Element: 'div:0' (id=divA)]'3/1/2011 4:00:28 PM' - LOG: This is text in frame A.'3/1/2011 4:00:28 PM' - LOG: [Element: 'div:0' (id=divB)]'3/1/2011 4:00:28 PM' - LOG: This is text in frame B.'3/1/2011 4:00:28 PM' - LOG: [Element: 'div:0' (id=divC)]'3/1/2011 4:00:28 PM' - LOG: This is text in frame C.'3/1/2011 4:00:28 PM' - LOG: null'3/1/2011 4:00:28 PM' - 'Pass' : 2. [MyCustomStep] : MyCustom Step Description------------------------------------------------------------'3/1/2011 4:00:28 PM' - Overall Result: Pass'3/1/2011 4:00:28 PM' - Duration: [0 min: 0 sec: 918 msec]------------------------------------------------------------'3/1/2011 4:00:28 PM' - Test completed!The "Goto" frame is coming back as null, but I think that is to be expected. I actually retrieved the text out of "frame_a" as can be seen in the log.
Admittedly I used our Developer Edition, but the only thing it did for me was launch the browser and navigate to the test page. I wouldn't expect a functional difference with the code I used above. Greetings,
Cody