This is a migrated thread and some comments may be shown as answers.

Nested Iframes

7 Answers 199 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Gerald
Top achievements
Rank 1
Gerald asked on 19 Sep 2011, 03:28 PM
Hello,

I have a website with a frameset and nested iframes.
Please read the code to see where the problem occurs.

// Launch a browser instance
  Manager.LaunchNewBrowser(BrowserType.InternetExplorer);
  Manager.Current.ActiveBrowser.ClearCache(BrowserCacheType.TempFilesCache);
 
  // The active browser
  ActiveBrowser.NavigateTo("http://anydomain.com");
 
  // Find the google search box and set it to "Telerik";
  Find.ByName<HtmlInputText>("ctrlLogin$txtUser").Text = "user";
 
  // Click the Search button
  var loginButton = Find.ByExpression<HtmlSpan>(new HtmlFindExpression("TextContent=~Login", "class=Button_Text"));
  loginButton.Click();
   
  ActiveBrowser.WaitUntilReady();
 
  var mainFrame = ActiveBrowser.Frames["frMain"];
  //mainFrame.RefreshDomTree();
 
  //workFrame is found, workFrame is an iFrame
  var workFrame = mainFrame.WaitForElement(5000, "id=WorkFrame");
  
---- PROBLEM STARTS HERE ---
 
  // form is null here
  var form = new HtmlControl(workFrame).Find.ById<HtmlForm>("MyStart");
 
  var td = form.Find.ByAttributes<HtmlTableCell>("class=login_value");
  var loginName = td.InnerText;

How can I wait for the Iframe to finish loading? At the moment I cannot find the tags I am searching for.

Any ideas?

Thank you for your help!

7 Answers, 1 is accepted

Sort by
0
Anthony
Telerik team
answered on 19 Sep 2011, 04:30 PM
Hello Gerald,
 
The Frames collection contains a flat list of all frames on the page regardless of their nesting. It is unnecessary to access the SubFrame via the MainFrame. You can identify it directly.

Here is sample code that navigates to a page that contains three frames. One of those frames contains two sub-frames. One of those sub-frames points to bing.com.

Manager.LaunchNewBrowser();
ActiveBrowser.NavigateTo("c:\\html\\frame.html");
 
ArtOfTest.WebAii.Core.Browser frSub = ActiveBrowser.Frames["subFrame2"];
frSub.RefreshDomTree();
 
HtmlInputText input = frSub.Find.ByExpression<HtmlInputText>("id=sb_form_q");
input.Text = "Telerik";
 
HtmlInputSubmit search = frSub.Find.ByExpression<HtmlInputSubmit>("id=sb_form_go");
search.Click();


Greetings,
Anthony
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Anthony
Telerik team
answered on 19 Sep 2011, 04:31 PM
Hi Gerald,

Please see this article for more information on Frames Support in code.

Regards,
Anthony
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Gerald
Top achievements
Rank 1
answered on 20 Sep 2011, 09:08 AM
Hello Anthony,

thank you for your quick response. I will give you a little more insight into my html code for a better understanding.

<frameset rows="0,*" cols="*" border="0" frameBorder="NO" frameSpacing="0">
    <frame name="frController" src="controller.aspx" marginWidth="0" marginHeight="0" noResize="">
    <frame name="frMain" src="loading.aspx" noResize="" scrolling="no">
        <iframe name="WorkFrame" id="WorkFrame" src="Static/WorkFrame.htm">
            <iframe id="divForm_0_0_0" src="../Framework/MyStart_tabbed.aspx">
                <table align="right" style="margin-top: 0px; margin-bottom: 0px;" border="0" cellSpacing="0">
                    <tbody>
                        <tr>
                            <td align="left" class="login_value">

ActiveBrowser.Frames.Count is 1.

I can access ActiveBrowser.Frames["frMain"], but ActiveBrowser.Frames["frMain"].Frames.Count is 0 even if I wait for the Element "WorkFrame" to be loaded.

I hope the issue now is more clear to you.

Thanks for your support!

Best regards
Gerald

0
Accepted
Anthony
Telerik team
answered on 21 Sep 2011, 04:11 PM
Hello Gerald,

This is expected behavior. Again, because the Frames collection contains a flat list of all frames on the page, the count of sub-frames within a frame is expected to be zero. Also, frames are not treated as elements so you cannot reference them as such.

Here are three sample HTML files I tested with:

outer.html

<html>
<frameset cols="20%,40%,40%">
 
