我们有一个类似的问题,我们的内部框架被用于测试多个站点,其中一些使用 JQuery,一些使用 AngularJS(其中 1 甚至混合使用!)。我们的框架是用 C# 编写的,因此任何正在执行的 JScript 都必须以最小的块完成(出于调试目的),这一点很重要。实际上,它需要很多上述答案并将它们混合在一起(因此应归功于@npjohns)。下面是我们所做的解释:
如果 HTML DOM 已加载,则以下返回 true / false:
public bool DomHasLoaded(IJavaScriptExecutor jsExecutor, int timeout = 5)
{
var hasThePageLoaded = jsExecutor.ExecuteScript("return document.readyState");
while (hasThePageLoaded == null || ((string)hasThePageLoaded != "complete" && timeout > 0))
{
Thread.Sleep(100);
timeout--;
hasThePageLoaded = jsExecutor.ExecuteScript("return document.readyState");
if (timeout != 0) continue;
Console.WriteLine("The page has not loaded successfully in the time provided.");
return false;
}
return true;
}
然后我们检查是否正在使用 JQuery:
public bool IsJqueryBeingUsed(IJavaScriptExecutor jsExecutor)
{
var isTheSiteUsingJQuery = jsExecutor.ExecuteScript("return window.jQuery != undefined");
return (bool)isTheSiteUsingJQuery;
}
如果正在使用 JQuery,我们将检查它是否已加载:
public bool JqueryHasLoaded(IJavaScriptExecutor jsExecutor, int timeout = 5)
{
var hasTheJQueryLoaded = jsExecutor.ExecuteScript("jQuery.active === 0");
while (hasTheJQueryLoaded == null || (!(bool) hasTheJQueryLoaded && timeout > 0))
{
Thread.Sleep(100);
timeout--;
hasTheJQueryLoaded = jsExecutor.ExecuteScript("jQuery.active === 0");
if (timeout != 0) continue;
Console.WriteLine(
"JQuery is being used by the site but has failed to successfully load.");
return false;
}
return (bool) hasTheJQueryLoaded;
}
然后我们对 AngularJS 做同样的事情:
public bool AngularIsBeingUsed(IJavaScriptExecutor jsExecutor)
{
string UsingAngular = @"if (window.angular){
return true;
}";
var isTheSiteUsingAngular = jsExecutor.ExecuteScript(UsingAngular);
return (bool) isTheSiteUsingAngular;
}
如果它正在被使用,那么我们检查它是否已经加载:
public bool AngularHasLoaded(IJavaScriptExecutor jsExecutor, int timeout = 5)
{
string HasAngularLoaded =
@"return (window.angular !== undefined) && (angular.element(document.body).injector() !== undefined) && (angular.element(document.body).injector().get('$http').pendingRequests.length === 0)";
var hasTheAngularLoaded = jsExecutor.ExecuteScript(HasAngularLoaded);
while (hasTheAngularLoaded == null || (!(bool)hasTheAngularLoaded && timeout > 0))
{
Thread.Sleep(100);
timeout--;
hasTheAngularLoaded = jsExecutor.ExecuteScript(HasAngularLoaded);
if (timeout != 0) continue;
Console.WriteLine(
"Angular is being used by the site but has failed to successfully load.");
return false;
}
return (bool)hasTheAngularLoaded;
}
在我们检查 DOM 是否已成功加载后,您可以使用这些 bool 值进行自定义等待:
var jquery = !IsJqueryBeingUsed(javascript) || wait.Until(x => JQueryHasLoaded(javascript));
var angular = !AngularIsBeingUsed(javascript) || wait.Until(x => AngularHasLoaded(javascript));