如何在不事先知道HTML标签类型的情况下,在c#中使用编码UI测试批量设置表单字段值

本文关键字:UI 测试 编码 字段 表单 设置 先知 HTML 标签 情况下 类型 | 更新日期: 2023-09-27 18:18:05

我使用SpecFlow与编码UI测试相结合,我需要在多个表单字段上设置值,我知道HTML标签的Id,但我不一定知道底层的System.Type对应于编码UI测试中的HTML标签。

基本上,我想以一种通用的方式使用Coded UI Tests给表单字段赋值。

示例SpecFlow步骤:

When I fill in the "Hours of Operation Information" table with the following values:
    | Shift    | From    | To      |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |
    | DAY ONLY | 12:30AM | 12:00AM |

"Shift","From"answers"To"列标题被映射到一个HTML标记Id,为了简洁起见,我将省略它,因为这个映射可以工作。

步骤定义:

[When(@"I fill in the ""(.*)"" table with the following values:")]
public void WhenIFillInTheTableWithTheFollowingValues(string tableName, Table table)
{
    HtmlTable grid = GetGrid(tableName);
    HtmlControl control = null;
    TableRow row = null;
    string id;
    for (int i = 0; i < table.Rows.Count; i++)
    {
        row = table.Rows[i];
        foreach (KeyValuePair<string, string> column in row)
        {
            id = String.Format(FormMap.GetFieldName(tableName, column.Key), i);
            control = new HtmlControl(grid);
            control.SearchProperties[HtmlControl.PropertyNames.Id] = id;
            Assert.IsTrue(control.Exists, "Form field '{0}' does not exist in row {1} of the '{2}' grid (id={3}).", column.Key, i, tableName, id);
            // How do I set the form field value?
        }
    }
}

我创建了一个助手方法,它接受一个HtmlControl对象和一个值,然后查看HTML标记名。然后,它尝试将其强制转换为适当的类,以便我可以与它交互。

public void SetFormFieldValue(HtmlControl control, object value)
{
    string controlValue = value == null ? null : value.ToString();
    string tagName = control.TagName.ToLower();
    string fieldType = null;
    switch (tagName)
    {
        case "select":
            ((HtmlComboBox)control).SelectedItem = controlValue;
            break;
        case "input":
            fieldType = control.GetProperty(HtmlEdit.PropertyNames.Type).ToString().ToLower();
            switch (fieldType)
            {
                case "text":
                case "password":
                    ((HtmlEdit)control).Text = controlValue;
                    break;
                case "checkbox":
                    ((HtmlCheckBox)control).Checked = controlValue.ToLower() == "checked";
                    break;
                case "radio":
                    ((HtmlRadioButton)control).Selected = controlValue.ToLower() == "checked";
                    break;
                default:
                    throw new ArgumentException(String.Format("Cannot set value on {0}[type={1}]", tagName, fieldType));
            }
            break;
        case "textarea":
            ((HtmlTextArea)control).Text = controlValue;
            break;
        default:
            throw new ArgumentException(String.Format("Cannot set value on {0} tag.", tagName));
    }
}

在这个特定的场景中,我试图在<select>盒子上设置值。我得到以下异常:

系统。InvalidCastException:无法强制转换类型为"microsoft . visualstudio . testtools . uittesting . htmlcontrols"的对象。

将HtmlControl'转换为' microsoft . visualstudio . testtools . uittesting . htmlcontrols . htmlcombobox '。

问题:

我如何在不知道HTML标签类型的情况下使用编码UI测试批量设置表单字段的值?

如何在不事先知道HTML标签类型的情况下,在c#中使用编码UI测试批量设置表单字段值

我应该知道最好不要问问题,因为我总是在问完之后才找到答案。

有一个叫做UITestControl的方法。CopyFrom获取任何UITestControl对象并将其复制到源对象:

public void SetFormFieldValue(HtmlControl control, object value)
{
    string controlValue = value == null ? null : value.ToString();
    string tagName = control.TagName.ToLower();
    string fieldType = null;
    switch (tagName)
    {
        case "select":
            // The concrete Coded UI Test class I want to interact with
            HtmlComboBox select = new HtmlComboBox();
            // Make the `select` object reference the same element as `control`
            select.CopyFrom(control);
            // Set the value on the dropdown list
            select.SelectedItem = controlValue;
            break;
        case "textarea":
            HtmlTextArea textarea = new HtmlTextArea();
            textarea.CopyFrom(control);
            textarea.Text = controlValue;
            break;
        ...
    }
}