Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UITestOptions #9

Merged
merged 1 commit into from
May 1, 2024
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
21 changes: 12 additions & 9 deletions src/OrchardCoreContrib.Testing.UI/Browser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,30 @@ namespace OrchardCoreContrib.Testing.UI;
/// <param name="playwrightBrowserAccessor">The <see cref="IPlaywrightBrowserAccessor"/>.</param>
/// <param name="type">The <see cref="BrowserType"/>.</param>
/// <param name="headless">Whether to run browser in headless mode.</param>
public class Browser(IPlaywrightBrowserAccessor playwrightBrowserAccessor, BrowserType type, bool headless) : IBrowser
public class Browser(IPlaywrightBrowserAccessor playwrightBrowserAccessor) : IBrowser
{
/// <inheritdoc/>
public PlaywrightBrowser InnerBrowser => playwrightBrowserAccessor.PlaywrightBrowser;

/// <inheritdoc/>
public bool Headless => headless;
public BrowserType Type { get; set; }

/// <inheritdoc/>
public BrowserType Type => type;

/// <inheritdoc/>
public string Version => InnerBrowser.Version;
public string Version { get; set; } = playwrightBrowserAccessor.PlaywrightBrowser.Version;

/// <inheritdoc/>
public async Task<IPage> OpenPageAsync(string url)
{
var page = await InnerBrowser.NewPageAsync();
var playwrightPage = await InnerBrowser.NewPageAsync();

await playwrightPage.GotoAsync(url);

await page.GotoAsync(url);
var page = new Page(new PlaywrightPageAccessor(playwrightPage))
{
Title = await playwrightPage.TitleAsync(),
Content = await playwrightPage.ContentAsync()
};

return new Page(new PlaywrightPageAccessor(page));
return page;
}
}
25 changes: 17 additions & 8 deletions src/OrchardCoreContrib.Testing.UI/BrowserFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,29 @@ public static class BrowserFactory
/// Creates a new instance of <see cref="IBrowser"/> with a given browser type.
/// </summary>
/// <param name="playwright">The <see cref="IPlaywright"/>.</param>
/// <param name="browserType">The browser type in which <see cref="IBrowser"/> will be created.</param>
/// <param name="headless">Whether the browser runs in headless mode or not.</param>
/// <param name="testOptions">The <see cref="UITestOptions"/>.</param>
/// <returns>An instance of <see cref="IBrowser"/>.</returns>
/// <exception cref="NotSupportedException"></exception>
public static async Task<IBrowser> CreateAsync(IPlaywright playwright, BrowserType browserType, bool headless)
public static async Task<IBrowser> CreateAsync(IPlaywright playwright, UITestOptions testOptions)
{
var browser = browserType switch
var browser = testOptions.BrowserType switch
{
BrowserType.Edge => _edgeBrowser ?? await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Channel = "msedge", Headless = headless }),
BrowserType.Chrome => _chromeBrowser ?? await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = headless }),
BrowserType.Firefox => _fireFoxBrowser ?? await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions { Headless = headless }),
BrowserType.Edge => _edgeBrowser ?? await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Channel = "msedge",
Headless = testOptions.Headless
}),
BrowserType.Chrome => _chromeBrowser ?? await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = testOptions.Headless
}),
BrowserType.Firefox => _fireFoxBrowser ?? await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = testOptions.Headless
}),
_ => throw new NotSupportedException()
};

return new Browser(new PlaywrightBrowserAccessor(browser), browserType, headless);
return new Browser(new PlaywrightBrowserAccessor(browser)) { Type = testOptions.BrowserType };
}
}
16 changes: 11 additions & 5 deletions src/OrchardCoreContrib.Testing.UI/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,26 @@ namespace OrchardCoreContrib.Testing.UI;
public class Element(ILocator locator) : IElement
{
/// <inheritdoc/>
public string InnerText => locator.InnerTextAsync().GetAwaiter().GetResult();
public string InnerText { get; set; }

/// <inheritdoc/>
public string InnerHtml => locator.InnerHTMLAsync().GetAwaiter().GetResult();
public string InnerHtml { get; set; }

/// <inheritdoc/>
public bool Enabled => locator.IsEnabledAsync().GetAwaiter().GetResult();
public bool Enabled { get; set; }

/// <inheritdoc/>
public bool Visible => locator.IsVisibleAsync().GetAwaiter().GetResult();
public bool Visible { get; set; }

/// <inheritdoc/>
public async Task ClickAsync() => await locator.ClickAsync();

/// <inheritdoc/>
public async Task TypeAsync(string text) => await locator.FillAsync(text);
public async Task TypeAsync(string text)
{
await locator.FillAsync(text);

InnerText = await locator.InnerTextAsync();
InnerHtml = await locator.InnerHTMLAsync();
}
}
13 changes: 4 additions & 9 deletions src/OrchardCoreContrib.Testing.UI/IBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,14 @@ public interface IBrowser
public Microsoft.Playwright.IBrowser InnerBrowser { get; }

/// <summary>
/// Gets whether the browser runs on headless mode or not.
/// Gets or sets the browser type.
/// </summary>
public bool Headless { get; }
public BrowserType Type { get; set; }

