目前我正在使用以下等待代码:
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
我希望能够识别此代码花费最长时间的场景。我在多个地方使用此代码,但是有没有办法通过硒记录超时,而无需在调用此代码之前/之后添加秒表?
我想出的最佳方法是扩展方法:
public static IWebElement LoggedUntil(this WebDriverWait wait, Func<IWebDriver, IWebElement> condition)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
return wait.Until(condition);
}
finally
{
watch.Stop();
var elapsedSeconds = watch.Elapsed.TotalSeconds;
Console.WriteLine($"Wait took: {elapsedSeconds} Seconds");
}
}
在此之后,我可以更改所有使用.直到使用.记录到为止
protected IWebElement FindElement(By by)
{
Console.WriteLine($"Find {by}");
return Wait.LoggedUntil(ExpectedConditions.ElementExists(by));
}
您不测量超时,但配置超时。
WebDriverWait 与 ExpectConditions 结合使用被诱导等待所需的元素为:
present
visibe
interactable
WebDriverWait 类的构造函数是:
-
WebDriverWait 构造函数 (IWebDriver, TimeSpan(,它被定位为:
public WebDriverWait( IWebDriver driver, TimeSpan timeout ) Parameters: driver Type: OpenQA.Selenium.IWebDriver The WebDriver instance used to wait. timeout Type: System.TimeSpan The timeout value indicating how long to wait for the condition.
-
WebDriverWait 构造函数 (IClock, IWebDriver, TimeSpan, TimeSpan(,它被定位为:
public WebDriverWait( IClock clock, IWebDriver driver, TimeSpan timeout, TimeSpan sleepInterval ) Parameters clock Type: OpenQA.Selenium.Support.UI.IClock An object implementing the IClock interface used to determine when time has passed. driver Type: OpenQA.Selenium.IWebDriver The WebDriver instance used to wait. timeout Type: System.TimeSpan The timeout value indicating how long to wait for the condition. sleepInterval Type: System.TimeSpan A TimeSpan value indicating how often to check for the condition to be true.
超时和睡眠间隔几乎是可配置的,应该根据测试规范进行配置,因为所需的元素需要在所需的时间跨度内存在、可见或可交互。
作为扩展方法的替代方法,您可以创建一个类来实现IWait<IWebDriver>
以烘焙持续时间的计时和日志记录。
类继承自 DefaultWait,它实现了 IWait 接口(确切地说是 IWait(。您可以嵌套"等待"对象。测量持续时间的"等待"对象只需要实现 IWait 接口:
public class TimeableWebDriverWait : IWait<IWebDriver>
{
private readonly Action<string> logger;
private readonly IWait<IWebDriver> wait;
public string Message
{
get => wait.Message;
set => wait.Message = value;
}
public TimeSpan PollingInterval
{
get => wait.PollingInterval;
set => wait.PollingInterval = value;
}
public TimeSpan Timeout
{
get => wait.Timeout;
set => wait.Timeout = value;
}
public TimeableWebDriverWait(IWait<IWebDriver> wait, Action<string> logger = null)
{
this.wait = wait ?? throw new ArgumentNullException(nameof(wait));
this.logger = logger ?? Console.WriteLine;
}
public void IgnoreExceptionTypes(params Type[] exceptionTypes)
{
wait.IgnoreExceptionTypes(exceptionTypes);
}
public TResult Until<TResult>(Func<T, TResult> condition)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
return wait.Until<TResult>(condition);
}
finally
{
watch.Stop();
logger($"Wait took: {watch.Elapsed.TotalSeconds} Seconds");
}
}
}
现在你可以将它与任何WebDriverWait对象一起使用:
var realWait = new WebDriverWait(driver, 30);
var wait = new TimeableWebDriverWait(realWait);
wait.Until(...);
您可以指定自己的函数来记录消息,只要它接受字符串参数并具有void
返回类型:
var realWait = new WebDriverWait(driver, 30);
var wait = new TimeableWebDriverWait(realWait, System.Diagnostic.Trace.WriteLine);
wait.Until(...);