вторник, января 03, 2012

WatiN, Selenium и IsDisplayed

Недавно столкнулся с такой проблемой в WatiN, которая заключается в том, что нет стандартной возможности выяснить отображается сейчас элемент на экране или нет. В наш век сверх динамичных приложений, в которых кода на клиентском JavaScript больше чем серверного, возможность выяснить отображается ли элемент на экране или нет – жизненно важно.

По крайне мере для меня, потому что, я могу отличить одну страницу приложения от другой, только привязавшись к конкретному элементу, который может всегда существовать в DOM страницы, но отображаться только после некоторой последовательности действий.

Пока что я правильного решения не нашел. Но, куда копать знаю.
Первое что пришло на ум, это реализовать проверку стиля display и visibility для элемента. И в последствие оказалось, что стиль, например, для visibility может быть visible, hidden и… inherit…
А inherit означает что нужно спросить родительский элемент о его стиле, и если и тот поморозится ответить, и скажет что inherit, то приодеться подниматься по дереву DOM все выше и выше.
В общем, код расширения для класса Element получился следующий:

public static string GetElementVisibility(Element element)
        {
            string visibilityProp = element.Style.GetAttributeValue("visibility");
            if (element.Style.GetAttributeValue("visibility").Equals("inherit", StringComparison.OrdinalIgnoreCase))
            {
                return GetElementVisibility(element.Parent);
            }
            else
            {
                return visibilityProp;
            }
        }


        public static bool ExistsAndVisible(this Element element)
        {
            bool elementExists = element.Exists;
            if (elementExists)
            {
                bool hasStyleDisplayNone = element.Style.Display.Equals("none", StringComparison.OrdinalIgnoreCase);
                string visibilityProp = GetElementVisibility(element);
                bool hasStyleVisibilityHidden = visibilityProp.Equals("hidden", StringComparison.OrdinalIgnoreCase);

                elementExists = !hasStyleDisplayNone && !hasStyleVisibilityHidden;
            }
            return elementExists;
        }

На сколько я понял, автор библиотеки WatiN Extensions тоже сталкивался с подобной проблемой, и предложил следующею реализацию, которая, к сожалению, не подходит в моем случае.
ElementExtensions:

public static bool IsVisible<TElement>(this TElement element, bool assert = false, bool assertExpectedValue = true) where TElement : Element
        {
            var result = element.Style.Display.ToLower() != "none";

            if (result && Settings.MaxVisibilitySearchScope > 0)
            {
                var parent = element.Parent;

                for (var i = 0; i < Settings.MaxVisibilitySearchScope; i++)
                {
                    if (!result || parent == null)
                    {
                        break;
                    }

                    result = parent.Style.Display.ToLower() != "none";
                    parent = parent.Parent;
                }
            }

            if (assert)
            {
#if !Xunit
                Assert.AreEqual(assertExpectedValue, result, string.Format("Element of type '{0}' is {1}visible", typeof(TElement).Name, assertExpectedValue ? "not " : string.Empty));
#else
                Assert.True(assertExpectedValue == result, string.Format("Element of type '{0}' is {1}visible", typeof(TElement).Name, assertExpectedValue ? "not " : string.Empty));
#endif
            }

            return result;
        }

И, сегодня я нашел, что Selenium умеет определять состояние отображения элемента страницы.

Код нашел, но теперь нужно найти, откуда он был сгенерирован:

Комментариев нет: