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

OSOE-733: Ability to configure default browser #326

Merged
merged 3 commits into from
Nov 26, 2023
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
1 change: 1 addition & 0 deletions Lombiq.Tests.UI.Samples/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ For general details about and on using the Toolbox see the [root Readme](../Read
- [Error handling](Tests/ErrorHandlingTests.cs)
- [Monkey tests](Tests/MonkeyTests.cs)
- [Database snapshot tests](Tests/DatabaseSnapshotTests.cs)
- [Multi-browser tests](Tests/MultiBrowserTests.cs)
- [Basic visual verification tests](Tests/BasicVisualVerificationTests.cs)
- [Testing in tenants](Tests/TenantTests.cs)
- [Interactive mode](Tests/InteractiveModeTests.cs)
Expand Down
6 changes: 2 additions & 4 deletions Lombiq.Tests.UI.Samples/Tests/AccessibilityTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Services;
using System.Threading.Tasks;
Expand All @@ -17,14 +16,13 @@ public AccessibilityTest(ITestOutputHelper testOutputHelper)
{
}

[Theory, Chrome]
public Task FrontendPagesShouldBeAccessible(Browser browser) =>
[Fact]
public Task FrontendPagesShouldBeAccessible() =>
ExecuteTestAfterSetupAsync(
context =>
// This is just a simple test that visits two pages: The homepage, where the test will start by default,
// and another one.
context.GoToRelativeUrlAsync("/categories/travel"),
browser,
configuration =>
{
// We adjust the configuration just for this test but you could do the same globally in UITestBase.
Expand Down
11 changes: 4 additions & 7 deletions Lombiq.Tests.UI.Samples/Tests/AzureBlobStorageTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Samples.Extensions;
using Lombiq.Tests.UI.Services;
Expand All @@ -21,22 +20,20 @@ public AzureBlobStorageTests(ITestOutputHelper testOutputHelper)
// Here we have basically two of the same tests as in BasicTests but now we're using Azure Blob Storage as the
// site's Media storage. If they still work and there are no errors in the log then the app works with Azure Blob
// Storage too.
[Theory, Chrome]
public Task AnonymousHomePageShouldExistWithAzureBlobStorage(Browser browser) =>
[Fact]
public Task AnonymousHomePageShouldExistWithAzureBlobStorage() =>
ExecuteTestAfterSetupAsync(
context => context.CheckIfAnonymousHomePageExistsAsync(),
browser,
// Note the configuration! We could also set this globally in UITestBase. You'll need an accessible Azure
// Blob Storage account. For testing we recommend the Azurite emulator
// (https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azurite) that can be used from tests
// without any further configuration.
configuration => configuration.UseAzureBlobStorage = true);

[Theory, Chrome]
public Task TogglingFeaturesShouldWorkWithAzureBlobStorage(Browser browser) =>
[Fact]
public Task TogglingFeaturesShouldWorkWithAzureBlobStorage() =>
ExecuteTestAfterSetupAsync(
context => context.ExecuteAndAssertTestFeatureToggleAsync(),
browser,
configuration =>
{
configuration.UseAzureBlobStorage = true;
Expand Down
10 changes: 3 additions & 7 deletions Lombiq.Tests.UI.Samples/Tests/BasicOrchardFeaturesTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Samples.Constants;
using Lombiq.Tests.UI.Services;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
Expand All @@ -21,11 +19,9 @@ public BasicOrchardFeaturesTests(ITestOutputHelper testOutputHelper)

// We could reuse the previously specified SetupHelpers.RecipeId const here but it's actually a different recipe for
// this test.
[Theory, Chrome]
public Task BasicOrchardFeaturesShouldWork(Browser browser) =>
ExecuteTestAsync(
context => context.TestBasicOrchardFeaturesAsync(RecipeIds.BasicOrchardFeaturesTests),
browser);
[Fact]
public Task BasicOrchardFeaturesShouldWork() =>
ExecuteTestAsync(context => context.TestBasicOrchardFeaturesAsync(RecipeIds.BasicOrchardFeaturesTests));
}

// END OF TRAINING SECTION: Basic Orchard features tests.
Expand Down
34 changes: 14 additions & 20 deletions Lombiq.Tests.UI.Samples/Tests/BasicTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Constants;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Services;
Expand All @@ -19,12 +18,11 @@ public BasicTests(ITestOutputHelper testOutputHelper)
{
}

// Checking that everything is OK with the homepage as an anonymous user. Note the attributes: [Theory] is necessary
// for xUnit, while [Chrome] is an input parameter of the test. The latter is an important concept: You can create
// so-called data-driven tests. See here for more info:
// https://andrewlock.net/creating-parameterised-tests-in-xunit-with-inlinedata-classdata-and-memberdata/.
[Theory, Chrome]
public Task AnonymousHomePageShouldExist(Browser browser) =>
// Checking that everything is OK with the homepage as an anonymous user. Note the [Fact] attribute: it's necessary
// for xUnit.
// Note that by default, tests are run via Chrome. Check out MultiBrowserTests for samples on using other browsers.
[Fact]
public Task AnonymousHomePageShouldExist() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -36,13 +34,12 @@ public Task AnonymousHomePageShouldExist(Browser browser) =>

// Are we logged out?
(await context.GetCurrentUserNameAsync()).ShouldBeNullOrEmpty();
},
browser);
});