<frame name="frMain" src="middle.html" noResize="" scrolling="no">
<frame name="TwoFrame" src="http://bing.com">
<frame name="ThreeFrame" src="http://google.com">
 
</frameset>
</html>

middle.html

<html>
 
<body>
<iframe name="workFrame" src="inner.html"></iframe>
</body>
 
</html>

inner.html

<html>
<body>
 
<table border="5">
    <tr>
        <td><a href="http://www.ask.com" id="ask">Cell 1</a></td>
        <td><a href="http://www.yahoo.com" id="yahoo">Cell 2</a></td>
        <td>Cell 3</td>
    </tr>
</table>
 
</body>
</html>


Here's the code to act on an element within the nested iFrame:

Manager.LaunchNewBrowser();
ActiveBrowser.Window.Maximize();
ActiveBrowser.NavigateTo("c:\\html\\outer.html");
 
ArtOfTest.WebAii.Core.Browser frSub = ActiveBrowser.Frames["workFrame"];
frSub.RefreshDomTree();
 
//expected result is 4
int frameCount = ActiveBrowser.Frames.Count;
Log.WriteLine("Main frames = " + frameCount);
 
//expected result is 0
int frameCount2 = ActiveBrowser.Frames["frMain"].Frames.Count;
Log.WriteLine("Sub frames = " + frameCount2);
 
Element e1 = frSub.Find.ById("yahoo");
frSub.Actions.Click(e1);
 
System.Threading.Thread.Sleep(2000);

Access an element within the workFrame through the workFrame and try waiting for it (not the frame itself).

Best wishes,
Anthony
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Gerald
Top achievements
Rank 1
answered on 27 Sep 2011, 02:15 PM
Thank you for your help. 
I have now created the same code as you tested with to make an easy to verify example.

The issue I have to resolve is that I dynamically load another iframe in the workFrame which simply needs some time to load its content.

So lets say in the workFrame I have another iframe with name="innerFrame" that is dynamically loaded with a timeout of 10 seconds.

How can I successfully wait for its existence without calling Thread.Sleep?


So my code for middle.html would be:

<head>
    <title></title>
    <script type="text/javascript" src="files/js/jquery-1.5.2.js"></script>
</head>
<body>
    <script type="text/javascript">
        $(document).ready(function () {
            setTimeout(function(){ 
                $(document).find("[name=workFrame]").contents().find('html').html("<iframe name=\"innerIframe\" src=\"http://www.google.at\"></iframe>");
            }, 10000);
        });
     
    </script>
    <iframe name="workFrame" src=""></iframe>
</body>
</html>


Best regards
Gerald
0
Anthony
Telerik team
answered on 27 Sep 2011, 05:50 PM
Hi Gerald,

There are two methods mentioned at the bottom of the Frames Support article I originally sent you. After swapping your dynamic frame, use this code to wait for all frames to be ready:

ActiveBrowser.Frames.WaitAllUntilReady();
 

Then make sure to refresh that frame's DOM tree, or the DOM tree of each frame:

//option1
frSub.RefreshDomTree();
 
//option 2
ActiveBrowser.Frames.RefreshAllDomTrees();

You could even add a Wait For statement for an element within the dynamic frame before acting on it.

Best wishes,
Anthony
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Gerald
Top achievements
Rank 1
answered on 28 Sep 2011, 01:33 PM
Hi Anthony,

With your test html code which I extended a little bit it was also possible to wait for iframes, that dynamically load iframes which dynamically load content, and everything loaded with a few seconds delay.

I finally used this code which worked really well for the test:

var workFrame4 = ActiveBrowser.WaitForFrame(new FrameInfo(null, "workFrame4", null, 0));
 
Element e1 = workFrame4.WaitForElement(16000, "id=yahoo");
 
e1.Wait.ForExists();
workFrame4.Actions.Click(e1);

So workFrame4 was loaded with 5 seconds delay into workFrame3, which was itself loaded into frMain with 5 seconds delay.
workFrame4 loads inner.html which sets the yahoo hyperlink with 5seconds delay.
With this test case we could really prove the waiting functions.

Thank you for your great support and really fast answers. We will make a few further tests with the Testing Framework and will consider buying the Suite!

Best Regards
Gerald

Tags
General Discussions
Asked by
Gerald
Top achievements
Rank 1
Answers by
Anthony
Telerik team
Gerald
Top achievements
Rank 1
Share this question
or