/// <summary>
/// Gets the browser type.
/// Gets or sets the browser version.
/// </summary>
public BrowserType Type { get; }

/// <summary>
/// Gets the browser version.
/// </summary>
public string Version { get; }
public string Version { get; set; }

/// <summary>
/// Opens a page with a given URL
Expand Down
6 changes: 3 additions & 3 deletions src/OrchardCoreContrib.Testing.UI/IElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public interface IElement
/// <summary>
/// Gets the inner text of the element.
/// </summary>
public string InnerText { get; }
public string InnerText { get; set; }

/// <summary>
/// Gets the inner HTML of the element.
Expand All @@ -18,12 +18,12 @@ public interface IElement
/// <summary>
/// Gets whether the element is enabled.
/// </summary>
public bool Enabled { get; }
public bool Enabled { get; set; }

/// <summary>
/// Gets whether the element is visible.
/// </summary>
public bool Visible { get; }
public bool Visible { get; set; }

/// <summary>
/// Writes a given text into an element.
Expand Down
8 changes: 4 additions & 4 deletions src/OrchardCoreContrib.Testing.UI/IPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public interface IPage
public Microsoft.Playwright.IPage InnerPage { get; }

/// <summary>
/// Gets the page title.
/// Gets or sets the page title.
/// </summary>
public string Title { get; }
public string Title { get; set; }

/// <summary>
/// Gets the page content in HTML format.
/// Gets or sets the page content in HTML format.
/// </summary>
public string Content { get; }
public string Content { get; set; }

/// <summary>
/// Navigates to a given URL.
Expand Down
23 changes: 18 additions & 5 deletions src/OrchardCoreContrib.Testing.UI/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,33 @@ public class Page(IPlaywrightPageAccessor playwrightPageAccessor) : IPage
public Microsoft.Playwright.IPage InnerPage => playwrightPageAccessor.PlaywrightPage;

/// <inheritdoc/>
public string Title => InnerPage.TitleAsync().GetAwaiter().GetResult();
public string Title { get; set; }

/// <inheritdoc/>
public string Content => InnerPage.ContentAsync().GetAwaiter().GetResult();
public string Content { get; set; }

/// <inheritdoc/>
public async Task GoToAsync(string url) => await InnerPage.GotoAsync(url);
public async Task GoToAsync(string url)
{
await InnerPage.GotoAsync(url);

Title = await InnerPage.TitleAsync();
Content = await InnerPage.ContentAsync();
}

/// <inheritdoc/>
public IElement FindElement(string selector)
{
var locator = InnerPage.Locator(selector);

return new Element(locator);
var element = new Element(locator)
{
InnerText = locator.InnerTextAsync().GetAwaiter().GetResult(),
InnerHtml = locator.InnerHTMLAsync().GetAwaiter().GetResult(),
Enabled = locator.IsEnabledAsync().GetAwaiter().GetResult(),
Visible = locator.IsVisibleAsync().GetAwaiter().GetResult()
};

return element;
}

/// <inheritdoc/>
Expand Down
11 changes: 9 additions & 2 deletions src/OrchardCoreContrib.Testing.UI/UITest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Playwright;
using OrchardCoreContrib.Testing.UI.Infrastructure;
using Xunit;

