Skip to content

Commit

Permalink
#116 Should.Not.Exist() fails for controls with specific find strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
YevgeniyShunevych committed Dec 1, 2017
1 parent 01c95b2 commit 626bb1e
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 25 deletions.
15 changes: 15 additions & 0 deletions src/Atata.Tests/Components/FindingPage.cs
Expand Up @@ -55,5 +55,20 @@ public class FindingPage : Page<_>
[ControlDefinition("input[@type='hidden']", Visibility = Visibility.Hidden)]
[FindById("type-hidden-input")]
public Input<string, _> TypeHiddenInputWithDeclaredDefinition { get; private set; }

[FindByCss("[name='unknown']")]
public RadioButton<_> MissingOptionByCss { get; private set; }

[FindByLabel("unknown")]
public RadioButton<_> MissingOptionByLabel { get; private set; }

[FindByXPath("*[@name='unknown']")]
public RadioButton<_> MissingOptionByXPath { get; private set; }

[FindById("unknown")]
public RadioButton<_> MissingOptionById { get; private set; }

[FindByColumnHeader("unknown")]
public RadioButton<_> MissingOptionByColumnHeader { get; private set; }
}
}
39 changes: 39 additions & 0 deletions src/Atata.Tests/FindingTests.cs
Expand Up @@ -94,6 +94,36 @@ public void Find_Hidden()
Assert.That(page.FailDisplayNoneInput.Exists(SearchOptions.Hidden()), Is.True);
}

[Test]
public void Find_ByCss_Missing()
{
VerifyNotExist(page.MissingOptionByCss);
}

[Test]
public void Find_ByLabel_Missing()
{
VerifyNotExist(page.MissingOptionByLabel);
}

[Test]
public void Find_ByXPath_Missing()
{
VerifyNotExist(page.MissingOptionByXPath);
}

[Test]
public void Find_ById_Missing()
{
VerifyNotExist(page.MissingOptionById);
}

[Test]
public void Find_ByColumnHeader_Missing()
{
VerifyNotExist(page.MissingOptionByColumnHeader);
}

private void VerifyRadioButton(RadioButton<FindingPage> radioButton, string expectedValue = "OptionC")
{
VerifyValue(radioButton, expectedValue);
Expand All @@ -107,5 +137,14 @@ private void VerifyValue<TOwner>(UIComponent<TOwner> component, string expectedV
{
Assert.That(component.Attributes.GetValue("value"), Is.EqualTo(expectedValue));
}

private void VerifyNotExist<TOwner>(UIComponent<TOwner> component)
where TOwner : PageObject<TOwner>
{
component.Should.Not.Exist();

Assert.Throws<NoSuchElementException>(() =>
component.Should.AtOnce.Exist());
}
}
}
Expand Up @@ -19,7 +19,7 @@ public FindByColumnHeaderStrategy(string headerXPath)

public ComponentScopeLocateResult Find(IWebElement scope, ComponentScopeLocateOptions options, SearchOptions searchOptions)
{
var headers = scope.GetAll(By.XPath(headerXPath).OfAnyVisibility());
var headers = scope.GetAll(By.XPath(headerXPath).With(searchOptions).OfAnyVisibility());
var headerNamePredicate = options.Match.GetPredicate();

int? columnIndex = headers.
Expand Down
56 changes: 32 additions & 24 deletions src/Atata/ScopeSearch/StrategyScopeLocator.cs
Expand Up @@ -52,16 +52,27 @@ public bool IsMissing(SearchOptions searchOptions = null, string xPathCondition
{
searchOptions = ResolveSearchOptions(searchOptions);

XPathComponentScopeLocateResult[] xPathResults = GetScopeLocateResults(searchOptions);
if (xPathResults.Any())
{
Dictionary<By, ISearchContext> byScopePairs = xPathResults.ToDictionary(x => x.CreateBy(xPathCondition), x => (ISearchContext)x.ScopeSource);
return component.Driver.Try().MissingAll(byScopePairs);
}
SearchOptions quickSearchOptions = SearchOptions.SafelyAtOnce();
quickSearchOptions.Visibility = searchOptions.Visibility;

bool isMissing = component.Driver.Try(searchOptions.Timeout, searchOptions.RetryInterval).Until(_ =>
{
XPathComponentScopeLocateResult[] xPathResults = GetScopeLocateResults(quickSearchOptions);
if (xPathResults.Any())
{
Dictionary<By, ISearchContext> byScopePairs = xPathResults.ToDictionary(x => x.CreateBy(xPathCondition), x => (ISearchContext)x.ScopeSource);
return component.Driver.Try(TimeSpan.Zero).MissingAll(byScopePairs);
}
else
{
return true;
}
});

if (!searchOptions.IsSafely && !isMissing)
throw ExceptionFactory.CreateForNotMissingElement(component.ComponentFullName);
else
{
return true;
}
return isMissing;
}

private SearchOptions ResolveSearchOptions(SearchOptions searchOptions)
Expand All @@ -79,34 +90,31 @@ private XPathComponentScopeLocateResult[] GetScopeLocateResults(SearchOptions se
IWebElement scopeSource = component.ScopeSource.GetScopeElement(component);

if (scopeSource == null && searchOptions.IsSafely)
return null;
return new XPathComponentScopeLocateResult[0];

ComponentScopeLocateResult result = strategy.Find(scopeSource, scopeLocateOptions, searchOptions);

return ResolveScopeLocateResults(result, scopeSource, searchOptions);
return ResolveScopeLocateResult(result, scopeSource, searchOptions);
}

private XPathComponentScopeLocateResult[] ResolveScopeLocateResults(ComponentScopeLocateResult result, IWebElement scopeSource, SearchOptions searchOptions)
private XPathComponentScopeLocateResult[] ResolveScopeLocateResult(ComponentScopeLocateResult result, IWebElement scopeSource, SearchOptions searchOptions)
{
result.CheckNotNull("result");
result.CheckNotNull(nameof(result));

MissingComponentScopeLocateResult missingResult = result as MissingComponentScopeLocateResult;
if (missingResult != null)
return null;
if (result is MissingComponentScopeLocateResult missingResult)
return new XPathComponentScopeLocateResult[0];

XPathComponentScopeLocateResult xPathResult = result as XPathComponentScopeLocateResult;
if (xPathResult != null)
if (result is XPathComponentScopeLocateResult xPathResult)
return new[] { xPathResult };

SequalComponentScopeLocateResult sequalResult = result as SequalComponentScopeLocateResult;
if (sequalResult != null)
if (result is SequalComponentScopeLocateResult sequalResult)
{
ComponentScopeLocateOptions nextScopeLocateOptions = sequalResult.ScopeLocateOptions ?? scopeLocateOptions;

if (sequalResult.ScopeSource != null)
{
ComponentScopeLocateResult nextResult = sequalResult.Strategy.Find(sequalResult.ScopeSource, nextScopeLocateOptions, searchOptions);
return ResolveScopeLocateResults(nextResult, sequalResult.ScopeSource, searchOptions);
return ResolveScopeLocateResult(nextResult, sequalResult.ScopeSource, searchOptions);
}
else
{
Expand All @@ -116,21 +124,21 @@ private XPathComponentScopeLocateResult[] ResolveScopeLocateResults(ComponentSco

var results = nextScopeSources.
Select(nextScopeSource => sequalResult.Strategy.Find(nextScopeSource, nextScopeLocateOptions, nextSearchOptions)).
Select(nextResult => ResolveScopeLocateResults(nextResult, nextScopeSources[0], nextSearchOptions)).
Select(nextResult => ResolveScopeLocateResult(nextResult, nextScopeSources[0], nextSearchOptions)).
Where(xPathResults => xPathResults != null).
SelectMany(xPathResults => xPathResults).
ToArray();

if (results.Any())
return results;
else if (searchOptions.IsSafely)
return null;
return new XPathComponentScopeLocateResult[0];
else
throw ExceptionFactory.CreateForNoSuchElement(by: sequalResult.ScopeSourceBy);
}
}

throw new ArgumentException("Unsupported ComponentScopeLocateResult type: {0}".FormatWith(result.GetType().FullName), "result");
throw new ArgumentException($"Unsupported {nameof(ComponentScopeLocateResult)} type: {result.GetType().FullName}", nameof(result));
}
}
}

0 comments on commit 626bb1e

Please sign in to comment.