Last active
October 31, 2019 14:34
-
-
Save YevgeniyShunevych/37bad1e3c762b476c355fca696eb3708 to your computer and use it in GitHub Desktop.
Atata - FindInShadowDomAttribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace Atata | |
{ | |
public class FindInShadowDomAttribute : FindAttribute | |
{ | |
public FindInShadowDomAttribute(params string[] shadowContainerXPaths) | |
{ | |
ShadowContainerXPaths = shadowContainerXPaths; | |
} | |
public IEnumerable<string> ShadowContainerXPaths { get; } | |
protected override Type DefaultStrategy => typeof(FindInShadowDomStrategy); | |
protected override IEnumerable<object> GetStrategyArguments() | |
{ | |
yield return ShadowContainerXPaths; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Linq; | |
using OpenQA.Selenium; | |
namespace Atata | |
{ | |
public class FindInShadowDomStrategy : IComponentScopeLocateStrategy | |
{ | |
private const string GetShadowRootChildElementsScript = | |
@"var shadowChildren = arguments[0].shadowRoot.children; | |
var filteredChildren = []; | |
for (var i = 0; i < shadowChildren.length; i++) { | |
var nodeName = shadowChildren[i].nodeName; | |
if (nodeName !== 'STYLE' && nodeName !== 'SCRIPT') { | |
filteredChildren.push(shadowChildren[i]); | |
} | |
} | |
return filteredChildren;"; | |
public FindInShadowDomStrategy(IEnumerable<string> shadowContainerXPaths) | |
{ | |
ShadowContainerXPaths = shadowContainerXPaths; | |
} | |
public IEnumerable<string> ShadowContainerXPaths { get; } | |
public ComponentScopeLocateResult Find(IWebElement scope, ComponentScopeLocateOptions options, SearchOptions searchOptions) | |
{ | |
string shadowContainerXPath = ShadowContainerXPaths.First(); | |
By shadowContainerBy = By.XPath(shadowContainerXPath). | |
With(searchOptions). | |
Named("shadow container"); | |
IWebElement shadowContainer = scope.Get(shadowContainerBy); | |
if (shadowContainer == null) | |
{ | |
if (searchOptions.IsSafely) | |
return new MissingComponentScopeLocateResult(); | |
else | |
throw ExceptionFactory.CreateForNoSuchElement(options.GetTermsAsString(), by: shadowContainerBy, searchContext: scope); | |
} | |
var shadowChildren = (ReadOnlyCollection<IWebElement>)AtataContext.Current.Driver.ExecuteScript( | |
GetShadowRootChildElementsScript, | |
shadowContainer); | |
IEnumerable<string> deeperShadowContainerXPaths = ShadowContainerXPaths.Skip(1).ToArray(); | |
IComponentScopeLocateStrategy nextStrategy = deeperShadowContainerXPaths.Any() | |
? new FindInShadowDomStrategy(deeperShadowContainerXPaths) as IComponentScopeLocateStrategy | |
: options.Index.HasValue | |
? new FindByIndexStrategy() as IComponentScopeLocateStrategy | |
: new FindFirstDescendantOrSelfStrategy(); | |
return new SequalComponentScopeLocateResult(shadowChildren, nextStrategy); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment