Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into issue/LMBQ-299
Browse files Browse the repository at this point in the history
  • Loading branch information
DemeSzabolcs committed Feb 17, 2024
2 parents 811f97e + 5b283da commit 2b374bb
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 7 deletions.
11 changes: 10 additions & 1 deletion Lombiq.Tests.UI.Samples/Tests/MonkeyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,17 @@ public Task TestCurrentPageAsMonkeyRecursivelyShouldWorkWithAnonymousUser() =>
public Task TestAdminPagesAsMonkeyRecursivelyShouldWorkWithAdminUser() =>
ExecuteTestAfterSetupAsync(
context =>
{
// Monkey tests needn't all start from the homepage. This one starts from the Orchard admin dashboard.
context.TestAdminAsMonkeyRecursivelyAsync(CreateMonkeyTestingOptions()),
var monkeyTestingOptions = CreateMonkeyTestingOptions();
// So we don't take too much time testing the whole Orchard admin, this sample restricts requests to
// "/Admin". But this is just this sample, you can unleash monkeys on the whole admin too!
monkeyTestingOptions.UrlFilters.Add(new MatchesRegexMonkeyTestingUrlFilter("/Admin$"));
return context.TestAdminAsMonkeyRecursivelyAsync(monkeyTestingOptions);
},
configuration =>
configuration.AssertBrowserLog = logEntries => logEntries.ShouldNotContain(
logEntry => IsValidAdminBrowserLogEntry(logEntry),
Expand Down
12 changes: 12 additions & 0 deletions Lombiq.Tests.UI/Extensions/ExtendedLoggingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ private static void ExecuteSection(this UITestContext context, LogSection sectio
}
catch (StaleElementReferenceException) when (notLast)
{
LogStaleElementReferenceExceptionRetry(context, i);
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Expand All @@ -122,6 +123,7 @@ private static TResult ExecuteSection<TResult>(this UITestContext context, LogSe
}
catch (StaleElementReferenceException) when (notLast)
{
LogStaleElementReferenceExceptionRetry(context, i);
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Expand Down Expand Up @@ -150,16 +152,26 @@ private static async Task<TResult> ExecuteSectionAsync<TResult>(
// multiple sections are started in concurrent threads, the result will be incorrect. This shouldn't be too much
// of an issue for now though since tests, while async, are single-threaded.
context.Scope.AtataContext.Log.Start(section);
context.Scope.AtataContext.Log.Info("Log section {0} started.", section.Message);
var result = await functionAsync();
context.Scope.AtataContext.Log.Info("Log section {0} ended.", section.Message);
context.Scope.AtataContext.Log.EndSection();
return result;
}
catch (StaleElementReferenceException) when (notLast)
{
LogStaleElementReferenceExceptionRetry(context, i);
await Task.Delay(TimeSpan.FromSeconds(1));
}
}

throw new InvalidOperationException("Impossible to reach.");
}

private static void LogStaleElementReferenceExceptionRetry(UITestContext context, int tryIndex) =>
context.Scope.AtataContext.Log.Info(
"The operation in the log section failed with StaleElementReferenceException but will be retried. This " +
"is try number {0} out of {1}.",
tryIndex + 1,
StabilityRetryCount);
}
20 changes: 20 additions & 0 deletions Lombiq.Tests.UI/Extensions/NavigationUITestContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ private static async Task SetFieldDropdownByTextAsync(UITestContext context, By
public static Task ClickReliablyOnAsync(this UITestContext context, By by, int maxTries = 3) =>
context.Get(by).ClickReliablyAsync(context, maxTries);

/// <summary>
/// Reliably clicks on the link identified by the given text with <see
/// cref="NavigationWebElementExtensions.ClickReliablyAsync(IWebElement, UITestContext, int)"/>.
/// </summary>
/// <param name="maxTries">The maximum number of clicks attempted altogether, if retries are needed.</param>
public static Task ClickReliablyOnByLinkTextAsync(this UITestContext context, string linkText, int maxTries = 3) =>
context.Get(By.LinkText(linkText)).ClickReliablyAsync(context, maxTries);

/// <summary>
/// A convenience method that merges <see cref="ElementRetrievalUITestContextExtensions.Get"/> and <see
/// cref="NavigationWebElementExtensions.ClickReliablyUntilPageLeaveAsync(IWebElement, UITestContext, TimeSpan?,
Expand All @@ -316,6 +324,18 @@ public static Task ClickReliablyOnUntilPageLeaveAsync(
TimeSpan? interval = null) =>
context.Get(by).ClickReliablyUntilPageLeaveAsync(context, timeout, interval);

/// <summary>
/// A convenience method that merges <see cref="ElementRetrievalUITestContextExtensions.Get"/> and <see
/// cref="NavigationWebElementExtensions.ClickReliablyUntilUrlChangeAsync(IWebElement, UITestContext, TimeSpan?,
/// TimeSpan?)"/> so the <paramref name="context"/> doesn't have to be passed twice.
/// </summary>
public static Task ClickReliablyOnUntilUrlChangeAsync(
this UITestContext context,
By by,
TimeSpan? timeout = null,
TimeSpan? interval = null) =>
context.Get(by).ClickReliablyUntilUrlChangeAsync(context, timeout, interval);

/// <summary>
/// Switches control to JS alert box, accepts it, and switches control back to main document or first frame.
/// </summary>
Expand Down
32 changes: 30 additions & 2 deletions Lombiq.Tests.UI/Extensions/NavigationWebElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ await context.Configuration.Events.AfterClick
});

