Skip to content

Commit

Permalink
Fix iOS so if you remove more than one page it's able to remove them …
Browse files Browse the repository at this point in the history
…successfully (xamarin#14383)

* Fix iOS Shell when removing multiple views

* - ui tests and fix navigate args

* - improve logic

* Update ShellSection.cs

* - update UI Tests
  • Loading branch information
PureWeen authored Jul 5, 2021
1 parent 0cc0a37 commit 86db848
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@
</PackageReference>
<PackageReference Include="Xam.Plugin.DeviceInfo" Version="3.0.2" />
<PackageReference Include="Xamarin.Insights" Version="1.12.3" />
<PackageReference Include="Xamarin.TestCloud.Agent" Version="0.22.1" />
<PackageReference Include="Xamarin.TestCloud.Agent" Version="0.22.2" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;


#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 13916, "[iOS] iOS Application crashes on Back press when navigated to using GoToAsync with \"//\" or \"///\" route if 2 or more things are removed from the navigation stack",
PlatformAffected.iOS)]
#if UITEST
[NUnit.Framework.Category(Core.UITests.UITestCategories.Github5000)]
[NUnit.Framework.Category(UITestCategories.Shell)]
#endif
public class Issue13916 : TestShell
{
static int pageCount = 1;
protected override void Init()
{
Routing.RegisterRoute(nameof(Issue13916SuccessPage), typeof(Issue13916SuccessPage));

AddFlyoutItem(CreateContentPage(), "Push Me");
}


public class Issue13916SuccessPage : ContentPage
{
public Issue13916SuccessPage()
{
StackLayout layout = new StackLayout();
Label label = new Label()
{
Text = "Success",
AutomationId = "Success"
};
layout.Children.Add(label);
Content = layout;
}
}

ContentPage CreateContentPage()
{
StackLayout layout = new StackLayout();
Button button = new Button()
{
Text = "Click Me",
AutomationId = $"ClickMe{pageCount}",
Command = new Command(async () =>
{
if (Navigation.NavigationStack.Count >= 3)
{
await GoToAsync($"../../{nameof(Issue13916SuccessPage)}");
}
else
{
await Navigation.PushAsync(CreateContentPage());
}
})
};
pageCount++;

layout.Children.Add(button);

return new ContentPage()
{
Content = layout
};
}

#if UITEST
[Test]
public void RemovingMoreThanOneInnerPageAndThenPushingAPageCrashes()
{
RunningApp.Tap("ClickMe1");
RunningApp.Tap("ClickMe2");
RunningApp.Tap("ClickMe3");
RunningApp.WaitForElement("Success");
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue13126.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13126_2.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13551.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13916.cs" />
<Compile Include="$(MSBuildThisFileDirectory)RadioButtonTemplateFromStyle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ShellSearchHandlerItemSizing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ShellWithCustomRendererDisabledAnimations.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="Xam.Plugin.DeviceInfo" Version="3.0.2" />
<PackageReference Include="Xamarin.UITest" Version="3.0.14" />
<PackageReference Include="Xamarin.UITest" Version="3.1.0" />
<PackageReference Include="NUnit3TestAdapter">
<Version>3.17.0</Version>
</PackageReference>
Expand Down
211 changes: 211 additions & 0 deletions Xamarin.Forms.Core.UnitTests/ShellNavigatedArgsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Xamarin.Forms.Internals;

namespace Xamarin.Forms.Core.UnitTests
{
[TestFixture]
public class ShellNavigatedArgsTests : ShellTestBase
{
[TearDown]
public override void TearDown()
{
base.TearDown();
Routing.Clear();
}

[Test]
public async Task RemoveInnerPagesNavigatingArgs()
{
Routing.RegisterRoute("SecondPageView", typeof(ContentPage));
Routing.RegisterRoute("ThirdPageView", typeof(ContentPage));
Routing.RegisterRoute("FourthPage", typeof(ContentPage));

var shell = new TestShell(CreateShellItem<FlyoutItem>(shellContentRoute: "HomePageView"));

await shell.GoToAsync("//HomePageView/SecondPageView/ThirdPageView");
await shell.GoToAsync("//HomePageView/FourthPage");

shell.TestNavigatedArgs(ShellNavigationSource.Pop, "//HomePageView/SecondPageView/ThirdPageView", "//HomePageView/FourthPage");
Assert.AreEqual(3, shell.NavigatedCount);
}

[Test]
public async Task PopToRootSetsCorrectNavigationSource()
{
var shell = new TestShell(CreateShellItem());
await shell.Navigation.PushAsync(new ContentPage());
await shell.Navigation.PushAsync(new ContentPage());
await shell.Navigation.PopToRootAsync();
Assert.AreEqual(ShellNavigationSource.PopToRoot, shell.LastShellNavigatingEventArgs.Source);

await shell.Navigation.PushAsync(new ContentPage());
await shell.Navigation.PushAsync(new ContentPage());

await shell.Navigation.PopAsync();
Assert.AreEqual(ShellNavigationSource.Pop, shell.LastShellNavigatingEventArgs.Source);

await shell.Navigation.PopAsync();
Assert.AreEqual(ShellNavigationSource.PopToRoot, shell.LastShellNavigatingEventArgs.Source);
}

[Test]
public async Task PushingSetsCorrectNavigationSource()
{
var shell = new TestShell(CreateShellItem(shellItemRoute: "item1"));
shell.RegisterPage(nameof(PushingSetsCorrectNavigationSource));
await shell.GoToAsync(nameof(PushingSetsCorrectNavigationSource));

shell.TestNavigatingArgs(ShellNavigationSource.Push,
"//item1", $"{nameof(PushingSetsCorrectNavigationSource)}");

shell.TestNavigatedArgs(ShellNavigationSource.Push,
"//item1", $"//item1/{nameof(PushingSetsCorrectNavigationSource)}");
}

[Test]
public async Task ChangingShellItemSetsCorrectNavigationSource()
{
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item1"),
CreateShellItem(shellItemRoute: "item2")
);

await shell.GoToAsync("//item2");

shell.TestNavigationArgs(ShellNavigationSource.ShellItemChanged,
"//item1", "//item2");
}

[Test]
public async Task ChangingShellSectionSetsCorrectNavigationSource()
{
var shell = new TestShell(
CreateShellItem(shellSectionRoute: "item1")
);

shell.Items[0].Items.Add(CreateShellSection(shellContentRoute: "item2"));

await shell.GoToAsync("//item2");

shell.TestNavigationArgs(ShellNavigationSource.ShellSectionChanged,
"//item1", "//item2");
}

[Test]
public async Task PoppingSamePageSetsCorrectNavigationSource()
{
Routing.RegisterRoute("detailspage", typeof(ContentPage));
var shell = new TestShell(CreateShellItem(shellItemRoute: "item1"));
await shell.GoToAsync("detailspage/detailspage");
await shell.Navigation.PopAsync();


shell.TestNavigatingArgs(ShellNavigationSource.Pop,
"//item1/detailspage/detailspage", $"..");

shell.TestNavigatedArgs(ShellNavigationSource.Pop,
"//item1/detailspage/detailspage", $"//item1/detailspage");
}

[Test]
public async Task ChangingShellContentSetsCorrectNavigationSource()
{
var shell = new TestShell(
CreateShellItem(shellContentRoute: "item1")
);

shell.Items[0].Items[0].Items.Add(CreateShellContent(shellContentRoute: "item2"));

await shell.GoToAsync("//item2");

shell.TestNavigationArgs(ShellNavigationSource.ShellContentChanged,
"//item1", "//item2");
}

[Test]
public async Task InsertPageSetsCorrectNavigationSource()
{
Routing.RegisterRoute("pagemiddle", typeof(ContentPage));
Routing.RegisterRoute("page", typeof(ContentPage));
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item")
);

await shell.GoToAsync("//item/page");
await shell.GoToAsync("//item/pagemiddle/page");

shell.TestNavigationArgs(ShellNavigationSource.Insert,
"//item/page", "//item/pagemiddle/page");
}


[Test]
public async Task InsertPageFromINavigationSetsCorrectNavigationSource()
{
Routing.RegisterRoute("pagemiddle", typeof(ContentPage));
Routing.RegisterRoute("page", typeof(ContentPage));
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item")
);

await shell.GoToAsync("//item/page");
ContentPage contentPage = new ContentPage();
Routing.SetRoute(contentPage, "pagemiddle");
shell.Navigation.InsertPageBefore(contentPage, shell.Navigation.NavigationStack.Last());

shell.TestNavigationArgs(ShellNavigationSource.Insert,
"//item/page", "//item/pagemiddle/page");
}


[Test]
public async Task RemovePageFromINavigationSetsCorrectNavigationSource()
{
Routing.RegisterRoute("pagemiddle", typeof(ContentPage));
Routing.RegisterRoute("page", typeof(ContentPage));
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item")
);

await shell.GoToAsync("//item/pagemiddle/page");
shell.Navigation.RemovePage(shell.Navigation.NavigationStack[1]);

shell.TestNavigationArgs(ShellNavigationSource.Remove,
"//item/pagemiddle/page", "//item/page");
}

[Test]
public async Task RemovePageSetsCorrectNavigationSource()
{
Routing.RegisterRoute("pagemiddle", typeof(ContentPage));
Routing.RegisterRoute("page", typeof(ContentPage));
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item")
);

await shell.GoToAsync("//item/pagemiddle/page");
await shell.GoToAsync("//item/page");


shell.TestNavigationArgs(ShellNavigationSource.Remove,
"//item/pagemiddle/page", "//item/page");
}

[Test]
public async Task InitialNavigatingArgs()
{
var shell = new TestShell(
CreateShellItem(shellItemRoute: "item")
);

shell.TestNavigationArgs(ShellNavigationSource.ShellItemChanged,
null, "//item");
}
}
}
Loading

0 comments on commit 86db848

Please sign in to comment.