Skip to content

Commit

Permalink
Merge pull request #326 from Lombiq/issue/OSOE-733
Browse files Browse the repository at this point in the history
OSOE-733: Ability to configure default browser
  • Loading branch information
sarahelsaig authored Nov 26, 2023
2 parents 4ddea2d + dca959e commit 88ec8ca
Show file tree
Hide file tree
Showing 19 changed files with 210 additions and 115 deletions.
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

0 comments on commit 88ec8ca

Please sign in to comment.