-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
GOV-29: Adding the ability to do UI testing on a remote environment
- Loading branch information
Showing
11 changed files
with
227 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using Lombiq.Tests.UI.Extensions; | ||
using OpenQA.Selenium; | ||
using Shouldly; | ||
using System; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace Lombiq.Tests.UI.Samples.Tests; | ||
|
||
// We recommend always running UI tests on the latest code of your app as part of your CI workflow. So, if anything got | ||
// broken by a pull request, it should be readily visible. Such tests are self-contained and should not even need access | ||
// to the internet. | ||
|
||
// However, sometimes in addition to this, you also want to test remote apps available online, like running rudimentary | ||
// smoke tests on your production app (e.g.: Can people still log in? Are payments still working?). The UI Testing | ||
// Toolbox also supports this. Check out the example below! | ||
|
||
// Note how the test derives from RemoteUITestBase this time, not UITestBase. | ||
public class RemoteTests : RemoteUITestBase | ||
{ | ||
public RemoteTests(ITestOutputHelper testOutputHelper) | ||
: base(testOutputHelper) | ||
{ | ||
} | ||
|
||
// The test itself is largely the same as all the local ones, but you need to provide a base URI. | ||
[Fact] | ||
public Task ExampleDotComShouldWork() => | ||
ExecuteTestAsync( | ||
new Uri("https://example.com/"), | ||
context => | ||
{ | ||
// Assertions work as usual. Implicit assertions like HTML validation and accessibility checks work too, | ||
// and upon a failing assertion a failure dump is generated as you'd expect it. | ||
context.Get(By.CssSelector("h1")).Text.ShouldBe("Example Domain"); | ||
context.Exists(By.LinkText("More information...")); | ||
// Note that due to a remote app not being under our control, some things are not supported. E.g., you | ||
// can't access the Orchard Core logs, or use shortcuts (the *Directly methods). | ||
}, | ||
configuration => configuration.HtmlValidationConfiguration.RunHtmlValidationAssertionOnAllPageChanges = false); | ||
} | ||
|
||
// END OF TRAINING SECTION: Remote tests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using Lombiq.Tests.UI.Extensions; | ||
using Lombiq.Tests.UI.Models; | ||
using Lombiq.Tests.UI.Services; | ||
using System; | ||
using System.Threading.Tasks; | ||
using Xunit.Abstractions; | ||
|
||
namespace Lombiq.Tests.UI; | ||
|
||
public abstract class RemoteUITestBase : UITestBase | ||
{ | ||
protected RemoteUITestBase(ITestOutputHelper testOutputHelper) | ||
: base(testOutputHelper) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Executes the given UI test on a remote (i.e. not locally running) app. | ||
/// </summary> | ||
protected virtual Task ExecuteTestAsync( | ||
Uri baseUri, | ||
Action<UITestContext> testAsync, | ||
Action<OrchardCoreUITestExecutorConfiguration> changeConfiguration = null) => | ||
ExecuteTestAsync(baseUri, testAsync.AsCompletedTask(), changeConfiguration.AsCompletedTask()); | ||
|
||
/// <summary> | ||
/// Executes the given UI test on a remote (i.e. not locally running) app. | ||
/// </summary> | ||
protected virtual Task ExecuteTestAsync( | ||
Uri baseUri, | ||
Func<UITestContext, Task> testAsync, | ||
Action<OrchardCoreUITestExecutorConfiguration> changeConfiguration = null) => | ||
ExecuteTestAsync(baseUri, testAsync, changeConfiguration.AsCompletedTask()); | ||
|
||
/// <summary> | ||
/// Executes the given UI test on a remote (i.e. not locally running) app. | ||
/// </summary> | ||
protected virtual Task ExecuteTestAsync( | ||
Uri baseUri, | ||
Func<UITestContext, Task> testAsync, | ||
Func<OrchardCoreUITestExecutorConfiguration, Task> changeConfigurationAsync) => | ||
ExecuteTestAsync(baseUri, testAsync, default, changeConfigurationAsync); | ||
|
||
/// <summary> | ||
/// Executes the given UI test on a remote (i.e. not locally running) app. | ||
/// </summary> | ||
protected virtual async Task ExecuteTestAsync( | ||
Uri baseUri, | ||
Func<UITestContext, Task> testAsync, | ||
Browser browser, | ||
Func<OrchardCoreUITestExecutorConfiguration, Task> changeConfigurationAsync) | ||
{ | ||
async Task BaseUriVisitingTest(UITestContext context) | ||
{ | ||
await context.GoToAbsoluteUrlAsync(baseUri); | ||
await testAsync(context); | ||
} | ||
|
||
var testManifest = new UITestManifest(_testOutputHelper) { TestAsync = BaseUriVisitingTest }; | ||
|
||
var configuration = new OrchardCoreUITestExecutorConfiguration | ||
{ | ||
OrchardCoreConfiguration = new OrchardCoreConfiguration(), | ||
TestOutputHelper = _testOutputHelper, | ||
BrowserConfiguration = { Browser = browser }, | ||
}; | ||
|
||
configuration.HtmlValidationConfiguration.HtmlValidationAndAssertionOnPageChangeRule = (_) => true; | ||
configuration.AccessibilityCheckingConfiguration.AccessibilityCheckingAndAssertionOnPageChangeRule = (_) => true; | ||
configuration.FailureDumpConfiguration.CaptureAppSnapshot = false; | ||
|
||
if (changeConfigurationAsync != null) await changeConfigurationAsync(configuration); | ||
|
||
await ExecuteOrchardCoreTestAsync((_, _) => new RemoteInstance(baseUri), testManifest, configuration); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Lombiq.Tests.UI.Services; | ||
|
||
public sealed class RemoteInstance : IWebApplicationInstance | ||
{ | ||
public IServiceProvider Services => throw new NotSupportedException(); | ||
|
||
private readonly Uri _baseUri; | ||
|
||
public RemoteInstance(Uri baseUri) => _baseUri = baseUri; | ||
|
||
public Task<Uri> StartUpAsync() => Task.FromResult(_baseUri); | ||
|
||
public IEnumerable<IApplicationLog> GetLogs(CancellationToken cancellationToken = default) => Enumerable.Empty<IApplicationLog>(); | ||
public TService GetRequiredService<TService>() => throw new NotSupportedException(); | ||
public Task PauseAsync() => throw new NotSupportedException(); | ||
public Task ResumeAsync() => throw new NotSupportedException(); | ||
public Task TakeSnapshotAsync(string snapshotDirectoryPath) => throw new NotSupportedException(); | ||
|
||
public ValueTask DisposeAsync() => ValueTask.CompletedTask; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using Lombiq.Tests.UI.Models; | ||
using Lombiq.Tests.UI.Services; | ||
using Lombiq.Tests.UI.Services.GitHub; | ||
using System; | ||
using System.Threading.Tasks; | ||
using Xunit.Abstractions; | ||
|
||
namespace Lombiq.Tests.UI; | ||
|
||
public abstract class UITestBase | ||
{ | ||
protected ITestOutputHelper _testOutputHelper; | ||
|
||
static UITestBase() => AtataFactory.SetupShellCliCommandFactory(); | ||
|
||
protected UITestBase(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; | ||
|
||
protected async Task ExecuteOrchardCoreTestAsync( | ||
WebApplicationInstanceFactory webApplicationInstanceFactory, | ||
UITestManifest testManifest, | ||
OrchardCoreUITestExecutorConfiguration configuration) | ||
{ | ||
var originalTestOutputHelper = _testOutputHelper; | ||
Action afterTest = null; | ||
if (configuration.ExtendGitHubActionsOutput && | ||
configuration.GitHubActionsOutputConfiguration.EnablePerTestOutputGrouping && | ||
GitHubHelper.IsGitHubEnvironment) | ||
{ | ||
(_testOutputHelper, afterTest) = | ||
GitHubActionsGroupingTestOutputHelper.CreateDecorator(_testOutputHelper, testManifest); | ||
configuration.TestOutputHelper = _testOutputHelper; | ||
} | ||
|
||
try | ||
{ | ||
await UITestExecutor.ExecuteOrchardCoreTestAsync(webApplicationInstanceFactory, testManifest, configuration); | ||
} | ||
finally | ||
{ | ||
_testOutputHelper = originalTestOutputHelper; | ||
// This warning is a false positive as it is not considering the evaluation of the if statement above. | ||
#pragma warning disable S2583 // Conditionally executed code should be reachable | ||
afterTest?.Invoke(); | ||
#pragma warning restore S2583 // Conditionally executed code should be reachable | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters