我正在使用Wait.Until方法检查我的页面是否已加载或是否仍在加载。 这就是它的样子:
protected IWebElement FindElement(By by, int timeoutInSeconds)
{
StackTrace stackTrace = new StackTrace();
string callingMethod = stackTrace.GetFrame(1).GetMethod().Name;
string message = "Error finding element in method: " + callingMethod;
if (timeoutInSeconds > 0)
{
try
{
WebDriverWait wait = new WebDriverWait(chromeDriver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.Until(ExpectedConditions.ElementIsVisible(by));
Thread.Sleep(800);
}
catch (Exception)
{
Assert(false, message);
throw new Exception(message);
}
}
return chromeDriver.FindElement(by);
}
但是现在我们想要改变我们的自动化页面并开始使用FindBy敌人的每个元素,如下所示:
[FindsBy(How = How.Id, Using = "username")]
public IWebElement _logInUserName;
但wait.until需要" by"元素。
我看到了这个问题的抽象解决方案,但这对我的情况没有好处。 谁能知道我可以使用的另一种解决方案?
答案 0 :(得分:2)
有一个ByFactory
class in Selenium .NET solution。我采用这种实现来实现你想要的目标:
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace SeleniumPlayground
{
public static class SeleniumHelper
{
public static FindsByAttribute GetFindsByAttributeFromField(Type pageObject, string iwebElementFieldName)
{
FieldInfo fi = pageObject.GetField(iwebElementFieldName);
FindsByAttribute attr = (FindsByAttribute)fi.GetCustomAttributes(typeof(FindsByAttribute), false).FirstOrDefault();
return attr;
}
public static By GeyByFromFindsBy(FindsByAttribute attribute)
{
var how = attribute.How;
var usingValue = attribute.Using;
switch (how)
{
case How.Id:
return By.Id(usingValue);
case How.Name:
return By.Name(usingValue);
case How.TagName:
return By.TagName(usingValue);
case How.ClassName:
return By.ClassName(usingValue);
case How.CssSelector:
return By.CssSelector(usingValue);
case How.LinkText:
return By.LinkText(usingValue);
case How.PartialLinkText:
return By.PartialLinkText(usingValue);
case How.XPath:
return By.XPath(usingValue);
case How.Custom:
if (attribute.CustomFinderType == null)
{
throw new ArgumentException("Cannot use How.Custom without supplying a custom finder type");
}
if (!attribute.CustomFinderType.IsSubclassOf(typeof(By)))
{
throw new ArgumentException("Custom finder type must be a descendent of the By class");
}
ConstructorInfo ctor = attribute.CustomFinderType.GetConstructor(new Type[] { typeof(string) });
if (ctor == null)
{
throw new ArgumentException("Custom finder type must expose a public constructor with a string argument");
}
By finder = ctor.Invoke(new object[] { usingValue }) as By;
return finder;
}
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Did not know how to construct How from how {0}, using {1}", how, usingValue));
}
}
以下是一个示例用法:
public class Page
{
private IWebDriver driver;
[FindsBy(How = How.Id, Using = "content")]
public IWebElement ele;
public Page(IWebDriver _driver)
{
this.driver = _driver;
}
}
使用如下:
Page page = PageFactory.InitElements<Page>(driver);
FindsByAttribute findsBy = SeleniumHelper.GetFindsByAttributeFromField(typeof(Page), "ele");
By by = SeleniumHelper.GeyByFromFindsBy(findsBy);
答案 1 :(得分:1)
我找到了办法:)
public static IWebElement FindElement( IWebElement element, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(chromeDriver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => element);
}
return element;
}
答案 2 :(得分:1)
使用硒进行测试时遇到了同样的问题。所以我们在selenium之上创建了一个迷你框架,它一直在努力(无论你想用硒做什么)。或者您可以提供自定义的前置或后置条件。
https://github.com/LiquidThinking/Xenon
设置非常简单,所有信息都可以在github上获得,另外还有Screen对象,可以帮助重用代码。
例如
MobID
所以在这个例子中,我们添加了一个预先等待条件,说“在进入google.co.uk之前确保当前页面包含页面源中的”google“。这显然是不正确的方法,但它解释如何使用等前或等待条件。
如果您没有指定任何等待条件,那么对于某些操作,则存在默认的等待操作。例如https://github.com/LiquidThinking/Xenon/blob/master/Xenon/BaseXenonTest.cs#L72 看看我们如何检查customPreWait是否可用于“Click”,如果没有,那么我们在执行“实际点击操作”之前添加了自定义预等待以检查页面上是否存在css选择器。
希望它会帮助你,它是nuget或者只是使用你想要的代码。它是在麻省理工学院的许可下。