Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ public override void PushViewController(UIViewController viewController, bool an

public override UIViewController PopViewController(bool animated)
{
_popRequested = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you include an UITest based on https://github.com/Vetle444/MauiTestApp/tree/swipeBackBug?
Can use App.SwipeLeftToRight(); in the test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it doesn't work for this iOS-specific-swipe-back gesture

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it do anything? I can take a look and add it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be cool if you could figure it out

_pendingViewControllers = null;
if (IsInMoreTab && ParentViewController is UITabBarController tabBarController)
{
Expand Down
62 changes: 62 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue28485.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Maui.Controls.Sample.Issues;
[Issue(IssueTracker.Github, 28485, "Back-navigation with swipe-back navigates back twice", PlatformAffected.iOS)]
public class Issue28485 : Shell
{
public Issue28485()
{
Routing.RegisterRoute("page2", typeof(Issue28485Page2));
Routing.RegisterRoute("page3", typeof(Issue28485Page3));

var page1 = new ShellContent
{
Title = "Page 1",
Content = new ContentPage()
{
Content = new Button
{
Text = "Go to Page 2",
AutomationId = "GotoPage2",
Command = new Command(async () =>
{
await Shell.Current.GoToAsync("page2", false);
})
}
}
};

Items.Add(page1);
}

class Issue28485Page2 : ContentPage
{
public Issue28485Page2()
{
Title = "Page 1";
Content = new StackLayout
{
Children =
{
new Label { Text = "Welcome to Page 2", AutomationId="Page2Label" },
new Button
{
Text = "Go to Page 3",
AutomationId = "GotoPage3",
Command = new Command(async () =>
{
await Shell.Current.GoToAsync("page3", false);
})
}
}
};
}
}

class Issue28485Page3 : ContentPage
{
public Issue28485Page3()
{
Title = "Page 3";
Content = new Label { Text = "Welcome to Page 3", AutomationId = "Page3Label" };
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#if IOS
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue28485 : _IssuesUITest
{
public Issue28485(TestDevice testDevice) : base(testDevice)
{
}

public override string Issue => "Back-navigation with swipe-back navigates back twice";

[Test]
[Category(UITestCategories.Shell)]
[Category(UITestCategories.Navigation)]
public void SwipeBackGestureShouldNavigateOnce()
{
App.WaitForElement("GotoPage2");
App.Click("GotoPage2");
App.WaitForElement("GotoPage3");
App.Click("GotoPage3");
App.Click("Page3Label");
App.InteractivePopGesture();
App.WaitForElement("Page2Label");
App.WaitForNoElement("GotoPage2");
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
using OpenQA.Selenium.Appium.iOS;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium.iOS;
using UITest.Core;

namespace UITest.Appium
{
public class AppiumIOSSpecificActions : ICommandExecutionGroup
{
const string ShakeDeviceCommand = "shake";
const string InteractivePopGesture = "interactivePopGesture";

readonly AppiumApp _appiumApp;

readonly List<string> _commands = new()
{
ShakeDeviceCommand,
InteractivePopGesture
};

public AppiumIOSSpecificActions(AppiumApp appiumApp)
Expand All @@ -29,10 +32,32 @@ public CommandResponse Execute(string commandName, IDictionary<string, object> p
return commandName switch
{
ShakeDeviceCommand => ShakeDevice(parameters),
InteractivePopGesture => PerformInteractivePopGesture(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
}

CommandResponse PerformInteractivePopGesture(IDictionary<string, object> parameters)
{
if (_appiumApp.Driver is IOSDriver iOSDriver)
{
var sceenSize = iOSDriver.Manage().Window.Size;
var args = new Dictionary<string, object>
{
{ "fromX", 0 },
{ "toX", sceenSize.Width * 0.8 },
{ "fromY", sceenSize.Height / 2 },
{ "toY", sceenSize.Height / 2 },
{ "duration", 1 }
};

iOSDriver.ExecuteScript("mobile: dragFromToForDuration", args);
return CommandResponse.SuccessEmptyResponse;
}

return CommandResponse.FailedEmptyResponse;
}

CommandResponse ShakeDevice(IDictionary<string, object> parameters)
{
if (_appiumApp.Driver is IOSDriver iOSDriver)
Expand Down
15 changes: 15 additions & 0 deletions src/TestUtils/src/UITest.Appium/HelperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,21 @@ public static void Shake(this IApp app)
app.CommandExecutor.Execute("shake", ImmutableDictionary<string, object>.Empty);
}

/// <summary>
/// Triggers the interactive pop gesture on an iOS device, simulating the default swipe-back navigation.
/// </summary>
/// <param name="app">The application instance used to execute the gesture.</param>
/// <exception cref="InvalidOperationException">Thrown if the method is called on a non-iOS Appium instance.</exception>
public static void InteractivePopGesture(this IApp app)
{
if (app is not AppiumIOSApp)
{
throw new InvalidOperationException($"Interactive Pop Gesture is only supported on AppiumIOSAppp");
}

app.CommandExecutor.Execute("interactivePopGesture", ImmutableDictionary<string, object>.Empty);
}

/// <summary>
/// Start recording screen.
/// Functionality that's only available on Android, iOS and Windows.
Expand Down
Loading