Yan
Yan

Reputation: 17

Selenium C# - Assert a specific tag within a recurring div

C# with selenium webdriver here! (very new to both, VbScript/QTP background)

On this webpage there's a recurring DIV. I want to look inside each instance of it, verify some content inside it/assert every instance of it. Specifically, I want to assert that: the text inside the first instance of each div (div's classname=span7) is wrapped in a <b> ... </b> tag. In other words, I need to assert that all the text in that DIV is bold.

The catch: There are two span7s, the first (I've called it "cat1") needs to be <b>bold</b>. The second span7, I can safely ignore. FYI, there are about ten occurrences of this div class ("types") all next to each other.

<div class="types">
   <div class="row">
      <div class="span3 h4">Cat1</div>
      <div class="span7">
         <b>THIS TEXT SHOULD BE BOLD</b>
      </div>
   </div>
   <div class="row">
      <div class="span3 h4">Cat2</div>
      <div class="span7">
         This text doesnt need to be bold
      </div>
   </div>
</div>

I would code it like this (this is a mixture of the C# I know + what I want C# to help me do)

if (theparentof  Driver.FindElements(By.Classname("span7") = "Cat2" 
then ignore
else Assert.Istrue( Driver.FindElements(By.Classname("span7")).Text contains <b>

Upvotes: 1

Views: 1472

Answers (2)

JeffC
JeffC

Reputation: 25644

The way I would tackle this is to loop through the DIV elements that have class types (CSS selector div.types). For each of those DIVs, look for the first DIV with class span7 (CSS selector div.span7) and then look for a B tag inside. If that B tag doesn't exist, then the test fails.

IReadOnlyCollection<IWebElement> types = Driver.FindElements(By.CssSelector("div.types"));
foreach (IWebElement type in types)
{
    Assert.Istrue(type.FindElement(By.CssSelector("div.span7")).FindElements(By.TagName("b")).Count > 0);
}

Upvotes: 1

Paul Hicks
Paul Hicks

Reputation: 14009

You're better off grabbing exactly the elements you want to test. In this case, you can either go with Selenium's provided By alternatives, or do it yourself using the general By.CssSelector or By.XPath.

Or you could fix the HTML so that all elements that need to be identified in tests have unique id attributes. This is definitely the best option.

Option 1: Use linq and By.ClassName: The Single() will throw an exception if there is more than one matching element.

var elementToTest = Driver.FindElements(
    By.ClassName("row").SelectMany(e =>
        e.FindElements(By.ClassName("span7"))).Single();

Option 2: Use CssSelector: Again the Single() will throw an exception if there is more than one matching element.

var elementToTest = Driver.FindElements(
    By.CssSelector(".row > .span7")).Single();

Option 3: Use XPath: Again the Single() will throw an exception if there is more than one matching element.

var elementToTest = Driver.FindElements(
    By.XPath("//div[contains(@class, 'row')]/div[contains(@class, 'span7')]"))
    .Single();

But really, you should change the HTML. Put id attributes on everything that you need to test.

Upvotes: 0

Related Questions