d.rodriguez
d.rodriguez

Reputation: 319

Obtaining all elements of a particular class plus navigating back and forth with CodedUI

I have the following HTML

`<table id="tableRepeat44" class="scaledTableGroup">
 <tbody>
   <tr>
   <tr class="grpTableRegRow">
     <td class="borderCell" title="Strongly Disagree">
       <input id="QID16108TAG1" value="1" name="QID16108TAG" type="radio">
     <td class="borderCell" title="Disagree">
       <input id="QID16108TAG2" value="2" name="QID16108TAG" type="radio">
     <td class="borderCell" title="Somewhat Disagree">
       <input id="QID16108TAG3" value="3" name="QID16108TAG" type="radio">
     <td class="borderCell" title="Somewhat Agree">
       <input id="QID16108TAG4" value="4" name="QID16108TAG" type="radio">
     <td class="borderCell" title="Agree">
       <input id="QID16108TAG5" value="5" name="QID16108TAG" type="radio">
     <td class="borderCell" title="Strongly Agree">
       <input id="QID16108TAG6" value="6" name="QID16108TAG" type="radio">
     <td class="questionColumn">
       <span id="lblsubq16108_7" class="Answer">This is a question. </span>
     </td>
   </tr>
   <tr class="grpTableAltRow">
   <tr class="grpTableRegRow">
   <tr class="grpTableAltRow">
 </tbody>
</table>`

Each row contains the same syntax as the expanded first row. What I'm looking to do through CodedUI is obtain all of the questions' text (e.g. td:nth-of-type(7) > span || class="Answer") and then navigate out to the parent row so that I can access the Agree/Disagree radio button tds and make a selection based off a passed in parameter.

I have tried variations of

        HtmlCustom questionsTable = new HtmlCustom(browser);
        HtmlControl controls = new HtmlControl(questionsTable);
        if (howToAnswer.Trim().ToLower() == "correct")
        {
            questionsTable.SearchProperties[HtmlCustom.PropertyNames.TagName] = "Tbody";
            controls.SearchProperties.Add(HtmlControl.PropertyNames.Class, "Answer");
            UITestControlCollection collection = controls.FindMatchingControls();

            foreach (UITestControl answers in collection)
            {
                Debug.Write(answers);
            }                
        }

And it resulted in ControlType [Pane] ClassName [HtmlPane] TagName [SPAN], UniqueIdentifier [154] Id [lblsubq16172_7] Name [] for each row in the table. So I was close, but I haven't been able to figure out how to obtain the text for .InnerText is not accessible on answers.

And the last item to address would be how to navigate back and forth while maintaining reference to that particular row?

Upvotes: 0

Views: 68

Answers (1)

Ryanman
Ryanman

Reputation: 880

This is actually a pretty cool question. Remember that all elements in the DOM in Coded UI have a single parent and a collection of children.

In short, what you'll want to do is:

  • Create the Table Control
  • Iterate through each row
  • In each row, find the first HtmlSpan with class = "Answer". Add this to a collection of HtmlSpans.
  • Once you have this collection of Spans, you can once again iterate through this collection. From there I'd suggest creating a helper method that gets a "Sibling Control" based on an attribute. The method would look at the parent control's child collection and then get an element from there.

The last step is only necessary if you can't just select the correct answer while iterating through each row in the table. In my book, I'd rather:

  • Iterate through each row
  • Find the Answer element and its inner text
  • Use the inner text to choose the correct answer by checking the correct radio button in this same row(I assume this is data driven).

Does this make sense? Let me know if this helps at all or if you need more detail. I don't have my helper method code but it's exceedingly simple. Something like:

public static UiTestControl GetSiblingByClass (UiTestControl ctrl, string class) {
    var parent = ctrl.Parent;
    var controlToReturn = new UiTestControl(parent);
    controlToReturn.SearchProperties[HtmlControl.PropertyNames.Class] = class;
    return controlToReturn;
}

Upvotes: 1

Related Questions