C# WebBrowserDocumentCompletedEventHandler Don';不要等待Ajax异步完成

C# WebBrowserDocumentCompletedEventHandler Don';不要等待Ajax异步完成,c#,javascript,ajax,iframe,webbrowser-control,C#,Javascript,Ajax,Iframe,Webbrowser Control,在阅读了这篇优秀的文章之后,我成功地构建了一个小型的.net应用程序(几乎是来自Wu源代码的C&p)来自动化测试(我们称之为protoTestApp)。我的最终目标是打开十几个小窗口,在每个窗口中模拟不同的用户与一个web应用程序交互来强调它 它在某种程度上可以工作,但在我登录web应用程序(我们称之为InternalTestSubject)后,它会调用外部url(我们称之为ExternalTestSubject),并将其内容注入iFrame。这个特定的外部url是另一个web应用程序,它将查找

在阅读了这篇优秀的文章之后,我成功地构建了一个小型的.net应用程序(几乎是来自Wu源代码的C&p)来自动化测试(我们称之为protoTestApp)。我的最终目标是打开十几个小窗口,在每个窗口中模拟不同的用户与一个web应用程序交互来强调它

它在某种程度上可以工作,但在我登录web应用程序(我们称之为InternalTestSubject)后,它会调用外部url(我们称之为ExternalTestSubject),并将其内容注入iFrame。这个特定的外部url是另一个web应用程序,它将查找父窗口以获取一些参数。直接打开ExternalTestSubject不是一个选项

我的问题是在protoTestApp中,我也想与ExternalTestSubject交互(通过id查找按钮,单击按钮等),但在CompletedEvent处理程序中,iFrame仍然为空

WebBrowser显示web应用程序已完全加载且正在工作,因此我认为处理程序不会等待iFrame内容加载,因为它是通过Ajax异步调用完成的


有什么建议吗?

我想我在你的链接中解释了这一点(更多细节请参见)。AJAX页面是不确定的,因此没有通用的方法


使用定期异步轮询来查看页面的当前HTML快照或DOM的更改,链接的帖子演示了如何做到这一点。您可以用同样的方式轮询框架的内容。

我可以想象框架报告已经准备好了,但实际上没有。例如,帧包含帧,您无法知道是否所有这些帧都是通过使用
DocumentCompleted
事件加载的

简而言之:使用框架加载外部内容并进行测试不是一个好方法。即使您使用计时器手动检查加载状态。但是根据安全考虑,访问DOM会有很多问题。

我有两个建议:

  • 创建一个
    WebBrowser
    实例,并在其中打开外部测试主题。您将有很好的机会知道文档(及其框架)是否已完全加载。您仍然可以完全控制访问
    WebBrowser
    或cookie的任何元素,或单击元素或更改元素

  • 使用第三种工具,如测试驱动程序


  • 更新1:

    由于提问者不需要任何第三个工具,我建议让内部测试主体定期查询目标帧的加载完整性。可能的代码可以是check
    document.readyState==“complete”


    据我所知,由于外部测试主题是作为框架嵌入的,出于安全考虑,您可能无法访问框架的DOM。换句话说,除非您先更改Webbrowser控件的安全设置,否则无法执行鼠标单击等操作。

    填充iFrame的操作是如何启动的?是由AJAX调用injects响应到iFrame中的onload事件触发的JavaScript吗?InternalTestSubject是一个.net MVC Web应用程序。iFrame由bundled index.js在ready事件中动态生成,并附加到index.cshtml中声明的div中。iFrame指向ExternalTestSubject URL。到目前为止,我的WebBrowserDocumentCompletedEventHandler被调用了两次(在第一次被登录页面调用之后),在这两次调用中,我都可以看到空的iFrame,我想处理程序不是像在可视化中那样等待iFrame文档加载“我可以看到空的iFrame”,或者在尝试访问它的windows属性/DOM时?我要说的是,我想知道您是否遇到了与iFrame相关的相同来源策略限制。我可以直观地看到iFrame已完全加载到浏览器中,但在事件中,iFrame为空。没有限制,因为这两个应用程序都托管在同一个域中(这是一个在生产中工作的解决方案),在发布这个问题之前,我对您在github发布的源代码进行了一些研究(顺便说一句,代码不错)。使用控制台解决方案会得到相同的结果:一个空的iFrame。顺便说一句,WebBrowserDocumentCompletedEventHandler的isBusy始终为false,我必须弄清楚如何在无控制台中使用类似task/wait的东西solution@jean,我的意思是,在模拟单击之后,您需要继续使用代码中的
    Task.Delay
    技术轮询
    iframe
    的DOM内容(或计时器),以防
    WebBrowserDocumentCompletedEventHandler
    无法提供您所需的信息。遗憾的是,我失败了,这并不奇怪。现在我明白了,我对您的代码的理解比猜测的还要少。下次我会更加努力。也许我可以设法让github项目与此配合使用scenario@jeans是不是因为
    async/await
    很难明白吗?我想如果我改用金字塔形回调,可能会更让人困惑。我想这是因为我习惯于金字塔形回调,这是我第一次编写控制台/任务,我需要消化一些东西。正如我在第一次评论时所说,它给了我相同的结果(一个空的iFrame)但我下次会更努力地调试它。真的没有办法使用WebBrowserDocumentCompleted处理程序?我试图创建其中一个并将其附加到iFrame本身,但即使WebBrowser完全加载了应用程序也不起作用。问题是,打开外部测试主题不是一个选项,因为它不起作用完全脱离内部测试主题。将其视为水族馆和鱼。还尝试动态执行此操作,找到iFrame并将其“附加”到新的WebBrowser,但未成功(创建的实例不会触发事件)。购买第三方工具不是这里的选项。@jean我已经更新了,请检查。但我怀疑这种方法不会起作用。顺便说一句:Selenium是免费的。