Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CSF.Screenplay.Selenium/Builders/FindElementBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace CSF.Screenplay.Selenium.Builders
public class FindElementBuilder : IGetsPerformableWithResult<SeleniumElement>
{
readonly ITarget target;
readonly IHasSearchContext searchContext;
Locator locator;
string name;

Expand Down Expand Up @@ -46,7 +47,9 @@ public FindElementBuilder AndNameIt(string name)

IPerformableWithResult<SeleniumElement> IGetsPerformableWithResult<SeleniumElement>.GetPerformable()
{
return SingleElementPerformableWithResultAdapter.From(new FindElement(name, locator), target);
return target != null
? new FindElement(target, name, locator)
: new FindElement(searchContext, name, locator);
}

/// <summary>
Expand All @@ -59,13 +62,12 @@ public FindElementBuilder(ITarget target)
}

/// <summary>
/// Converts a <see cref="FindElementsBuilder"/> to a <see cref="SingleElementPerformableWithResultAdapter{SeleniumElement}"/>.
/// Initializes a new instance of the <see cref="FindElementsBuilder"/> class with the specified target.
/// </summary>
/// <param name="builder">The <see cref="FindElementBuilder"/> instance to convert.</param>
/// <returns>A <see cref="SingleElementPerformableWithResultAdapter{SeleniumElement}"/> instance.</returns>
public static implicit operator SingleElementPerformableWithResultAdapter<SeleniumElement>(FindElementBuilder builder)
/// <param name="searchContext">The target within which elements will be found.</param>
public FindElementBuilder(IHasSearchContext searchContext)
{
return SingleElementPerformableWithResultAdapter.From(new FindElement(builder.name, builder.locator), builder.target);
this.searchContext = searchContext ?? throw new System.ArgumentNullException(nameof(searchContext));
}
}
}
14 changes: 8 additions & 6 deletions CSF.Screenplay.Selenium/Builders/FindElementsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace CSF.Screenplay.Selenium.Builders
public class FindElementsBuilder : IGetsPerformableWithResult<SeleniumElementCollection>
{
readonly ITarget target;
readonly IHasSearchContext searchContext;
Locator locator;
string name;

Expand Down Expand Up @@ -46,7 +47,9 @@ public FindElementsBuilder AndNameThem(string name)

IPerformableWithResult<SeleniumElementCollection> IGetsPerformableWithResult<SeleniumElementCollection>.GetPerformable()
{
return SingleElementPerformableWithResultAdapter.From(new FindElements(name, locator), target);
return target != null
? new FindElements(target, name, locator)
: new FindElements(searchContext, name, locator);
}

/// <summary>
Expand All @@ -59,13 +62,12 @@ public FindElementsBuilder(ITarget target)
}

/// <summary>
/// Converts a <see cref="FindElementsBuilder"/> to a <see cref="SingleElementPerformableWithResultAdapter{SeleniumElementCollection}"/>.
/// Initializes a new instance of the <see cref="FindElementsBuilder"/> class with the specified target.
/// </summary>
/// <param name="builder">The <see cref="FindElementsBuilder"/> instance to convert.</param>
/// <returns>A <see cref="SingleElementPerformableWithResultAdapter{SeleniumElementCollection}"/> instance.</returns>
public static implicit operator SingleElementPerformableWithResultAdapter<SeleniumElementCollection>(FindElementsBuilder builder)
/// <param name="searchContext">The target within which elements will be found.</param>
public FindElementsBuilder(IHasSearchContext searchContext)
{
return SingleElementPerformableWithResultAdapter.From(new FindElements(builder.name, builder.locator), builder.target);
this.searchContext = searchContext ?? throw new System.ArgumentNullException(nameof(searchContext));
}
}
}
30 changes: 26 additions & 4 deletions CSF.Screenplay.Selenium/Elements/SeleniumElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ namespace CSF.Screenplay.Selenium.Elements
/// a <see cref="Name"/>. This optional, but recommended, technique facilitates human-readable reporting.
/// </para>
/// </remarks>
public class SeleniumElement : ITarget
public class SeleniumElement : ITarget, IHasWebElement, IHasSearchContext
{
const string unknownNameFormat = "an HTML {0} element";

/// <inheritdoc/>
public string Name { get; }

/// <summary>
/// Gets the native Selenium web element.
/// </summary>
/// <inheritdoc/>
public IWebElement WebElement { get; }

ISearchContext IHasSearchContext.SearchContext => WebElement;

SeleniumElementCollection ITarget.GetElements(IWebDriver driver) => new SeleniumElementCollection(new[] { this }, Name);

SeleniumElement ITarget.GetElement(IWebDriver driver) => this;
Expand All @@ -42,4 +42,26 @@ public SeleniumElement(IWebElement webElement, string name = null)
Name = name ?? string.Format(unknownNameFormat, webElement.TagName);
}
}

/// <summary>
/// An object which exposes a Selenium web element.
/// </summary>
public interface IHasWebElement : IHasName
{
/// <summary>
/// Gets the native Selenium web element.
/// </summary>
IWebElement WebElement { get; }
}

/// <summary>
/// An object which exposes a Selenium search context.
/// </summary>
public interface IHasSearchContext : IHasName
{
/// <summary>
/// Gets the native Selenium search context.
/// </summary>
ISearchContext SearchContext { get; }
}
}
34 changes: 34 additions & 0 deletions CSF.Screenplay.Selenium/Elements/ShadowRoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using OpenQA.Selenium;

namespace CSF.Screenplay.Selenium.Elements
{
/// <summary>
/// Implementation of <see cref="IHasSearchContext"/> which represents an HTML shadow-root node.
/// </summary>
/// <seealso cref="Questions.GetShadowRootNatively"/>
/// <seealso cref="Questions.GetShadowRootWithJavaScript"/>
/// <seealso cref="Tasks.GetShadowRoot"/>
public class ShadowRoot : IHasSearchContext
{
readonly ISearchContext shadowRoot;

/// <inheritdoc/>
public ISearchContext SearchContext => shadowRoot;

/// <inheritdoc/>
public string Name { get; }

/// <summary>
/// Initializes a new instance of <see cref="ShadowRoot"/>.
/// </summary>
/// <param name="shadowRoot">The wrapped shadow root element</param>
/// <param name="name">The name of this Shadow Root object</param>
/// <exception cref="ArgumentNullException">If <paramref name="shadowRoot"/> is <see langword="null"/></exception>
public ShadowRoot(ISearchContext shadowRoot, string name = null)
{
this.shadowRoot = shadowRoot ?? throw new ArgumentNullException(nameof(shadowRoot));
Name = name ?? "Shadow root";
}
}
}
123 changes: 0 additions & 123 deletions CSF.Screenplay.Selenium/Elements/ShadowRootAdapter.cs

This file was deleted.

Loading
Loading