dee*_*zen 27 selenium end-to-end c#-4.0 phantomjs angularjs
我在堆栈ASP MVC + AngularJS上有一个SPA应用程序,我想测试UI.现在我正在尝试使用PhantomJS和WebKit驱动程序的Selenium.
这是一个示例测试页面 - 具有单个元素的视图.列表项<li>
从服务器动态加载,并由Angular限制.
<div id="items">
<li>text</li>
<li>text2</li>
</div>
Run Code Online (Sandbox Code Playgroud)
我正在尝试通过测试,并且此行中存在错误:
_driver.FindElements(By.TagName('li'))
Run Code Online (Sandbox Code Playgroud)
此时没有加载的元素,_driver.PageSource不包含元素.
我该如何等待加载项目?请不要建议Thread.Sleep()
npj*_*hns 38
这将等待页面加载/ jquery.ajax(如果存在)和$ http调用,以及任何伴随的摘要/渲染周期,将其抛入实用程序函数并等待.
/* C# Example
var pageLoadWait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(timeout));
pageLoadWait.Until<bool>(
(driver) =>
{
return (bool)JS.ExecuteScript(
@"*/
try {
if (document.readyState !== 'complete') {
return false; // Page not loaded yet
}
if (window.jQuery) {
if (window.jQuery.active) {
return false;
} else if (window.jQuery.ajax && window.jQuery.ajax.active) {
return false;
}
}
if (window.angular) {
if (!window.qa) {
// Used to track the render cycle finish after loading is complete
window.qa = {
doneRendering: false
};
}
// Get the angular injector for this app (change element if necessary)
var injector = window.angular.element('body').injector();
// Store providers to use for these checks
var $rootScope = injector.get('$rootScope');
var $http = injector.get('$http');
var $timeout = injector.get('$timeout');
// Check if digest
if ($rootScope.$$phase === '$apply' || $rootScope.$$phase === '$digest' || $http.pendingRequests.length !== 0) {
window.qa.doneRendering = false;
return false; // Angular digesting or loading data
}
if (!window.qa.doneRendering) {
// Set timeout to mark angular rendering as finished
$timeout(function() {
window.qa.doneRendering = true;
}, 0);
return false;
}
}
return true;
} catch (ex) {
return false;
}
/*");
});*/
Run Code Online (Sandbox Code Playgroud)
Sha*_*haz 26
创建一个新类,让您了解使用AngularJS的网站是否已完成AJAX调用,如下所示:
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
public class AdditionalConditions {
public static ExpectedCondition<Boolean> angularHasFinishedProcessing() {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return Boolean.valueOf(((JavascriptExecutor) driver).executeScript("return (window.angular !== undefined) && (angular.element(document).injector() !== undefined) && (angular.element(document).injector().get('$http').pendingRequests.length === 0)").toString());
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下代码在代码中的任何位置使用它:
WebDriverWait wait = new WebDriverWait(getDriver(), 15, 100);
wait.until(AdditionalConditions.angularHasFinishedProcessing()));
Run Code Online (Sandbox Code Playgroud)
小智 6
我们有一个类似的问题,我们的内部框架用于测试多个站点,其中一些使用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;
}
Run Code Online (Sandbox Code Playgroud)
然后我们检查是否正在使用JQuery:
public bool IsJqueryBeingUsed(IJavaScriptExecutor jsExecutor)
{
var isTheSiteUsingJQuery = jsExecutor.ExecuteScript("return window.jQuery != undefined");
return (bool)isTheSiteUsingJQuery;
}
Run Code Online (Sandbox Code Playgroud)
如果正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
然后我们对AngularJS做同样的事情:
public bool AngularIsBeingUsed(IJavaScriptExecutor jsExecutor)
{
string UsingAngular = @"if (window.angular){
return true;
}";
var isTheSiteUsingAngular = jsExecutor.ExecuteScript(UsingAngular);
return (bool) isTheSiteUsingAngular;
}
Run Code Online (Sandbox Code Playgroud)
如果它正在使用,那么我们检查它是否已加载:
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;
}
Run Code Online (Sandbox Code Playgroud)
检查DOM是否已成功加载后,您可以使用这些bool值进行自定义等待:
var jquery = !IsJqueryBeingUsed(javascript) || wait.Until(x => JQueryHasLoaded(javascript));
var angular = !AngularIsBeingUsed(javascript) || wait.Until(x => AngularHasLoaded(javascript));
Run Code Online (Sandbox Code Playgroud)
如果您使用 AngularJS,那么使用 Protractor 是一个好主意。
如果您使用量角器,您可以使用它的 waitForAngular() 方法,该方法将等待 http 请求完成。在对元素进行操作之前等待元素显示仍然是一个很好的做法,具体取决于您的语言和实现,它可能在同步语言中看起来如此
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
Run Code Online (Sandbox Code Playgroud)
或者在 JS 中你可以使用 wait 方法来执行一个函数直到它返回 true
browser.wait(function () {
return browser.driver.isElementPresent(elementToFind);
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
38264 次 |
最近记录: |