1

I've been learning automation with C# for some weeks now, though I'm progressing in a slow manner. I'm currently trying to do a certain test using a mock page (automationexercise.com).

The page mocks an E-commerce.

I want to capture the products listed in the main page so I can store their properties and test them.

The original html from the page looks like this: There is a div, which contains 34 divs with the class class="col-sm-4" and inside each one of those we have a content like this:

I want to capture the content of the paragraph that appears in the picture that is present in each one of those 34 divs containing the product name.

I wrote this code expecting it to print the name of each product but it returns a selector error:

IList<IWebElement> productos = driver.FindElements(By.CssSelector("div[class=col-sm-4]"));

foreach (IWebElement element in productos)
{

    IWebElement asd = element.FindElement(By.XPath("./div[1]/div[1]/div[1]/p[1]"));

    TestContext.Progress.WriteLine(asd.Text);
}

I have also tried some more variations, none had any success at all except the following Xpath which returns the content of the paragraph in the firs product 34 times.

//div[@class='productinfo text-center']//p

Can someone please help me understand the correct way to build the selector (be it xpath or css selector) in this case?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Maybe this page is loaded dynamically with AJAX. In that case all of your attempts will fail, because the DOM is not fully created at the time of querying. – zx485 Jun 09 '23 at 15:53
  • Souldn't in that case also fail the iteration trough the product items? i forgot to specify it, but i'm able to capture the class="col-sm-4" objects @zx485 – Luciano Valdez Jun 09 '23 at 16:37

4 Answers4

0

To capture the product names, you can use either XPath or CSS selector as following.

Xpath -> IList<IWebElement> products = driver.FindElements(By.XPath("//div[@class='col-sm-4']//p"));

CSS -> IList<IWebElement> products = driver.FindElements(By.CssSelector("div.col-sm-4 p"));

foreach (IWebElement product in products)
{
    TestContext.Progress.WriteLine(product.Text);
}
0

Within the browser console and JavaScript the code

document.querySelectorAll('div.col-sm-4').forEach(div => console.log(div.querySelector('div.productinfo p').textContent))

gives a similar error while

document.querySelectorAll('div.col-sm-4').forEach(div => console.log(div.querySelector('div.productinfo p')?.textContent))

outputs all product names and some undefined.

So I would try

IList<IWebElement> productos = driver.FindElements(By.CssSelector("div[class=col-sm-4]"));

foreach (IWebElement element in productos)
{
    try
    {
        IWebElement asd = element.FindElement(By.CssSelector("div.productinfo p"));

        TestContext.Progress.WriteLine(asd.Text);
    }
    catch (NoSuchElementException e) { }

}

That can then probably be simplified to

IList<IWebElement> productos = driver.FindElements(By.CssSelector("div[class=col-sm-4] div.productinfo p"));

foreach (IWebElement element in productos)
{
    Console.WriteLine(element.Text);
}
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
0

With a little tweak in the CssSelector as:

div.productinfo p

all the items can be identified as follows:

40


Solution

To capture the products listed in the main webpage and you can use either of the following locator strategies:

  • Using CssSelector:

    driver.Url = "https://www.allbanglanewspaper.xyz/";
    IList<IWebElement> elements = driver.FindElements(By.CssSelector("div.productinfo p"));
    foreach (IWebElement ele in elements)
    {
        Console.WriteLine(ele.Text);
    }
    
  • Using XPath:

    driver.Url = "https://www.allbanglanewspaper.xyz/";
    IList<IWebElement> elements = driver.FindElements(By.XPath("//div[contains(@class, 'productinfo')]//p"));
    foreach (IWebElement ele in elements)
    {
        Console.WriteLine(ele.Text);
    }
    
  • Console Output:

    Blue Top
    Men Tshirt
    Sleeveless Dress
    Stylish Dress
    Winter Top
    ...
    ...
    ...
    Stylish Dress
    Winter Top
    Summer White Top
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    Thank you very much! it really worked like magic! i hadn't seen that kind of cssselector before!Also helped me a lot understanding the nonesense that was trying to capture the card first and then trying to acces the paragraph! – Luciano Valdez Jun 12 '23 at 17:18
0

You can get all of those p's with:

driver.execute_script("""
  return [...document.querySelectorAll('.col-sm-4')].map(div => div.querySelector('.productinfo p')?.innerText)
""")
pguardiario
  • 53,827
  • 19
  • 119
  • 159