namespace OrchardCoreContrib.Testing.UI;
Expand All @@ -18,12 +17,20 @@ public class UITest(BrowserType browserType = BrowserType.Edge, bool headless =
/// </summary>
public IBrowser Browser { get; private set; }

public UITestOptions Options { get; private set; }

/// <inheritdoc/>
public async Task InitializeAsync()
{
Options = new UITestOptions
{
BrowserType = browserType,
Headless = headless
};

_playwright = await Playwright.CreateAsync();

Browser = await BrowserFactory.CreateAsync(_playwright, browserType, headless);
Browser = await BrowserFactory.CreateAsync(_playwright, Options);
}

/// <inheritdoc/>
Expand Down
2 changes: 2 additions & 0 deletions src/OrchardCoreContrib.Testing.UI/UITestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public abstract class UITestBase<TStartup>(WebApplicationFactoryFixture<TStartup
/// Gets the base URL used for the tested website.
/// </summary>
public string BaseUrl => fixture.ServerAddress;

public UITestOptions Options { get; protected set; }
}
8 changes: 7 additions & 1 deletion src/OrchardCoreContrib.Testing.UI/UITestOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ public class UITest<TStartup>(BrowserType browserType = BrowserType.Edge, bool h
/// <inheritdoc/>
public async Task InitializeAsync()
{
Options = new UITestOptions
{
BrowserType = browserType,
Headless = headless
};

_playwright = await Playwright.CreateAsync();

Browser = await BrowserFactory.CreateAsync(_playwright, browserType, headless);
Browser = await BrowserFactory.CreateAsync(_playwright, Options);
}

/// <inheritdoc/>
Expand Down
17 changes: 17 additions & 0 deletions src/OrchardCoreContrib.Testing.UI/UITestOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace OrchardCoreContrib.Testing.UI;

/// <summary>
/// Represents a set of options to be used during the test.
/// </summary>
public class UITestOptions
{
/// <summary>
/// Gets or sets whether to run the browser on headless mode. Defaults <c>true</c>.
/// </summary>
public bool Headless { get; set; } = true;

/// <summary>
/// Gets or sets the browser type to run the test on. Defaults <see cref="BrowserType.Edge"/>.
/// </summary>
public BrowserType BrowserType { get; set; } = BrowserType.Edge;
}
26 changes: 16 additions & 10 deletions test/OrchardCoreContrib.Testing.UI.Tests/BrowserFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,44 @@ namespace OrchardCoreContrib.Testing.UI.Tests;

public class BrowserFactoryTests
{
[InlineData(BrowserType.Chrome, PlaywrightBrowserType.Chromium, false)]
[InlineData(BrowserType.Edge, PlaywrightBrowserType.Chromium, false)]
[InlineData(BrowserType.Firefox, PlaywrightBrowserType.Firefox, false)]
[InlineData(BrowserType.Chrome, PlaywrightBrowserType.Chromium, true)]
[InlineData(BrowserType.Edge, PlaywrightBrowserType.Chromium, true)]
[InlineData(BrowserType.Firefox, PlaywrightBrowserType.Firefox, true)]
[InlineData(BrowserType.Chrome, PlaywrightBrowserType.Chromium)]
[InlineData(BrowserType.Edge, PlaywrightBrowserType.Chromium)]
[InlineData(BrowserType.Firefox, PlaywrightBrowserType.Firefox)]
[Theory]
public async Task CreateBrowser(BrowserType browserType, string playwrightBrowserType, bool headless)
public async Task CreateBrowser(BrowserType browserType, string playwrightBrowserType)
{
// Arrange
var playwright = await Playwright.CreateAsync();

var testOptions = new UITestOptions
{
BrowserType = browserType
};

// Act
var browser = await BrowserFactory.CreateAsync(playwright, browserType, headless);
var browser = await BrowserFactory.CreateAsync(playwright, testOptions);
browser.Type = browserType;

// Assert
Assert.NotNull(browser);
Assert.Equal(browserType, browser.Type);
Assert.Equal(playwrightBrowserType, browser.InnerBrowser.BrowserType.Name);
Assert.Equal(headless, browser.Headless);
}

[Fact]
public async Task CreateBrowser_ThrowsException_WhenBrowserTypeInvalid()
{
// Arrange
var playwright = await Playwright.CreateAsync();
var testOptions = new UITestOptions
{
BrowserType = BrowserType.NotSet
};

// Act & Assert
await Assert.ThrowsAsync<NotSupportedException>(async () =>
{
await BrowserFactory.CreateAsync(playwright, BrowserType.NotSet, headless: true);
await BrowserFactory.CreateAsync(playwright, testOptions);
});
}
}
5 changes: 2 additions & 3 deletions test/OrchardCoreContrib.Testing.UI.Tests/BrowserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ public void ShouldCreateBrowser()
var playwrightBrowserAccessor = new PlaywrightBrowserAccessor(_browserMock.Object);

// Act
var browser = new Browser(playwrightBrowserAccessor, BrowserType.Edge, headless: true);
var browser = new Browser(playwrightBrowserAccessor) { Type = BrowserType.Edge };

// Assert
Assert.NotNull(browser);
Assert.Equal(BrowserType.Edge, browser.Type);
Assert.Equal(version, browser.Version);
Assert.True(browser.Headless);
Assert.Same(playwrightBrowserAccessor.PlaywrightBrowser, browser.InnerBrowser);
}

Expand All @@ -37,7 +36,7 @@ public async Task ShouldOpenPage()
{
// Arrange
var playwrightBrowserAccessor = new PlaywrightBrowserAccessor(_browserMock.Object);
var browser = new Browser(playwrightBrowserAccessor, BrowserType.Edge, headless: true);
var browser = new Browser(playwrightBrowserAccessor) { Type = BrowserType.Edge };

// Act
var page = await browser.OpenPageAsync("https://www.orchardcore.net");
Expand Down
22 changes: 7 additions & 15 deletions test/OrchardCoreContrib.Testing.UI.Tests/ElementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,14 @@ public class ElementTests
[Fact]
public void GetElementInformation()
{
// Arrange
var locatorMock = new Mock<ILocator>();
locatorMock.Setup(l => l.InnerHTMLAsync(null))
.ReturnsAsync("<h1>Orchard Core Contrib</h1>");

locatorMock.Setup(l => l.InnerTextAsync(null))
.ReturnsAsync("Orchard Core Contrib");

locatorMock.Setup(l => l.IsDisabledAsync(null))
.ReturnsAsync(false);

locatorMock.Setup(l => l.IsVisibleAsync(null))
.ReturnsAsync(true);

// Act
var element = new Element(locatorMock.Object);
var element = new Element(Mock.Of<ILocator>())
{
InnerHtml = "<h1>Orchard Core Contrib</h1>",
InnerText = "Orchard Core Contrib",
Enabled = false,
Visible = true
};

// Assert
Assert.Equal("<h1>Orchard Core Contrib</h1>", element.InnerHtml);
Expand Down
Loading