...
<
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