diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue26843.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue26843.cs new file mode 100644 index 000000000000..c78ec35adf14 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue26843.cs @@ -0,0 +1,99 @@ +using Microsoft.Maui.Controls; +using System.Linq; + +namespace Maui.Controls.Sample.Issues +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + [Issue(IssueTracker.Github, 26843, "WebView Fails to Load URLs with Certain Encoded Characters on Android", PlatformAffected.Android, isInternetRequired:true)] + public partial class Issue26843 : ContentPage + { + private Grid layout; + private Label navigationResultLabel; + private bool isSourceSet; + + public Issue26843() + { + navigationResultLabel = new Label + { + AutomationId = "NavigationResultLabel", + HorizontalOptions = LayoutOptions.Center, + VerticalOptions = LayoutOptions.Center, + TextColor = Colors.Black, + FontSize = 14 + }; + + var webViewSourceEntry = new Entry + { + AutomationId = "WebViewSourceEntry", + Placeholder = "Enter URL" + }; + + var loadButton = new Button + { + AutomationId = "LoadUrlButton", + Text = "Load URL" + }; + + loadButton.Clicked += (sender, e) => + { + if (!string.IsNullOrWhiteSpace(webViewSourceEntry.Text)) + { + var existingWebView = layout.Children.FirstOrDefault(c => c is WebView); + if (existingWebView != null) + { + layout.Children.Remove(existingWebView); + } + + var webView = new WebView + { + AutomationId = "WebView", + ZIndex = 1, + Source = webViewSourceEntry.Text + }; + + webView.Navigated += OnNavigated; + isSourceSet = true; + + layout.Children.Add(webView); + Grid.SetRow(webView, 3); + } + }; + + layout = new Grid + { + RowDefinitions = + { + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }, + new RowDefinition { Height = new GridLength(1, GridUnitType.Star) } + }, + Children = { navigationResultLabel, webViewSourceEntry, loadButton } + }; + + Grid.SetRow(navigationResultLabel, 0); + Grid.SetRow(webViewSourceEntry, 1); + Grid.SetRow(loadButton, 2); + + Content = layout; + } + + private void OnNavigated(object sender, WebNavigatedEventArgs e) + { + if (isSourceSet) + { + if (e.Result == WebNavigationResult.Success) + { + navigationResultLabel.Text = "Successfully navigated to the encoded URL"; + } + else + { + navigationResultLabel.Text = "Failed to navigate to the encoded URL"; + } + isSourceSet = false; + } + } + } +} + + \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26843.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26843.cs new file mode 100644 index 000000000000..de9cbee74f76 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26843.cs @@ -0,0 +1,51 @@ +#if TEST_FAILS_ON_WINDOWS // Skipping this test on Windows due to WebView's OnNavigated event returning WebNavigationResult.Failure for URLs with non-Western characters. More information: https://github.com/dotnet/maui/issues/27425 +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + internal class Issue26843 : _IssuesUITest + { + public Issue26843(TestDevice device) : base(device) { } + + public override string Issue => "WebView Fails to Load URLs with Certain Encoded Characters on Android"; + + /// + /// This test validates that absolute URIs are not treated as relative ones. + /// Notably, we test URIs with non-Western characters (e.g., "Ğ" and spaces encoded as "%20"). + /// + [Test] + [Category(UITestCategories.WebView)] + [TestCase("https://example.com/test-Ağ-Sistem%20Bilgi%20Güvenliği%20Md/Guide.pdf")] + [TestCase("https://google.com/[]")] + public void WebViewShouldLoadEncodedUrl(string url) + { + App.WaitForElement("WebViewSourceEntry"); + App.ClearText("WebViewSourceEntry"); + App.Tap("WebViewSourceEntry"); + App.EnterText("WebViewSourceEntry", url); + App.WaitForElement("LoadUrlButton"); + App.Tap("LoadUrlButton"); + var label = App.WaitForElement("NavigationResultLabel"); + Assert.That(label.GetText(), Is.EqualTo("Successfully navigated to the encoded URL")); + } + + public override void TestSetup() + { + base.TestSetup(); + + try + { + App.WaitForElement("NoInternetAccessLabel", timeout: TimeSpan.FromSeconds(1)); + Assert.Inconclusive("This device doesn't have internet access"); + } + catch (TimeoutException) + { + // Element not found within timeout, assume internet is available + // Continue with the test + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Core/src/Platform/Android/MauiWebView.cs b/src/Core/src/Platform/Android/MauiWebView.cs index 807e7d705e83..03a3d80fe5d1 100644 --- a/src/Core/src/Platform/Android/MauiWebView.cs +++ b/src/Core/src/Platform/Android/MauiWebView.cs @@ -32,7 +32,7 @@ void IWebViewDelegate.LoadUrl(string? url) _handler.CurrentNavigationEvent = WebNavigationEvent.NewPage; } - if (url != null && !url.StartsWith('/') && !Uri.IsWellFormedUriString(url, UriKind.Absolute)) + if (url is not null && !url.StartsWith('/') && !Uri.TryCreate(url, UriKind.Absolute, out _)) { // URLs like "index.html" can't possibly load, so try "file:///android_asset/index.html" url = AssetBaseUrl + url;