Nested Iframes

8 posts, 1 answers
  1. Gerald
    Gerald avatar
    4 posts
    Member since:
    Aug 2011

    Posted 19 Sep 2011 Link to this post

    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!
  2. Anthony
    Admin
    Anthony avatar
    19 posts

    Posted 19 Sep 2011 Link to this post

    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
  3. Anthony
    Admin
    Anthony avatar
    19 posts

    Posted 19 Sep 2011 Link to this post

    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
  4. Gerald
    Gerald avatar
    4 posts
    Member since:
    Aug 2011

    Posted 20 Sep 2011 Link to this post

    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

  5. Answer
    Anthony
    Admin
    Anthony avatar
    19 posts

    Posted 21 Sep 2011 Link to this post

    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
  6. Gerald
    Gerald avatar
    4 posts
    Member since:
    Aug 2011

    Posted 27 Sep 2011 Link to this post

    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
  7. Anthony
    Admin
    Anthony avatar
    19 posts

    Posted 27 Sep 2011 Link to this post

    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
  8. Gerald
    Gerald avatar
    4 posts
    Member since:
    Aug 2011

    Posted 28 Sep 2011 Link to this post

    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

Back to Top