Skip to content

Instantly share code, notes, and snippets.

@YevgeniyShunevych
Last active October 31, 2019 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YevgeniyShunevych/37bad1e3c762b476c355fca696eb3708 to your computer and use it in GitHub Desktop.
Save YevgeniyShunevych/37bad1e3c762b476c355fca696eb3708 to your computer and use it in GitHub Desktop.
Atata - FindInShadowDomAttribute
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;
}
}
}
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