Недавно столкнулся с такой проблемой в 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 умеет определять состояние отображения элемента страницы.
Код нашел, но теперь нужно найти, откуда он был сгенерирован: