我已经设法打开了Chrome浏览器,转到特定页面,然后单击表单上的提交按钮。 我的 AJAX 调用是从 jQuery 文件触发的(onclick="saveUserToDb" - 在 HTML 中(
我没有找到如何从我的 AJAX 请求中捕获响应? 只有我能找到的是隐式等待或显式等待。 我已经实现了它,但我想确保我的 AJAX 成功运行(状态代码 = 200(
下面是示例代码:
[TestMethod]
public void TestMethod1()
{
const string prefix = "details";
// Arrange
var driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://localhost/MyApp.View/");
//enters to the Manager section
driver.FindElementById("mngId").Click();
//expand the menu - codelists
driver.FindElementById("codelists").Click();
//entering to the EnterMobile page
driver.FindElementById("enterMobilePrefix").Click();
//click on Add for new MobilePrefix
driver.FindElementById("addMobilePrefix").Click();
//populate data for MobilePrefix
Thread.Sleep(1000);
IWebElement codeElement = driver.FindElementById(prefix + "_Code");
IWebElement coreCodeElement = driver.FindElementById(prefix + "_CoreCode");
IWebElement valueElement = driver.FindElementById(prefix + "_Value");
codeElement.SendKeys("10254");
coreCodeElement.SendKeys("8794");
valueElement.SendKeys("test55");
//Calling the AJAX
driver.FindElementByClassName("btn-info").Click();
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,10));
wait.Until(driverAjax =>
{
bool isAjaxFinished = (bool)((IJavaScriptExecutor)driverAjax).
ExecuteScript("return jQuery.active == 0");
return isAjaxFinished;
});
Thread.Sleep(2000);
driver.Quit();
// Assert
//StringAssert.EndsWith(session.ToString(), "html");
}
根据我找到的文档
这是使用 waitFor 命令完成的,如 waitForElementPresent 或 waitForVisible,它们动态等待,每秒检查所需条件,并在满足条件后立即继续执行脚本中的下一个命令。
另一种解决方法可能会解决您的问题
将 Ajax 响应设置在隐藏元素中,并使其具有 ID ex:"AjaxResponse"。在您尚未发送请求时,该元素应为空,如果请求失败,则包含单词 FAILED(您也可以添加失败的消息(或填充 Ajax 响应。在 C# 代码中,单击将发送请求的按钮。等待500ms然后检查它。如果为空,请再等待 500 毫秒,直到总等待时间超过指定的限制。到那时,您将在元素中出现失败单词。
我的灵魂是实现你的WaitHelper类:
public static class WaitHelper
{
public static bool WaitFor(int timeoutInMiliseconds, int sleepInMiliseconds, Func<bool> waitForSuccessfullResult)
{
return WaitFor(
TimeSpan.FromMilliseconds(timeoutInMiliseconds),
TimeSpan.FromMilliseconds(sleepInMiliseconds),
waitForSuccessfullResult);
}
public static bool WaitFor(TimeSpan timeout, TimeSpan sleepInverval, Func<bool> waitForSuccessfullResult)
{
while (timeout.TotalMilliseconds > 0)
{
try
{
if (waitForSuccessfullResult())
{
return true;
}
}
catch (Exception e)
{
Console.WriteLine("An error occured. Details: n" + e.ToString());
}
timeout -= sleepInverval;
Thread.Sleep(sleepInverval);
}
return false;
}
然后你可以等待一些Ajax请求,比如:
public static void WaitForAjaxRequest(this IWebDriver webDriver)
{
WaitHelper.WaitFor(
Config.ShortTime,
TimeSpan.FromMilliseconds(100),
() =>
{
return !webDriver.IsAjaxRequestInProgress();
});
}
public static bool IsAjaxRequestInProgress(this IWebDriver webDriver)
{
return webDriver.ExecuteJs<bool>("return window.jQuery ? window.jQuery.active != 0 : false");
}
或等待文档准备就绪:
public static void WaitForDocumentReady(this IWebDriver webDriver)
{
WaitHelper.WaitFor(
TimeSpan.FromSeconds(6),
TimeSpan.FromMilliseconds(200),
() =>
{
try
{
string readyState = webDriver.ExecuteJs<string>("if (document.readyState) return document.readyState;");
var ajaxInProgress = webDriver.IsAjaxRequestInProgress();
return readyState.ToLower() == "complete" && !ajaxInProgress;
}
catch (InvalidOperationException e)
{
// Window is no longer available
return e.Message.ToLower().Contains("unable to get browser");
}
catch (WebDriverException e)
{
// Browser is no longer available
return e.Message.ToLower().Contains("unable to connect");
}
catch (Exception)
{
return false;
}
});
}
JavaScript Executor:
public static T ExecuteJs<T>(this IWebDriver webDriver, string script)
{
var javaScriptExecutor = webDriver as IJavaScriptExecutor;
if (javaScriptExecutor == null)
{
return default(T);
}
return (T)javaScriptExecutor.ExecuteScript(script);
}