编码UI测试 - 根据表格行上的其他内容单击控件

3
我正在使用Visual Studio 2010为C#的Web应用程序制作Coded UI测试,希望根据第1列的内部文本单击表格中第6列中的按钮。这是否可能?
例如,我有一个表格,第一列是名称,其他信息和第6列是按钮。所有都是自动生成的。
我假设如果我可以从包含“John Smith”的单元格中获取行号,那么我就可以按下该行第6列的按钮。 有什么想法吗?我已经尝试过谷歌搜索和查看可以传递哪些参数,但我一直卡住了。
3个回答

4

以下基于以下内容的一些提示可能有所帮助。

通过从Coded UI录制器为断言或单击单元格生成的代码中复制代码来访问HTML表格。您应该得到类似于以下内容:

HtmlCell theTable = new HtmlCell(this.UItheWindow.UItheTable.UIItemTable);

表格的单元格可以通过添加属性来访问,例如:
theTable.FilterProperties[HtmlCell.PropertyNames.RowIndex] = "0";
theTable.FilterProperties[HtmlCell.PropertyNames.ColumnIndex] = "6";
UITestControl cell = theTable.Find();
HtmlCell wantedCell = (HtmlCell)cell;

上述代码可用作返回wantedCell值的方法体。现在,该名称应该可以使用:
wantedCell.InnerText;

访问要点击的按钮应该遵循类似的方法。另一种方法是使用GetChildren方法来遍历表格。先获取如上所述的theTable,然后像这样进行操作。
UITestControlCollection children = theTable.GetChildren();

循环遍历children检查行属性。当找到所需的行时,调用该行的GetChildren并通过它们进行循环以找到所需的列。一些要点:您可能需要在循环行之前循环列。您可以直接索引行和列的UITestControlCollection而不需要循环和检查值。根据表格编写的方式,可能会在表格和所需单元格之间添加附加级别,因此您可能需要检查子项、孙子项、曾孙子项等。


1
我建议使用对象检查器(十字准线)来检查对象,以确保该方法能够产生结果。 我很少看到表格的行为符合预期 :) 它们经常被编码嵌套,不一定是HtmlCells。也许只是我的运气不好,但我不认为单元格就是单元格。 - yonitdm
1
@yonitdm 提出了一个非常好的观点。我已经使用十字线来检查结构。我还使用 GetChildren 进行了递归下降结构,并打印了找到的每个控件的各种属性。 - AdrianHHH

2

我有几个扩展方法,用于处理表格中的内容(手工编码,而不是使用录制器)-

这个表格的扩展方法获取包含请求文本的单元格或控件的第一行。

public static HtmlRow GetRow(this HtmlTable table, string cellContent)
{
  if((UITestControl)table == (UITestControl)null)
    throw new ArgumentNullException("table");

  if(cellContent.Length > 80)
    cellContent = cellContent.Substring(0, 80); //Our table cells only display the first 80 chars

  //Locate the first control in the table that has the inner text that I'm looking for
  HtmlControl searchControl = new HtmlControl(table);
  searchControl.SearchProperties.Add(PropertyNames.InnerText, cellContent);

  //Did we find a control with that inner text?
  if(!searchControl.TryFind())
  {
    //If not, the control might be an HtmlEdit with the text
    HtmlEdit firstTableEdit = new HtmlEdit(table);
    //Get all of the HtmlEdits in the table
    UITestControlCollection matchingEdits = firstTableEdit.FindMatchingControls();
    //Iterate through them, see if any have the correct text
    foreach (UITestControl edit in matchingEdits)
    {
      if(cellContent == ((HtmlEdit)edit).Text)
        searchControl = (HtmlControl)edit;
    }
  }

  //We have(hopefully) found the control in the table with the text we're searching for
  //Now, we spiral up through its parents until we get to an HtmlRow
  while (!(searchControl is HtmlRow))
  {
    searchControl = (HtmlControl)searchControl.GetParent();
  }

  //The control we're left with should be an HtmlRow, and should be an Ancestor of a control that has the correct text
  return (HtmlRow)searchControl;
}

一旦您能够获取正确的行,就相对容易获取该行中的正确控件(或该行中给定单元格中的正确控件)。
在您的示例中,您在行的第6列中有一个按钮。该按钮可能具有某些相关属性,但即使没有这些属性,如果我们能正确地限制搜索,它仍将起作用。假设我们的表名为UITableCustomers-声明一个新按钮,并将其限制为仅位于包含“John Smith”的行中的第6(索引5)个单元格。
Mouse.Click(new HtmlInputButton(UITableCustomers.GetRow("John Smith").Cells[5]));

显然,如果给定的文本在表格的控件中不存在,这个调用将会失败。

哇,这非常令人印象深刻,但我感到不确定该将它放在哪里,还有它如何知道要查看哪个表?我需要以某种方式传递一个表吗? - Paul Cunningham
扩展方法可以放置在任何静态类中,然后通过using语句进行引用 - 通常,创建一个专门用于保存扩展方法的静态类。在对HtmlTable实现扩展方法之后,该表现在具有了.GetRow()方法 - 如您在我的示例中所见,我将UITableCustomers指定为我的表,并在其上调用.GetRow()。请参阅:http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx - Nick Raverty
只是尝试实现这段代码,在这一行 searchControl.SearchProperties.Add(PropertyNames.InnerText, cellContent);我得到了“PropertyNames不存在”的错误, 并且在这一行 if (!searchControl.TryFind()) TryFind也不存在。 - Paul Cunningham
@PaulCunningham,我刚刚注意到这个问题被标记为VS2010,TryFind()在那里不可用 - 一个.Exists检查代替.TryFind()应该以类似的方式工作。但是PropertyNames类应该存在于Microsoft.VisualStudio.TestTools.UITesting.HtmlControls命名空间中 - 你是否缺少了一个using语句?我手头没有2010来尝试它。如果有任何疑问,请告诉我。 - Nick Raverty
没问题,是的,我想可能是缺少了一个使用语句,所以我会尝试找出哪个。 - Paul Cunningham

-1

你的问题对我来说不是很清楚,但请查看 jQuery.trigger 的 文档

这个方法可以让你模拟一个点击事件。希望这是你需要的。


抱歉,我觉得你完全误解了问题。 - Paul Cunningham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接