diff --git a/src/OrchardCoreContrib.Testing.UI/Browser.cs b/src/OrchardCoreContrib.Testing.UI/Browser.cs
index 3162664..416e313 100644
--- a/src/OrchardCoreContrib.Testing.UI/Browser.cs
+++ b/src/OrchardCoreContrib.Testing.UI/Browser.cs
@@ -22,6 +22,9 @@ public class Browser(IPlaywrightBrowserAccessor playwrightBrowserAccessor) : IBr
///
public string Version { get; set; } = playwrightBrowserAccessor.PlaywrightBrowser.Version;
+ ///
+ public UITestOptions TestOptions { get; set; }
+
///
public async Task OpenPageAsync(string url)
{
@@ -29,7 +32,7 @@ public async Task OpenPageAsync(string url)
await playwrightPage.GotoAsync(url);
- var page = new Page(new PlaywrightPageAccessor(playwrightPage))
+ var page = new Page(new PlaywrightPageAccessor(playwrightPage), this)
{
Title = await playwrightPage.TitleAsync(),
Content = await playwrightPage.ContentAsync()
diff --git a/src/OrchardCoreContrib.Testing.UI/BrowserFactory.cs b/src/OrchardCoreContrib.Testing.UI/BrowserFactory.cs
index fbc951f..7bd959d 100644
--- a/src/OrchardCoreContrib.Testing.UI/BrowserFactory.cs
+++ b/src/OrchardCoreContrib.Testing.UI/BrowserFactory.cs
@@ -39,6 +39,10 @@ public static async Task CreateAsync(IPlaywright playwright, UITestOpt
_ => throw new NotSupportedException()
};
- return new Browser(new PlaywrightBrowserAccessor(browser)) { Type = testOptions.BrowserType };
+ return new Browser(new PlaywrightBrowserAccessor(browser))
+ {
+ Type = testOptions.BrowserType,
+ TestOptions = testOptions
+ };
}
}
diff --git a/src/OrchardCoreContrib.Testing.UI/Element.cs b/src/OrchardCoreContrib.Testing.UI/Element.cs
index 86a29b8..c6e23ba 100644
--- a/src/OrchardCoreContrib.Testing.UI/Element.cs
+++ b/src/OrchardCoreContrib.Testing.UI/Element.cs
@@ -7,8 +7,18 @@ namespace OrchardCoreContrib.Testing.UI;
///
/// The .
/// The .
-public class Element(ILocator locator) : IElement
+/// The .
+public class Element(ILocator locator, IPage page) : IElement
{
+ private readonly LocatorClickOptions _locatorClickOptions = page.Browser.TestOptions.Delay == 0
+ ? null
+ : new() { Delay = page.Browser.TestOptions.Delay };
+ private readonly LocatorPressSequentiallyOptions _locatorPressSequentiallyOptions = page.Browser.TestOptions.Delay == 0
+ ? null
+ : new() { Delay = page.Browser.TestOptions.Delay };
+
+ IPage IElement.Page => page;
+
///
public string InnerText { get; set; }
@@ -22,12 +32,12 @@ public class Element(ILocator locator) : IElement
public bool Visible { get; set; }
///
- public async Task ClickAsync() => await locator.ClickAsync();
+ public async Task ClickAsync() => await locator.ClickAsync(_locatorClickOptions);
///
public async Task TypeAsync(string text)
{
- await locator.FillAsync(text);
+ await locator.PressSequentiallyAsync(text, _locatorPressSequentiallyOptions);
InnerText = await locator.InnerTextAsync();
InnerHtml = await locator.InnerHTMLAsync();
diff --git a/src/OrchardCoreContrib.Testing.UI/IBrowser.cs b/src/OrchardCoreContrib.Testing.UI/IBrowser.cs
index 11946e4..1b78e1f 100644
--- a/src/OrchardCoreContrib.Testing.UI/IBrowser.cs
+++ b/src/OrchardCoreContrib.Testing.UI/IBrowser.cs
@@ -10,6 +10,11 @@ public interface IBrowser
///
public Microsoft.Playwright.IBrowser InnerBrowser { get; }
+ ///
+ /// Gets the test options that will be applied;
+ ///
+ public UITestOptions TestOptions { get; set; }
+
///
/// Gets or sets the browser type.
///
diff --git a/src/OrchardCoreContrib.Testing.UI/IElement.cs b/src/OrchardCoreContrib.Testing.UI/IElement.cs
index 66e2958..4abbc9f 100644
--- a/src/OrchardCoreContrib.Testing.UI/IElement.cs
+++ b/src/OrchardCoreContrib.Testing.UI/IElement.cs
@@ -5,6 +5,8 @@
///
public interface IElement
{
+ internal IPage Page { get; }
+
///
/// Gets the inner text of the element.
///
diff --git a/src/OrchardCoreContrib.Testing.UI/IPage.cs b/src/OrchardCoreContrib.Testing.UI/IPage.cs
index 2fbc7dc..2ccaa57 100644
--- a/src/OrchardCoreContrib.Testing.UI/IPage.cs
+++ b/src/OrchardCoreContrib.Testing.UI/IPage.cs
@@ -10,6 +10,8 @@ public interface IPage
///
public Microsoft.Playwright.IPage InnerPage { get; }
+ internal IBrowser Browser { get; }
+
///
/// Gets or sets the page title.
///
diff --git a/src/OrchardCoreContrib.Testing.UI/IUITest.cs b/src/OrchardCoreContrib.Testing.UI/IUITest.cs
new file mode 100644
index 0000000..990f653
--- /dev/null
+++ b/src/OrchardCoreContrib.Testing.UI/IUITest.cs
@@ -0,0 +1,19 @@
+using Xunit;
+
+namespace OrchardCoreContrib.Testing.UI;
+
+///
+/// Represents a contract for UI test.
+///
+public interface IUITest : IAsyncLifetime
+{
+ ///
+ /// Gets or sets the browser instance to be used during the test.
+ ///
+ public IBrowser Browser { get; set; }
+
+ ///
+ /// Gets the options used during the test.
+ ///
+ public UITestOptions Options { get; }
+}
diff --git a/src/OrchardCoreContrib.Testing.UI/Page.cs b/src/OrchardCoreContrib.Testing.UI/Page.cs
index 979f5ad..52ac48e 100644
--- a/src/OrchardCoreContrib.Testing.UI/Page.cs
+++ b/src/OrchardCoreContrib.Testing.UI/Page.cs
@@ -9,11 +9,14 @@ namespace OrchardCoreContrib.Testing.UI;
/// Creates an instance of .
///
/// The .
-public class Page(IPlaywrightPageAccessor playwrightPageAccessor) : IPage
+/// The .
+public class Page(IPlaywrightPageAccessor playwrightPageAccessor, IBrowser browser) : IPage
{
///
public Microsoft.Playwright.IPage InnerPage => playwrightPageAccessor.PlaywrightPage;
+ IBrowser IPage.Browser => browser;
+
///
public string Title { get; set; }
@@ -33,7 +36,7 @@ public async Task GoToAsync(string url)
public IElement FindElement(string selector)
{
var locator = InnerPage.Locator(selector);
- var element = new Element(locator)
+ var element = new Element(locator, this)
{
InnerText = locator.InnerTextAsync().GetAwaiter().GetResult(),
InnerHtml = locator.InnerHTMLAsync().GetAwaiter().GetResult(),
diff --git a/src/OrchardCoreContrib.Testing.UI/UITest.cs b/src/OrchardCoreContrib.Testing.UI/UITest.cs
index e6cfe53..9e98153 100644
--- a/src/OrchardCoreContrib.Testing.UI/UITest.cs
+++ b/src/OrchardCoreContrib.Testing.UI/UITest.cs
@@ -1,43 +1,17 @@
-using Microsoft.Playwright;
-using Xunit;
-
-namespace OrchardCoreContrib.Testing.UI;
+namespace OrchardCoreContrib.Testing.UI;
///
/// Represents a UI testing class.
///
/// The browser type that will be used during the test. Defaults to .
/// Whether the browser runs in headless mode or not. Defaults to true.
-public class UITest(BrowserType browserType = BrowserType.Edge, bool headless = true) : IAsyncLifetime
-{
- private IPlaywright _playwright;
-
- ///
- /// Gets the browser instance to be used during the test.
- ///
- public IBrowser Browser { get; private set; }
-
- public UITestOptions Options { get; private set; }
-
- ///
- public async Task InitializeAsync()
+/// The amount of time to wait between execute two actions. Defaults to 0.
+public class UITest(BrowserType browserType = BrowserType.Edge, bool headless = true, int delay = 0)
+ : UITestBase(new UITestOptions
{
- Options = new UITestOptions
- {
- BrowserType = browserType,
- Headless = headless
- };
-
- _playwright = await Playwright.CreateAsync();
-
- Browser = await BrowserFactory.CreateAsync(_playwright, Options);
- }
-
- ///
- public async Task DisposeAsync()
- {
- _playwright.Dispose();
-
- await Task.CompletedTask;
- }
+ BrowserType = browserType,
+ Headless = headless,
+ Delay = delay
+ })
+{
}
diff --git a/src/OrchardCoreContrib.Testing.UI/UITestBase.cs b/src/OrchardCoreContrib.Testing.UI/UITestBase.cs
index 5bd552f..5271059 100644
--- a/src/OrchardCoreContrib.Testing.UI/UITestBase.cs
+++ b/src/OrchardCoreContrib.Testing.UI/UITestBase.cs
@@ -1,18 +1,34 @@
-using OrchardCoreContrib.Testing.UI.Infrastructure;
+using Microsoft.Playwright;
namespace OrchardCoreContrib.Testing.UI;
-///
-/// Represents a base class for UI testing.
-///
-/// The startup class that will be used as entry point.
-/// The .
-public abstract class UITestBase(WebApplicationFactoryFixture fixture) where TStartup : class
+public abstract class UITestBase(UITestOptions testOptions) : IUITest
{
+ private IPlaywright _playwright;
+
+ ///
+ /// Gets or sets the browser instance to be used during the test.
+ ///
+ public IBrowser Browser { get; set; }
+
///
- /// Gets the base URL used for the tested website.
+ /// Gets the options used during the test.
///
- public string BaseUrl => fixture.ServerAddress;
+ public UITestOptions Options => testOptions;
+
+ ///
+ public virtual async Task InitializeAsync()
+ {
+ _playwright = await Playwright.CreateAsync();
+
+ Browser = await BrowserFactory.CreateAsync(_playwright, Options);
+ }
+
+ ///
+ public virtual async Task DisposeAsync()
+ {
+ _playwright.Dispose();
- public UITestOptions Options { get; protected set; }
+ await Task.CompletedTask;
+ }
}
diff --git a/src/OrchardCoreContrib.Testing.UI/UITestBaseOfT.cs b/src/OrchardCoreContrib.Testing.UI/UITestBaseOfT.cs
new file mode 100644
index 0000000..b62826b
--- /dev/null
+++ b/src/OrchardCoreContrib.Testing.UI/UITestBaseOfT.cs
@@ -0,0 +1,17 @@
+using OrchardCoreContrib.Testing.UI.Infrastructure;
+
+namespace OrchardCoreContrib.Testing.UI;
+
+///
+/// Represents a base class for UI testing.
+///
+/// The startup class that will be used as entry point.
+/// The .
+public abstract class UITestBase(WebApplicationFactoryFixture fixture, UITestOptions testOptions)
+ : UITestBase(testOptions) where TStartup : class
+{
+ ///
+ /// Gets the base URL used for the tested website.
+ ///
+ public string BaseUrl => fixture.ServerAddress;
+}
diff --git a/src/OrchardCoreContrib.Testing.UI/UITestOfT.cs b/src/OrchardCoreContrib.Testing.UI/UITestOfT.cs
index 8f3efab..7bc998d 100644
--- a/src/OrchardCoreContrib.Testing.UI/UITestOfT.cs
+++ b/src/OrchardCoreContrib.Testing.UI/UITestOfT.cs
@@ -1,6 +1,4 @@
-using Microsoft.Playwright;
-using OrchardCoreContrib.Testing.UI.Infrastructure;
-using Xunit;
+using OrchardCoreContrib.Testing.UI.Infrastructure;
namespace OrchardCoreContrib.Testing.UI;
@@ -9,37 +7,14 @@ namespace OrchardCoreContrib.Testing.UI;
///
/// The browser type that will be used during the test. Defaults to .
/// Whether the browser runs in headless mode or not. Defaults to true.
+/// The amount of time to wait between execute two actions. Defaults to 0.
/// The startup class type that will be used as entry point.
-public class UITest(BrowserType browserType = BrowserType.Edge, bool headless = true) :
- UITestBase(new WebApplicationFactoryFixture()),
- IAsyncLifetime where TStartup : class
-{
- private IPlaywright _playwright;
-
- ///
- /// Gets the browser instance to be used during the test.
- ///
- public IBrowser Browser { get; private set; }
-
- ///
- public async Task InitializeAsync()
+public class UITest(BrowserType browserType = BrowserType.Edge, bool headless = true, int delay = 0) :
+ UITestBase(new WebApplicationFactoryFixture(), new UITestOptions
{
- Options = new UITestOptions
- {
- BrowserType = browserType,
- Headless = headless
- };
-
- _playwright = await Playwright.CreateAsync();
-
- Browser = await BrowserFactory.CreateAsync(_playwright, Options);
- }
-
- ///
- public async Task DisposeAsync()
- {
- _playwright.Dispose();
-
- await Task.CompletedTask;
- }
+ BrowserType = browserType,
+ Headless = headless,
+ Delay = delay
+ }), IUITest where TStartup : class
+{
}
diff --git a/src/OrchardCoreContrib.Testing.UI/UITestOptions.cs b/src/OrchardCoreContrib.Testing.UI/UITestOptions.cs
index 068244c..598e587 100644
--- a/src/OrchardCoreContrib.Testing.UI/UITestOptions.cs
+++ b/src/OrchardCoreContrib.Testing.UI/UITestOptions.cs
@@ -14,4 +14,9 @@ public class UITestOptions
/// Gets or sets the browser type to run the test on. Defaults .
///
public BrowserType BrowserType { get; set; } = BrowserType.Edge;
+
+ ///
+ /// Gets or sets amount of time to wait before executing each event on the page. Defaults 0.
+ ///
+ public int Delay { get; set; } = 0;
}
diff --git a/test/OrchardCoreContrib.Testing.UI.Tests/ElementTests.cs b/test/OrchardCoreContrib.Testing.UI.Tests/ElementTests.cs
index 79a8d48..b608829 100644
--- a/test/OrchardCoreContrib.Testing.UI.Tests/ElementTests.cs
+++ b/test/OrchardCoreContrib.Testing.UI.Tests/ElementTests.cs
@@ -2,11 +2,22 @@
public class ElementTests
{
+ private readonly Page _page;
+
+ public ElementTests()
+ {
+ var browser = new Browser(new PlaywrightBrowserAccessor(Mock.Of()))
+ {
+ TestOptions = new UITestOptions()
+ };
+ _page = new Page(new PlaywrightPageAccessor(Mock.Of()), browser);
+ }
+
[Fact]
public void GetElementInformation()
{
// Act
- var element = new Element(Mock.Of())
+ var element = new Element(Mock.Of(), _page)
{
InnerHtml = "Orchard Core Contrib
",
InnerText = "Orchard Core Contrib",
@@ -26,7 +37,7 @@ public async Task ClickElement()
{
// Arrange
var locatorMock = new Mock();
- var element = new Element(locatorMock.Object);
+ var element = new Element(locatorMock.Object, _page);
// Act
await element.ClickAsync();
@@ -40,13 +51,13 @@ public async Task TypeTextIntoElement()
{
// Arrange
var locatorMock = new Mock();
- locatorMock.Setup(l => l.FillAsync(It.IsAny(), null))
+ locatorMock.Setup(l => l.PressSequentiallyAsync(It.IsAny(), null))
.Callback(() =>
{
locatorMock.Setup(l => l.InnerTextAsync(null))
.ReturnsAsync("Orchard Core Contrib");
});
- var element = new Element(locatorMock.Object);
+ var element = new Element(locatorMock.Object, _page);
// Act
await element.TypeAsync("Orchard Core Contrib");
diff --git a/test/OrchardCoreContrib.Testing.UI.Tests/PageTests.cs b/test/OrchardCoreContrib.Testing.UI.Tests/PageTests.cs
index 0c19299..6a3702b 100644
--- a/test/OrchardCoreContrib.Testing.UI.Tests/PageTests.cs
+++ b/test/OrchardCoreContrib.Testing.UI.Tests/PageTests.cs
@@ -2,6 +2,16 @@ namespace OrchardCoreContrib.Testing.UI.Tests;
public class PageTests
{
+ private readonly Browser _browser;
+
+ public PageTests()
+ {
+ _browser = new Browser(new PlaywrightBrowserAccessor(Mock.Of()))
+ {
+ TestOptions = new UITestOptions()
+ };
+ }
+
[Fact]
public void ShouldCreatePage()
{
@@ -9,7 +19,7 @@ public void ShouldCreatePage()
var playwrightPageAccessor = new PlaywrightPageAccessor(Mock.Of());
// Act
- var page = new Page(playwrightPageAccessor);
+ var page = new Page(playwrightPageAccessor, _browser);
// Assert
Assert.NotNull(page);
@@ -31,7 +41,7 @@ public async Task GetPageInformation()
var playwrightPageAccessor = new PlaywrightPageAccessor(pageMock.Object);
// Act
- var page = new Page(playwrightPageAccessor);
+ var page = new Page(playwrightPageAccessor, _browser);
await page.GoToAsync("www.occ.com");
// Assert
@@ -50,7 +60,7 @@ public void ShouldFindElement()
var playwrightPageAccessor = new PlaywrightPageAccessor(pageMock.Object);
- var page = new Page(playwrightPageAccessor);
+ var page = new Page(playwrightPageAccessor, _browser);
// Act
var result = page.FindElement("selector");
diff --git a/test/OrchardCoreContrib.Testing.UI.Tests/PlaywrightPageHelper.cs b/test/OrchardCoreContrib.Testing.UI.Tests/PlaywrightPageHelper.cs
index 45b18f7..bf87057 100644
--- a/test/OrchardCoreContrib.Testing.UI.Tests/PlaywrightPageHelper.cs
+++ b/test/OrchardCoreContrib.Testing.UI.Tests/PlaywrightPageHelper.cs
@@ -5,12 +5,16 @@ internal class PlaywrightPageHelper
public static async Task GotoAsync(string pageName)
{
var playwright = await Playwright.CreateAsync();
- var browser = await playwright.Chromium.LaunchAsync();
+ var playwrightBrowser = await playwright.Chromium.LaunchAsync();
+ var browser = new Browser(new PlaywrightBrowserAccessor(playwrightBrowser))
+ {
+ TestOptions = new UITestOptions()
+ };
- var page = await browser.NewPageAsync();
+ var page = await playwrightBrowser.NewPageAsync();
await page.GotoAsync(PageHelper.GetFullPath(pageName));
- return new Page(new PlaywrightPageAccessor(page));
+ return new Page(new PlaywrightPageAccessor(page), browser);
}
}