如何使用 Selenium 和 C# 访问包装在“.lazyload-wrapper”中的元素?
发布时间:2022-09-02 13:50:59 312
相关标签: # 工具
我正在为澳大利亚一家流行的五金店网站构建一个测试工具。我希望我的测试转到包含例如 36 个结果的页面(该页面实际上显示“显示 151 个结果中的 36 个”),然后单击一个随机选择的产品中的“添加到购物车”按钮。为此,我尝试driver.FindElements 使用 CssSelector 捕获页面中的所有 36 个按钮。
我面临的问题是我只能获得前 12 件物品,因为其余 24 件物品都包裹在 a 中class=lazyload-wrapper,而我无法让司机捕获它们。我尝试将页面滚动到底部,我尝试在任何地方插入 Thread.Sleep,我尝试过WebDriverWait,我还从 ExpectedConditions 重新创建了一些不推荐使用的函数以使其工作,但我仍然只得到 12 个元素。
我在这里和其他论坛上阅读了几乎所有关于类似问题的帖子,但我仍然被相同的 12 个项目所困扰。也许 Selenium 不是做到这一点的最佳选择。如果有人能对这一挑战有所了解,将不胜感激。
这是我用来与页面交互的类,请原谅我留下所有注释掉的代码,它只是为了显示所有失败的尝试:
using System;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
using System.Linq;
namespace Model.Pages
{
public class CarAccessoriesPage : BasePage
{
public CarAccessoriesPage(IWebDriver driver) : base(driver)
{
}
///
/// Add a random product to the shopping cart.
///
public CarAccessoriesPage AddRandomItemToCart()
{
// smooth scrolling down to force loading did not work
// IJavaScriptExecutor jsex = (IJavaScriptExecutor)driver;
// jsex.ExecuteScript("window.scrollTo({left:0, top:document.body.scrollHeight, behavior:'smooth'});");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
// Scroll
IJavaScriptExecutor jsex = (IJavaScriptExecutor)driver;
jsex.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
// maybe wait for the page to load? Did not work.
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
// Maybe inserting an ugly pause... no bueno
Thread.Sleep(3000);
// driver.FindElement(By.CssSelector("[data-index='35']")); // this element is not found
Random r = new Random();
int i = r.Next(0, GetPartialResultsCount());
// First approach throws OutOfRangeException because only 12 elements are found
// IWebElement itemElement = new WebDriverWait(driver, TimeSpan.FromSeconds(5))
// .Until(d => d.FindElements(By.CssSelector("[data-locator='atcButton']")))[i];
// Implementing a function from ExpectedConditions deprecated in C#, no good enough
var elements = wait
.Until(PresenceOfAllElementsLocatedBy(By.CssSelector("[data-locator='atcButton']")));
// maybe trying access the article elements inside the wrapper... fail
// var elements = driver.FindElements(By.CssSelector("article.lazyload-wrapper "));
Console.WriteLine(elements.Count); // Always 12!!! I know there are better ways to log
IWebElement ranItem = elements[i]; // Throws an OutOfRangeException if i > 11
Thread.Sleep(1000);
// center the element so the tob and bottom banners don intercept the click
jsex.ExecuteScript("arguments[0].scrollIntoView({block: 'center'});", ranItem);
Thread.Sleep(1000);
ranItem.Click();
Thread.Sleep(1000); // important or last function in test does not work (assertion fails: expected != actual)
return this;
}
///
/// Get the number of items in the shopping cart.
///
public int GetCartCount()
{
return Int32.Parse(driver.FindElement(By.ClassName("cartItemCount")).Text);
}
private Func<IWebDriver, ReadOnlyCollection> PresenceOfAllElementsLocatedBy(By locator)
{
return (driver) =>
{
try
{
var elements = driver.FindElements(locator);
return elements.Any() ? elements : null;
}
catch (StaleElementReferenceException)
{
return null;
}
};
}
///
/// Generate a random int no larger than the Collection of products
/// in the page. But due to lazy loading, the number generated was causing an out of range exception.
///
private int GetPartialResultsCount()
{
string partialResultsCount = driver.FindElement(By.CssSelector(".resultsCount > p")).Text;
return Int32.Parse(Regex.Match(partialResultsCount, @"\d+").Value);
}
}
}
测试本身实际上非常直接:
using NUnit.Framework;
using Model.Pages;
namespace Tests
{
public class ShoppingCartTests : BaseTests
{
[Test]
public void ValidateCartItemsCount()
{
int cartCount = open()
.GoToCarAccessoriesPage()
.AddRandomItemToCart()
.AddRandomItemToCart()
.GetCartCount();
// Validate cart has 2 items
Assert.AreEqual(2, cartCount);
}
}
}
最后,我可能只需要提到,如果我只考虑12个项目,测试就会运行并工作,但获取用户可以在页面中看到的所有项目就像个人痴迷一样。此外,不确定我是否应该共享我正在测试的实际网站,或者这违反了社区规则或最佳实践。可以说,这是澳大利亚最受欢迎的五金店,网站相当复杂。谢谢
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报