SpecBind / specbind

Bridges the SpecFlow and popular UI automation frameworks to simplify acceptance tests.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add support for custom HTML control classes derived from a specific HTML control class in `Microsoft.VisualStudio.TestTools.UITesting.HtmlControls`

icnocop opened this issue · comments

commented

Hi.

I'd like to request support for custom HTML control classes derived from a specific HTML control class in Microsoft.VisualStudio.TestTools.UITesting.HtmlControls

For example, if I try to automate selecting an item in a drop down list control by using the HtmlComboBox class, but the element is rendered on the HTML page using the Kendo UI DropDownList widget, the test will fail to select the item.

Instead, I can run JavaScript on the page using the ExecuteScript method on the IBrowser instance to get the selected value and set a new value.

For example, here is a helper class I created:

    internal class KendoDropDownList
    {
        private readonly IBrowser browser;
        private readonly string elementSelector;

        internal KendoDropDownList(IBrowser browser, string elementSelector)
        {
            this.browser = browser;
            this.elementSelector = elementSelector;
        }

        internal string GetValue()
        {
            return (string)this.browser.ExecuteScript($"return $('{this.elementSelector}').data('kendoDropDownList').value();");
        }

        internal void SetValue(object value)
        {
            this.browser.ExecuteScript($"$('{this.elementSelector}').data('kendoDropDownList').value('{value}');");

            // trigger the change event to update the bindings
            this.browser.ExecuteScript($"$('{this.elementSelector}').data('kendoDropDownList').trigger('change');");
        }
    }

I can then use it my page/dialog like this:

    public class PersonPage : HtmlDocument
    {
        private readonly IBrowser browser;

        private readonly KendoDropDownList genderDropDownList;

        public PersonPage(IBrowser browser, UITestControl parent)
            : base(parent)
        {
            this.browser = browser;
            this.genderDropDownList = new KendoDropDownList(browser, "#gender");
        }

        public string Gender
        {
            get
            {
                return this.genderDropDownList.GetValue();
            }

            set
            {
                this.roleDropDownList.SetValue(value);
            }
        }
    }

This works fine, but when I tried to simplify the page/dialog model as follows:

    public class PersonPage : HtmlDocument
    {
        public PersonPage(UITestControl parent)
            : base(parent)
        {
        }

        [ElementLocator(Id = "gender")]
        public KendoDropDownList Gender { get; set; }
    }

And refactored the class as follows:

    public class KendoDropDownList : HtmlComboBox
    {
        private readonly IBrowser browser;

        public KendoDropDownList()
        {
        }

        public KendoDropDownList(UITestControl parent)
        {
            this.browser = ScenarioContext.Current.Get<IBrowser>("CurrentBrowser");
        }

        public override string SelectedItem
        {
            get
            {
                return (string)this.browser.ExecuteScript($"return $('#{this.Id}').data('kendoDropDownList').value();");
            }

            set
            {
                this.browser.ExecuteScript($"$('#{this.Id}').data('kendoDropDownList').value({value});");

                // trigger the change event to update the bindings
                this.browser.ExecuteScript($"$('#{this.Id}').data('kendoDropDownList').trigger('change');");
            }
        }
    }

And run a scenario like this:

    Given I entered data
     | Field     | Value |
     | Gender | Male |

I get the following exception:

SpecBind.Pages.ElementExecuteException: Errors occurred while entering data. Details: Cannot find input handler for property 'Gender' on page PersonPage. Element propertyValue was: KendoDropDownList;

I expect SpecBind to be able to support HTML control classes that inherit from HtmlComboBox.

In this example, I think the issue is in the GetPageFillMethod method of the CodedUIPage class here: https://github.com/dpiessens/specbind/blob/master/src/SpecBind.CodedUI/CodedUIPage.cs#L275:

if (propertyType == typeof(HtmlComboBox))

Since my class inherits from HtmlComboBox, this condition returns false.

Instead, I think those types of condition statements should be refactored as follows:

if (typeof(HtmlComboBox).IsAssignableFrom(propertyType))

Thank you.

For reference, http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist