Error when accessing the Frames in Watin new version 2.1

柔情痞子 提交于 2019-11-30 23:02:49

I modified the code for AllFramesProcessor using Praveen's suggestion (see below).

Before I did this, I did an SVN update on the Watin trunk. Jeroen made a checkin on 4/18/11 that fixed an issue around WaitForFramesToComplete to retry/wait loading the main document. Jeroen's fix alone didn't solve the problem, but I believe it's the combination of that code and the modified AllFramesProcessor that made Watin more stable around the Frames issue.

public AllFramesProcessor(HTMLDocument htmlDocument)
{
    Elements = new List<INativeDocument>();
    _htmlDocument = htmlDocument;

    // Bug fix, trying to revert back to previous version
    // http://stackoverflow.com/questions/5882415/error-when-accessing-the-frames-in-watin-new-version-2-1
    //_iFrameElements = (IHTMLElementCollection)htmlDocument.all.tags("iframe");

    _iFrameElements = (IHTMLElementCollection)_htmlDocument.all.tags("frame");

    // If the current document doesn't contain FRAME elements, it then
    // might contain IFRAME elements.
    if (_iFrameElements.length == 0)
    {
        _iFrameElements = (IHTMLElementCollection)_htmlDocument.all.tags("iframe");
    }
}

You can work around this by accessing ie.NativeDocument.Frames and then passing ie and any INativeElement objects to the WatiN.Core.Element constructor:

   Element ElementFromFrames(string elementId, IList<INativeDocument> frames)
   { 
     foreach(var f in frames)
      {
        var e=f.Body.AllDescendants.GetElementsById(elementId).FirstOrDefault();
        if (e != null) return new Element(ie ,e);

        if (f.Frames.Count > 0) 
         { var ret = ElementFromFrames(elementId, f.Frames);
           if (ret != null) return ret;
         }
      }     

     return null;
   }

from https://sourceforge.net/tracker/?func=detail&aid=3290877&group_id=167632&atid=843727

This problem seems to be caused by the AllFramesProcessor class. The constructor for this class in Watin 1.3 looked like this:

public AllFramesProcessor(DomContainer domContainer, HTMLDocument
htmlDocument)
{
elements = new ArrayList();

frameElements = (IHTMLElementCollection)
htmlDocument.all.tags(ElementsSupport.FrameTagName);

// If the current document doesn't contain FRAME elements, it then
// might contain IFRAME elements.
if (frameElements.length == 0)
{
frameElements = (IHTMLElementCollection)
htmlDocument.all.tags("IFRAME");
}

this._domContainer = domContainer;
this.htmlDocument = htmlDocument;
}

The constructor in 2.1 looks like this:

public AllFramesProcessor(HTMLDocument htmlDocument)
{
Elements = new List<INativeDocument>();
_htmlDocument = htmlDocument;

_iFrameElements =
(IHTMLElementCollection)htmlDocument.all.tags("iframe");
}

By changing the "htmlDocument.all.tags("iframe")" to be "htmlDocument.all.tags("frame")" as per the Watin 1.3 constructor this seems to resolve this issue. Not quite sure why the constructor was changed to just look for iFrames though.

julian guppy

Recently I also encountered this problem and I started by following Richard Guions (accepted) answer and just to elaborate a little on that I did the following:-

svn co https://watin.svn.sourceforge.net/svnroot/watin watin 

and then loaded the "Watin/trunk/src/WatiN.sln" solution and recompiled the src, then referencing that new Watin.core.dll in my project.

Low and behold the browser.Frame(Find.ByName("maincontent")); started working and I did not need to apply any other changes to the AllFrames code. So I think that the svn source has already been updated to include this change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!