// Let's click around now. The login page is quite important, so let's make sure it works. While it's an Orchard
// feature, and thus not necessarily something we want to test, our custom code can break it in various ways.
[Theory, Chrome]
public Task LoginShouldWork(Browser browser) =>
[Fact]
public Task LoginShouldWork() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -67,16 +64,14 @@ public Task LoginShouldWork(Browser browser) =>
// itself), you don't need to log in via the login form every time: That would be slow and you'd test
// the login process multiple times. Use context.SignInDirectly() instead. Check out the
// ShortcutsShouldWork test below.
},
browser);
});

// Let's see if turning features on and off breaks something. Keep in mind that the Orchard logs are checked
// automatically so if there's an exception or anything, the test will fail.
[Theory, Chrome]
public Task TogglingFeaturesShouldWork(Browser browser) =>
[Fact]
public Task TogglingFeaturesShouldWork() =>
ExecuteTestAfterSetupAsync(
context => context.ExecuteAndAssertTestFeatureToggleAsync(),
browser,
// You can change the configuration even for each test.
configuration =>
// By default, apart from some commonly known exceptions, the browser log should be empty. However,
Expand All @@ -90,8 +85,8 @@ public Task TogglingFeaturesShouldWork(Browser browser) =>
});

// Let's see a couple more useful shortcuts in action.
[Theory, Chrome]
public Task ShortcutsShouldWork(Browser browser) =>
[Fact]
public Task ShortcutsShouldWork() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -113,8 +108,7 @@ public Task ShortcutsShouldWork(Browser browser) =>

// If you want a feature to be enabled or disabled just for one test, you can use shortcuts too:
await context.EnableFeatureDirectlyAsync("OrchardCore.HealthChecks");
},
browser);
});
}

// END OF TRAINING SECTION: UI Testing Toolbox basics.
Expand Down
7 changes: 3 additions & 4 deletions Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public BasicVisualVerificationTests(ITestOutputHelper testOutputHelper)
// the Chrome version 67 and 68 in the image rendering. This caused that the rendered image looked similar, but
// comparing pixel-by-pixel was different. You can investigate this or similar failure using the captured and
// generated diff images under the path FailureDumps/<test-name>/Attempt <n>/DebugInformation/VisualVerification.
[Theory, Chrome]
public Task VerifyBlogImage(Browser browser) =>
[Fact]
public Task VerifyBlogImage() =>
ExecuteTestAfterSetupAsync(
context =>
{
Expand All @@ -46,8 +46,7 @@ public Task VerifyBlogImage(Browser browser) =>
// Here we check that the rendered content visually equals the baseline image within a given error
// percentage. You can read more about this in the AssertVisualVerificationApproved method documentation.
context.AssertVisualVerificationApproved(blogImageElementSelector, 0);
},
browser);
});

// Checking that everything is OK with the branding of the navbar on the homepage. If you want to visually validate
// text content on different platforms (like Windows or Linux) or browsers, it can cause surprises too. The reason
Expand Down
12 changes: 4 additions & 8 deletions Lombiq.Tests.UI.Samples/Tests/DatabaseSnapshotTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Samples.Constants;
using Lombiq.Tests.UI.Services;
using System.IO;
using System.Threading.Tasks;
using Xunit;
Expand All @@ -23,8 +21,8 @@ public DatabaseSnapshotTests(ITestOutputHelper testOutputHelper)
// Here, we set up the application, then we take a snapshot of it, then we use the
// "ExecuteTestFromExistingDBAsync()" to run the test on that. Finally, we test the basic Orchard features to check
// that the application was set up correctly.
[Theory, Chrome]
public Task BasicOrchardFeaturesShouldWorkWithExistingDatabase(Browser browser) =>
[Fact]
public Task BasicOrchardFeaturesShouldWorkWithExistingDatabase() =>
ExecuteTestAsync(
async context =>
{
Expand All @@ -35,11 +33,9 @@ public Task BasicOrchardFeaturesShouldWorkWithExistingDatabase(Browser browser)

await ExecuteTestFromExistingDBAsync(
async context => await context.TestBasicOrchardFeaturesExceptSetupAsync(),
browser,
appForDatabaseTestFolder);
},
browser);
});
}

// END OF TRAINING SECTION: Database snapshot tests.
// NEXT STATION: Head over to Tests/BasicVisualVerificationTests.cs.
// NEXT STATION: Head over to Tests/MultiBrowserTests.cs.
7 changes: 2 additions & 5 deletions Lombiq.Tests.UI.Samples/Tests/EmailTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Atata;
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Helpers;
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using System.Threading.Tasks;
using Xunit;
Expand All @@ -19,8 +17,8 @@ public EmailTests(ITestOutputHelper testOutputHelper)
{
}

