Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue31075.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue31075"
Title="MediaPicker Modal Test">
<StackLayout Padding="20" Spacing="20">
<Label Text="Test for MediaPicker modal dismissal issue"
HorizontalOptions="Center"
FontSize="16" />

<Label Text="1. Tap 'Open Modal' to open a modal page" />
<Label Text="2. Tap 'Test MediaPicker' in the modal" />
<Label Text="3. Cancel the camera UI" />
<Label Text="4. Verify the modal page is NOT dismissed" />

<Button x:Name="OpenModalButton"
Text="Open Modal"
AutomationId="OpenModalButton"
Clicked="OnOpenModalClicked" />

<Label x:Name="StatusLabel"
Text="Ready to test"
AutomationId="StatusLabel"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
31 changes: 31 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue31075.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 31075, "MediaPicker.CapturePhotoAsync / CaptureVideoAsync causes modal page to dismiss unexpectedly", PlatformAffected.iOS)]
public partial class Issue31075 : ContentPage
{
public Issue31075()
{
InitializeComponent();
}

async void OnOpenModalClicked(object sender, System.EventArgs e)
{
try
{
var modalPage = new Issue31075Modal();
modalPage.ModalClosed += OnModalClosed;
await Navigation.PushModalAsync(modalPage);
StatusLabel.Text = "Modal opened";
}
catch (Exception ex)
{
StatusLabel.Text = $"Error: {ex.Message}";
}
}

void OnModalClosed(object sender, EventArgs e)
{
StatusLabel.Text = "Modal closed successfully";
}
}
}
34 changes: 34 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue31075Modal.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue31075Modal"
Title="Modal Page">
<StackLayout Padding="20" Spacing="20">
<Label Text="This is a modal page"
HorizontalOptions="Center"
FontSize="18"
FontAttributes="Bold" />

<Label Text="Test MediaPicker without dismissing this modal:" />

<Button x:Name="TestMediaPickerButton"
Text="Test MediaPicker (Photo)"
AutomationId="TestMediaPickerButton"
Clicked="OnTestMediaPickerClicked" />

<Button x:Name="TestVideoPickerButton"
Text="Test MediaPicker (Video)"
AutomationId="TestVideoPickerButton"
Clicked="OnTestVideoPickerClicked" />

<Label x:Name="ResultLabel"
Text="No test performed yet"
AutomationId="ResultLabel"
HorizontalOptions="Center" />

<Button x:Name="CloseModalButton"
Text="Close Modal"
AutomationId="CloseModalButton"
Clicked="OnCloseModalClicked" />
</StackLayout>
</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Microsoft.Maui.Media;

namespace Maui.Controls.Sample.Issues
{
public partial class Issue31075Modal : ContentPage
{
public event EventHandler ModalClosed;

public Issue31075Modal()
{
InitializeComponent();
}

async void OnTestMediaPickerClicked(object sender, System.EventArgs e)
{
try
{
ResultLabel.Text = "Testing photo capture...";

// Test the MediaPicker that was previously causing modal dismissal
var result = await MediaPicker.CapturePhotoAsync();

if (result != null)
{
ResultLabel.Text = "Photo captured successfully!";
}
else
{
ResultLabel.Text = "Photo capture was cancelled";
}
}
catch (Exception ex)
{
ResultLabel.Text = $"Error: {ex.Message}";
}
}

async void OnTestVideoPickerClicked(object sender, System.EventArgs e)
{
try
{
ResultLabel.Text = "Testing video capture...";

// Test the MediaPicker that was previously causing modal dismissal
var result = await MediaPicker.CaptureVideoAsync();

if (result != null)
{
ResultLabel.Text = "Video captured successfully!";
}
else
{
ResultLabel.Text = "Video capture was cancelled";
}
}
catch (Exception ex)
{
ResultLabel.Text = $"Error: {ex.Message}";
}
}

async void OnCloseModalClicked(object sender, System.EventArgs e)
{
ModalClosed?.Invoke(this, EventArgs.Empty);
await Navigation.PopModalAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue31075 : _IssuesUITest
{
public Issue31075(TestDevice device) : base(device)
{
}

public override string Issue => "MediaPicker.CapturePhotoAsync / CaptureVideoAsync causes modal page to dismiss unexpectedly";

[Test]
[Category(UITestCategories.Navigation)]
[Category(UITestCategories.Page)]
public void MediaPickerShouldNotDismissModal()
{
// Open the modal page
App.WaitForElement("OpenModalButton");
App.Tap("OpenModalButton");

// Verify modal opened
App.WaitForElement("TestMediaPickerButton");
App.WaitForElement("CloseModalButton");

// Test MediaPicker (this would previously dismiss the modal on iOS)
App.Tap("TestMediaPickerButton");

// On iOS, a permission dialog might appear - we'll handle this gracefully
try
{
// Wait a moment for any permission dialogs
System.Threading.Thread.Sleep(2000);

// Try to dismiss any system dialogs (camera permission, camera UI, etc.)
// The exact behavior will depend on the iOS simulator/device state
// Since we can't easily test the actual camera in UI tests,
// the important thing is that the modal page is still present
}
catch
{
// Ignore any exceptions from system UI interactions
}

// The critical test: verify the modal page is still present
// If the bug exists, this element would not be found because the modal would be dismissed
App.WaitForElement("CloseModalButton", "Modal should still be present after MediaPicker interaction");
App.WaitForElement("TestMediaPickerButton", "Modal content should still be present");

// Clean up by closing the modal properly
App.Tap("CloseModalButton");

// Verify we're back to the main page
App.WaitForElement("OpenModalButton");
}

[Test]
[Category(UITestCategories.Navigation)]
[Category(UITestCategories.Page)]
public void VideoPickerShouldNotDismissModal()
{
// Open the modal page
App.WaitForElement("OpenModalButton");
App.Tap("OpenModalButton");

// Verify modal opened
App.WaitForElement("TestVideoPickerButton");
App.WaitForElement("CloseModalButton");

// Test Video MediaPicker (this would previously dismiss the modal on iOS)
App.Tap("TestVideoPickerButton");

// Similar to photo test - handle system UI gracefully
try
{
System.Threading.Thread.Sleep(2000);
}
catch
{
// Ignore any exceptions from system UI interactions
}

// The critical test: verify the modal page is still present
App.WaitForElement("CloseModalButton", "Modal should still be present after MediaPicker interaction");
App.WaitForElement("TestVideoPickerButton", "Modal content should still be present");

// Clean up by closing the modal properly
App.Tap("CloseModalButton");

// Verify we're back to the main page
App.WaitForElement("OpenModalButton");
}
}
}
2 changes: 1 addition & 1 deletion src/Essentials/src/MediaPicker/MediaPicker.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public async Task<FileResult> PhotoAsync(MediaPickerOptions options, bool photo,
{
CompletedHandler = async info =>
{
await vc.DismissViewControllerAsync(true);
await picker.DismissViewControllerAsync(true);
GetFileResult(info, tcs);
}
};
Expand Down
Loading