【问题标题】:WebBrowserDocumentCompletedEventHandler Don't wait for Ajax Async to completeWebBrowserDocumentCompletedEventHandler 不要等待 Ajax Async 完成
【发布时间】:2014-06-27 16:47:52
【问题描述】:

在阅读了 Dianyang Wu article 和 this 的优秀帖子后,我设法构建了一个小型 .net 应用程序(几乎是 Wu 源代码的 C&P)来自动化测试(我们称之为 protoTestApp)。我的最终目标是打开十几个小窗口,并在每个小窗口中模拟不同的用户与 Web 应用交互以对其施加压力。

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

我的问题是在我的 protoTestApp 我还想与那个 ExternalTestSubject 交互(通过 id 找到一个按钮,单击它等)但是在我的 CompletedEvent 处理程序中,iFrame 仍然是空的。

WebBrowser 显示两个 Web 应用程序都已完全加载并正在运行,所以我想处理程序只是不等待 iFrame 内容加载,因为它是由 Ajax 异步调用完成的。

有什么建议可以完成吗?

【问题讨论】:

  • 如何启动填充 iFrame 的操作?是不是一些 JavaScript 由 onload 事件触发,AJAX 调用一个注入响应到 iFrame 中?
  • InternalTestSubject 是一个 .net MVC web 应用程序。 iFrame 由捆绑的 index.js 在 ready 事件中动态生成,并附加到 index.cshtml 中声明的 div 中。 iFrame 指向 ExternalTestSubject URL。到目前为止,我的 WebBrowserDocumentCompletedEventHandler 被调用了两次(在第一次被登录页面调用之后)并且在这两个中我都可以看到空的 iFrame,我想处理程序没有等待 iFrame 文档加载
  • “我可以在视觉上看到空的 iFrame”,或者在尝试访问它的 windows 属性/DOM 时?我要解决的问题是我想知道您是否遇到与 iFrame 相关的同源策略限制。
  • 我可以直观地看到 iFrame 已完全加载到浏览器中,但如果 iFrame 为空。没有限制,因为两个应用程序都托管在同一个域中(这是一个正在运行的解决方案)

标签: c# javascript ajax iframe webbrowser-control


【解决方案1】:

我想我在您链接的the answer 中解释了这一点(以及在another related answer 中的更多详细信息)。 AJAX 页面是非确定性的,因此没有通用的方法。

使用定期异步轮询来观察页面当前的 HTML 快照或 DOM 的变化,链接的帖子说明了如何做到这一点。您可以以相同的方式轮询框架的内容。

【讨论】:

  • 在发布这个问题之前,我玩了一点你在 github 上提供的源代码(顺便说一句,代码不错)。使用您的控制台解决方案给了我相同的结果:一个空的 iFrame。顺便说一句,WebBrowserDocumentCompletedEventHandler isBusy 总是错误的,我必须弄清楚如何在无控制台解决方案中使用类似该任务/等待的东西
  • @jean,我的意思是,在模拟点击之后,您需要使用Task.Delay 技术在该代码(或计时器)中继续轮询iframe 的DOM 内容,以防万一WebBrowserDocumentCompletedEventHandler 不会给你你想要的。
  • 很遗憾,我失败了。现在我看到我理解你的代码,甚至比我猜的还要少。下次我会更加努力。也许我可以设法让那个 github 项目在这种情况下工作
  • @jeans,嗯……是不是因为async/await很难理解?我认为如果我使用回调金字塔代替它可能会更加混乱。
  • 我想这是因为我习惯了回调金字塔,并且是我第一次编写控制台/任务,我需要消化一些东西。正如我在第一次评论中所说的那样,它给了我相同的结果(一个空的 iFrame),但我下次会尝试更努力地调试它。真的没有办法使用 WebBrowserDocumentCompleted 处理程序吗?我尝试创建并将其中一个附加到 iFrame 本身,但即使 WebBrowser 完全加载了应用程序也无法正常工作。
【解决方案2】:

我可以想象框架报告已准备就绪,但实际上并没有。例如,框架包含框架,您无法通过DocumentCompleted 事件知道是否所有这些框架都被加载。

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

我有两个建议给你:

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

  2. 使用Selenium 等第三个工具作为测试驱动程序。


更新 1:

由于提问者不需要任何第三个工具,我建议让内部测试对象定期查询目标框架的加载完整性。可能的代码可以检查document.readyState == 'complete'。

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

【讨论】:

  • 问题指出打开外部测试对象不是一个选项,因为它无法在内部测试对象之外正常工作。既是水族馆,又是鱼。还尝试动态执行此操作,找到 iFrame 并将其“附加”到新的 WebBrowser 并且不起作用(创建的实例不会触发事件)。购买第三方工具不是这里的选择。
  • @jean 我已经更新了,请检查。但我怀疑这种方法行不通。顺便说一句:Selenium 是免费的。
猜你喜欢
  • 2018-12-20
  • 2021-01-26
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 2017-05-20
  • 2019-04-08
  • 1970-01-01
相关资源
最近更新 更多