[Theory, Chrome]
public Task SendingTestEmailShouldWork(Browser browser) =>
[Fact]
public Task SendingTestEmailShouldWork() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand Down Expand Up @@ -61,7 +59,6 @@ await ReliabilityHelper.DoWithRetriesOrFailAsync(
// If the e-mail we've sent exists then it's all good.
context.Exists(ByHelper.SmtpInboxRow("Test message"));
},
browser,
// UseSmtpService = true automatically enables the Email module too so you don't have to enable it in a
// recipe.
configuration => configuration.UseSmtpService = true);
Expand Down
28 changes: 11 additions & 17 deletions Lombiq.Tests.UI.Samples/Tests/ErrorHandlingTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Exceptions;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Pages;
using Lombiq.Tests.UI.Samples.Helpers;
using Lombiq.Tests.UI.Services;
using Shouldly;
using System;
using System.Linq;
Expand All @@ -24,8 +22,8 @@ public ErrorHandlingTests(ITestOutputHelper testOutputHelper)
// It's easier to diagnose a test failure if you know whether an element is missing because there something is
// actually missing or there was a server-side error. The below test visits a page where the action method throws an
// exception.
[Theory, Chrome]
public Task ServerSideErrorOnLoadedPageShouldHaltTest(Browser browser) =>
[Fact]
public Task ServerSideErrorOnLoadedPageShouldHaltTest() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -42,13 +40,12 @@ public Task ServerSideErrorOnLoadedPageShouldHaltTest(Browser browser) =>
// Remove all logs to have a clean slate.
context.ClearLogs();
}
},
browser);
});

// You can interact with the browser log and its history as well. E.g. 404s and JS exceptions show up in the browser
// log.
[Theory, Chrome]
public Task ClientSideErrorOnLoadedPageShouldHaltTest(Browser browser) =>
[Fact]
public Task ClientSideErrorOnLoadedPageShouldHaltTest() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -65,13 +62,12 @@ public Task ClientSideErrorOnLoadedPageShouldHaltTest(Browser browser) =>
// Remove browser logs to have a clean slate.
context.ClearHistoricBrowserLog();
}
},
browser);
});

// To be able to trust the test above, we have to be sure that the browser logs survive the navigation events and
// all get collected into the historic browser log.
[Theory, Chrome]
public Task BrowserLogsShouldPersist(Browser browser) =>
[Fact]
public Task BrowserLogsShouldPersist() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand Down Expand Up @@ -99,15 +95,13 @@ public Task BrowserLogsShouldPersist(Browser browser) =>
.HistoricBrowserLog
.Count(entry => entry.Message.Contains(testLog))
.ShouldBe(6);
},
browser);
});

[Theory, Chrome]
public Task ErrorDuringSetupShouldHaltTest(Browser browser) =>
[Fact]
public Task ErrorDuringSetupShouldHaltTest() =>
Should.ThrowAsync<PageChangeAssertionException>(() =>
ExecuteTestAfterSetupAsync(
_ => throw new InvalidOperationException("This point shouldn't be reachable because setup fails."),
browser,
configuration =>
{
// The test is guaranteed to fail so we don't want to retry it needlessly.
Expand Down
16 changes: 6 additions & 10 deletions Lombiq.Tests.UI.Samples/Tests/InteractiveModeTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using Shouldly;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -24,9 +22,9 @@ public InteractiveModeTests(ITestOutputHelper testOutputHelper)
}

// If you want to try it out yourself, just remove the "Skip" parameter and run this test.
[Theory(Skip = "Use this to test to try out the interactive mode. This is not a real test you can run in CI."), Chrome]
[Fact(Skip = "Use this to test to try out the interactive mode. This is not a real test you can run in CI.")]
[SuppressMessage("Usage", "xUnit1004:Test methods should not be skipped", Justification = "Only a demo.")]
public Task SampleTest(Browser browser) =>
public Task SampleTest() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -43,14 +41,13 @@ public Task SampleTest(Browser browser) =>
// won't affect the test. If that's not practical, you can also do your thing in a new tab and close it
// before continuing the test.
(await context.GetCurrentUserNameAsync()).ShouldNotBeNullOrWhiteSpace();
},
browser);
});

// This test checks if interactive mode works by opening it in one thread, and then clicking it away in a different
// thread. This ensures that the new tab correctly appears with the clickable "Continue Test" button, and then
// disappears once it's clicked.
[Theory, Chrome]
public Task EnteringInteractiveModeShouldWait(Browser browser) =>
[Fact]
public Task EnteringInteractiveModeShouldWait() =>
ExecuteTestAfterSetupAsync(
async context =>
{
Expand All @@ -69,8 +66,7 @@ await Task.WhenAll(

// Ensure that the info tab is closed and the control handed back to the last tab.
context.Driver.Url.ShouldBe(currentUrl);
},
browser);
});
}

// END OF TRAINING SECTION: Interactive mode.
Loading