我在selenium页面上有一个列为propterty的列表,例如:
public IEnumerable<MyItem> MyList =>
webDriverInstance.FindListElementsWithWait<MyItem>(By.ClassName("my-item"));
其中FindListElementsWithWait是一个扩展方法:
public static IEnumerable<T> FindListElementsWithWait<T>(this IWebDriver driver, By locator, int timeOutMilliseconds = 10000)
{
var elements = new List<T>();
var wait = new WebDriverWait(driver, TimeSpan.FromMilliseconds(timeOutMilliseconds));
wait.Until(d =>
{
try
{
elements = d.FindElements(locator).Select(x => (T)Activator.CreateInstance(typeof(T), x)).ToList();
return true;
}
catch (TargetInvocationException)
{
return false;
}
}
);
return elements;
}
这是使用WebDriverWait而不是Thread.Sleep。由于这是一个列表,因此每个MyItem都没有唯一的定位器。这种方法有效,但有一些怪癖。
例如:
public class MyItem
{
public string Name { get; private set; }
public MyItem(IWebElement webElement)
{
Name = webElement.FindElement(By.TagName("H4")).Text;
}
}
这是有效的,但我遇到的问题是,如果我在MyItem上有其他属性,这些属性最初不在元素上。例如,如果我更改某个状态,现在会出现取消按钮。如果我在构造函数中初始化取消按钮,那么它将抛出NoSuchElementException并在页面加载时失败。我可以通过为新的Cancel按钮属性提供一个getter主体来解决这个问题。但这是产生/促进脆弱的测试。
有没有人找到一种干净的方法来更新/刷新列表中的陈旧WebElement,其中没有唯一的定位器用于陈旧的WebElement?
答案 0 :(得分:1)
好的,所以这是javascript中的竞争条件,其中webdriver在AJAX请求完成之前正在做事情。 @JeffC在使用驱动程序拉取web元素之前提出了一个很好的观点,特别是使用列表。
在我的特定情况下,我正在删除列表中的元素。因此,如果您收到StaleElementReferenceException并从视图中删除元素,那么这可能对您有用:
我在解决此问题时发现以下文章非常有用:https://bocoup.com/weblog/a-day-at-the-races
答案 1 :(得分:0)
在我看来,你是在设计这个问题。我喜欢简单。
By MyItemsBeforeLocator = By.TagName("h4"); // locator for the element BEFORE the page state change
By MyItemsAfterLocator = By.CssSelector("h4.my-item"); // locator for the element AFTER the page state change
WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
ReadOnlyCollection<IWebElement> Items = wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(MyItemsBeforeLocator));
// do stuff with Items
// do stuff that changes the state of the page
Items = wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(MyItemsAfterLocator));
// do stuff with Items
我建议您也查看页面对象模型。在页面对象中定义给定页面的所有定位器,然后提供使用这些定位器在页面上执行操作的方法。