In .NET 6.0 using WebView2, I'm trying to wait for a period of time to see if an element becomes visible in the DOM (essentially what Selenium WebDriverWait does, but in WebView2).
I think this code should do that:
internal async Task<bool> WaitForElementToBeVisible(FormWebView2 formWebView2, string element, int numberOfSecondBeforeTimingOut)
{
using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
try
{
await Task.Run(async () => {
while (true) {
cancellationToken.ThrowIfCancellationRequested(); // Stop the task if cancelled in the outer catch
string webPage = await formWebView2.webView2.ExecuteScriptAsync("document.documentElement.innerHTML"); // Get the web page using JavaScript
string decodedWebPage = System.Text.RegularExpressions.Regex.Unescape(webPage);
if (decodedWebPage.Contains(element))
break; // Stop checking
await Task.Delay(100); // Wait 1/10th of a second before checking again
}
}).WaitAsync(TimeSpan.FromSeconds(numberOfSecondBeforeTimingOut));
// If the task ran to completion, ie the element exists,
Debug.WriteLine("Element exists");
return true;
}
catch (TimeoutException)
{
// If the task created in try timed out,
Debug.WriteLine("Timed out after " + numberOfSecondBeforeTimingOut + " seconds");
cancellationTokenSource.Cancel(); // Cancel the task
return false;
}
}
When I run it, I get an error:
System.InvalidOperationException: CoreWebView2 can only be accessed from the UI thread.
I'm way over my head trying to figure out how to run this on the UI thread. Creating and starting a task on the UI thread looks helpful, but the answer no longer seems to be available in .NET 6.0.
Suggestions, hopefully with sample code, would be very welcome.
This works using a Stopwatch to check for a time out: