From ec30f24141922958fc3f5565a745538e928f5d78 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sat, 31 Jan 2026 22:06:55 +0000 Subject: [PATCH] Resolve #284 - Open URL throws if the Url is not absolute --- CSF.Screenplay.Selenium/Actions/OpenUrl.cs | 2 ++ .../Actions/OpenUrlTests.cs | 20 ++++++++++++++++ .../MockDriverAttribute.cs | 23 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 Tests/CSF.Screenplay.Selenium.Tests/MockDriverAttribute.cs diff --git a/CSF.Screenplay.Selenium/Actions/OpenUrl.cs b/CSF.Screenplay.Selenium/Actions/OpenUrl.cs index 3bbd7264..58254350 100644 --- a/CSF.Screenplay.Selenium/Actions/OpenUrl.cs +++ b/CSF.Screenplay.Selenium/Actions/OpenUrl.cs @@ -15,6 +15,8 @@ public class OpenUrl : IPerformable, ICanReport public ValueTask PerformAsAsync(ICanPerform actor, CancellationToken cancellationToken = default) { var ability = actor.GetAbility(); + if(!uri.Uri.IsAbsoluteUri) + throw new InvalidOperationException($"The URL to open must be absolute; have you forgotten to grant {actor} the {nameof(UseABaseUri)} ability?"); ability.WebDriver.Url = uri.Uri.ToString(); return default; } diff --git a/Tests/CSF.Screenplay.Selenium.Tests/Actions/OpenUrlTests.cs b/Tests/CSF.Screenplay.Selenium.Tests/Actions/OpenUrlTests.cs index 0191cddc..b7e514b6 100644 --- a/Tests/CSF.Screenplay.Selenium.Tests/Actions/OpenUrlTests.cs +++ b/Tests/CSF.Screenplay.Selenium.Tests/Actions/OpenUrlTests.cs @@ -1,5 +1,7 @@ +using System; using CSF.Screenplay.Selenium.Elements; +using OpenQA.Selenium; using static CSF.Screenplay.PerformanceStarter; using static CSF.Screenplay.Selenium.PerformableBuilder; @@ -34,4 +36,22 @@ public async Task OpenTheUrlWithDifferentBasePathShouldYieldDifferentContent(ISt Assert.That(contents, Is.EqualTo("This is content at the deeper path.")); } + + [Test, AutoMoqData] + public async Task PerformAsAsyncShouldThrowIfTheUrlIsNotAbsolute(Actor actor, + [MockDriver] BrowseTheWeb ability) + { + actor.IsAbleTo(ability); + var sut = new OpenUrl(new NamedUri("foo/bar/baz.html")); + Assert.That(() => sut.PerformAsAsync(actor), Throws.InstanceOf()); + } + + [Test, AutoMoqData] + public async Task PerformAsAsyncShouldNotThrowIfTheUrlIsAbsolute(Actor actor, + [MockDriver] BrowseTheWeb ability) + { + actor.IsAbleTo(ability); + var sut = new OpenUrl(new NamedUri("https://example.com/foo/bar/baz.html")); + Assert.That(() => sut.PerformAsAsync(actor), Throws.Nothing); + } } \ No newline at end of file diff --git a/Tests/CSF.Screenplay.Selenium.Tests/MockDriverAttribute.cs b/Tests/CSF.Screenplay.Selenium.Tests/MockDriverAttribute.cs new file mode 100644 index 00000000..dae743ba --- /dev/null +++ b/Tests/CSF.Screenplay.Selenium.Tests/MockDriverAttribute.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using AutoFixture; +using CSF.Extensions.WebDriver; +using CSF.Extensions.WebDriver.Factories; +using Moq; + +namespace CSF.Screenplay.Selenium; + +public class MockDriverAttribute : CustomizeAttribute +{ + public override ICustomization GetCustomization(ParameterInfo parameter) + => new MockDriverCustomization(); +} + +public class MockDriverCustomization : ICustomization +{ + public void Customize(IFixture fixture) + { + fixture.Customize(c => c.FromFactory((WebDriverAndOptions d) => Mock.Of(m => m.GetDefaultWebDriver(null) == d + && m.GetWebDriver(It.IsAny(), null) == d))); + fixture.Customize(c => c.FromFactory((IGetsWebDriver d) => new BrowseTheWeb(d))); + } +} \ No newline at end of file