/// <summary>
/// Repeatedly clicks an element until the browser leaves the page. If you're doing a Get() before then use <see
/// cref="NavigationUITestContextExtensions.ClickReliablyOnAsync(UITestContext, By, int)"/> instead.
/// Repeatedly clicks an element until the browser leaves the page. Note that unlike <see
/// cref="ClickReliablyUntilUrlChangeAsync"/> this doesn't just necessitate a URL change but also a page leave. If
/// you're doing a Get() before then use <see
/// cref="NavigationUITestContextExtensions.ClickReliablyOnUntilPageLeaveAsync(UITestContext, By, TimeSpan?,
/// TimeSpan?)"/> instead.
/// </summary>
public static Task ClickReliablyUntilPageLeaveAsync(
this IWebElement element,
Expand All @@ -82,4 +85,29 @@ public static Task ClickReliablyUntilPageLeaveAsync(
},
timeout,
interval);

/// <summary>
/// Repeatedly clicks an element until the browser URL changes. Note that unlike <see
/// cref="ClickReliablyUntilPageLeaveAsync"/> this doesn't necessitate a page leave, but can include it. If you're
/// doing a Get() before then use <see
/// cref="NavigationUITestContextExtensions.ClickReliablyOnUntilUrlChangeAsync(UITestContext, By, TimeSpan?,
/// TimeSpan?)"/> instead.
/// </summary>
public static Task ClickReliablyUntilUrlChangeAsync(
this IWebElement element,
UITestContext context,
TimeSpan? timeout = null,
TimeSpan? interval = null)
{
var originalUri = context.GetCurrentUri();

return context.DoWithRetriesOrFailAsync(
async () =>
{
await element.ClickReliablyAsync(context);
return context.GetCurrentUri() != originalUri;
},
timeout,
interval);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ public static async Task ClickNewContentItemAsync(this UITestContext context, st
if (dropdown)
{
await context.ClickReliablyOnAsync(By.Id("new-dropdown"));
await context.ClickReliablyOnAsync(By.LinkText(contentItemName));
await context.ClickReliablyOnByLinkTextAsync(contentItemName);
}
else
{
await context.ClickReliablyOnAsync(By.LinkText($"New {contentItemName}"));
await context.ClickReliablyOnByLinkTextAsync($"New {contentItemName}");
}
}

Expand Down
4 changes: 2 additions & 2 deletions Lombiq.Tests.UI/Extensions/TenantsUITestContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static async Task CreateAndSwitchToTenantManuallyAsync(
{
await context.CreateTenantManuallyAsync(name, urlPrefix, urlHost, featureProfile, navigate);

await context.ClickReliablyOnAsync(By.LinkText("Setup"));
await context.ClickReliablyOnByLinkTextAsync("Setup");

context.SwitchCurrentTenant(name, urlPrefix);
}
Expand All @@ -34,7 +34,7 @@ public static async Task CreateTenantManuallyAsync(
await context.GoToAdminRelativeUrlAsync("/Tenants");
}

await context.ClickReliablyOnAsync(By.LinkText("Add Tenant"));
await context.ClickReliablyOnByLinkTextAsync("Add Tenant");
await context.ClickAndFillInWithRetriesAsync(By.Id("Name"), name);

if (!string.IsNullOrEmpty(urlPrefix))
Expand Down

0 comments on commit 2b374bb

Please sign in to comment.