Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Testing] Added appium UITest for FlyoutNavigationBetweenItemsWithNavigationStacks #19444

Merged
merged 1 commit into from
Jan 26, 2024
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
@@ -0,0 +1,87 @@
using System;
using Microsoft.Maui.Controls;

namespace Maui.Controls.Sample.Issues
{
// src/Compatibility/ControlGallery/src/Issues.Shared/Issue6738.cs
[Issue(IssueTracker.None, 6738, "Flyout Navigation fails when coupled with tabs that have a stack", PlatformAffected.Android)]
public class Issue6738 : TestShell
{
const string PushAutomationId = "PushPageButton";
const string InsertAutomationId = "InsertPageButton";
const string ReturnAutomationId = "ReturnPageButton";
const string FlyoutMainId = "Main";
const string FlyoutMainTitle = "Main";
const string FlyoutOtherId = "OtherPage";
const string FlyoutOtherTitle = "Other Page";

readonly Tab _flyoutContent = new Tab();
readonly Button _pushPageButton = new Button { Text = "Tap to push new page to stack", AutomationId = PushAutomationId };
readonly Button _insertPageButton = new Button { Text = "Push another page to the stack, then go to tab two", AutomationId = InsertAutomationId };
ContentPage _pushedPage;
readonly Tab _tabOne = new Tab { Title = "TabOne" };
readonly Tab _tabTwo = new Tab { Title = "TabTwo " };

protected override void Init()
{
var tabOnePage = new ContentPage { Content = _pushPageButton };
var stackLayout = new StackLayout();
stackLayout.Children.Add(new Label { Text = "If you've been here already, go to tab one now. Otherwise, go to Other Page in the flyout." });
var returnButton = new Button { Text = "Go back to tab 1", AutomationId = ReturnAutomationId };
returnButton.Clicked += OnReturnTapped;
stackLayout.Children.Add(returnButton);

var tabTwoPage = new ContentPage { Content = stackLayout };
_tabOne.Items.Add(tabOnePage);
_tabTwo.Items.Add(tabTwoPage);

_pushPageButton.Clicked += OnPushTapped;
_insertPageButton.Clicked += OnInsertTapped;
_flyoutContent.Items.Add(new ContentPage { Content = new Label { Text = "Go back to main page via the flyout" } });

Items.Add(new FlyoutItem
{
AutomationId = FlyoutMainId,
Title = FlyoutMainTitle,
Items = { _tabOne, _tabTwo }
});

Items.Add(new FlyoutItem
{
AutomationId = FlyoutOtherId,
Title = FlyoutOtherTitle,
Items = { _flyoutContent }
});
}

void OnReturnTapped(object sender, EventArgs e)
{
ForceTabSwitch();
}

async void OnPushTapped(object sender, EventArgs e)
{
_pushedPage = new ContentPage { Content = _insertPageButton };
await Navigation.PushAsync(_pushedPage);
}

void OnInsertTapped(object sender, EventArgs e)
{
Navigation.InsertPageBefore(new ContentPage { Content = new Label { Text = "This is an extra page" } }, _pushedPage);
ForceTabSwitch();
}

void ForceTabSwitch()
{
if (CurrentItem != null)
{
if (CurrentItem.CurrentItem == _tabOne)
{
CurrentItem.CurrentItem = _tabTwo;
}
else
CurrentItem.CurrentItem = _tabOne;
}
}
}
}
197 changes: 197 additions & 0 deletions src/Controls/samples/Controls.Sample.UITests/Issues/TestShell.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
using System;
using Microsoft.Maui.Controls;

namespace Maui.Controls.Sample.Issues
{
public abstract class TestShell : Shell
{
protected TestShell() : base()
{
Init();
}

protected ContentPage DisplayedPage
{
get
{
return (ContentPage)(CurrentItem.CurrentItem as IShellSectionController).PresentedPage;
}
}

public ContentPage AddTopTab(string title, string icon = null, ShellSection root = null)
{
var page = new ContentPage()
{
Title = title
};

AddTopTab(page, title, icon, root);
return page;
}


public void AddTopTab(ContentPage page, string title = null, string icon = null, ShellSection root = null)
{
if (Items.Count == 0)
{
var item = AddContentPage(page);
item.Items[0].Items[0].Title = title ?? page.Title;
return;
}

root = Items[0].Items[0];
title ??= page.Title;
var content = new ShellContent()
{
Title = title,
Content = page,
Icon = icon,
AutomationId = title
};

root.Items.Add(content);

if (!string.IsNullOrWhiteSpace(content.Title))
content.Route = content.Title;
}

public ContentPage AddBottomTab(ContentPage page, string title, string icon = null)
{
if (Items.Count == 0)
{
var item = AddContentPage(page);
item.Items[0].Items[0].Title = title ?? page.Title;
item.Items[0].Title = title ?? page.Title;
return page;
}

Items[0].Items.Add(new ShellSection()
{
AutomationId = title,
Route = title,
Title = title,
Icon = icon,
Items =
{
new ShellContent()
{
ContentTemplate = new DataTemplate(() => page),
Title = title
}
}
});

return page;
}

public ContentPage AddBottomTab(string title, string icon = null)
{
ContentPage page = new ContentPage();

if (Items.Count == 0)
{
var item = AddContentPage(page, title);
item.Items[0].Items[0].Title = title ?? page.Title;
item.Items[0].Title = title ?? page.Title;
return page;
}

Items[0].Items.Add(new ShellSection()
{
AutomationId = title,
Route = title,
Title = title,
Icon = icon,
Items =
{
new ShellContent()
{
ContentTemplate = new DataTemplate(() => page),
Title = title
}
}
});

return page;
}

public ContentPage CreateContentPage<TShellItem>(string title)
where TShellItem : ShellItem
{
ContentPage page = new ContentPage() { Title = title };
AddContentPage<TShellItem, Tab>(page, title);
return page;
}

public FlyoutItem AddFlyoutItem(string title)
{
return AddContentPage<FlyoutItem, Tab>(new ContentPage(), title);
}

public FlyoutItem AddFlyoutItem(ContentPage page, string title)
{
return AddContentPage<FlyoutItem, Tab>(page, title);
}

public ContentPage CreateContentPage(string shellItemTitle = null)
=> CreateContentPage<ShellItem, ShellSection>(shellItemTitle);

public ContentPage CreateContentPage<TShellItem, TShellSection>(string shellItemTitle = null)
where TShellItem : ShellItem
where TShellSection : ShellSection
{
shellItemTitle ??= $"Item: {Items.Count}";
ContentPage page = new ContentPage();

TShellItem item = Activator.CreateInstance<TShellItem>();
item.Title = shellItemTitle;

TShellSection shellSection = Activator.CreateInstance<TShellSection>();
shellSection.Title = shellItemTitle;

shellSection.Items.Add(new ShellContent()
{
ContentTemplate = new DataTemplate(() => page)
});

item.Items.Add(shellSection);

Items.Add(item);
return page;
}

public ShellItem AddContentPage(ContentPage contentPage = null, string title = null)
=> AddContentPage<ShellItem, ShellSection>(contentPage, title);

public TShellItem AddContentPage<TShellItem, TShellSection>(ContentPage contentPage = null, string title = null)
where TShellItem : ShellItem
where TShellSection : ShellSection
{
title ??= contentPage?.Title;
contentPage ??= new ContentPage();
TShellItem item = Activator.CreateInstance<TShellItem>();
item.Title = title;
TShellSection shellSection = Activator.CreateInstance<TShellSection>();
Items.Add(item);
item.Items.Add(shellSection);
shellSection.Title = title;

var content = new ShellContent()
{
ContentTemplate = new DataTemplate(() => contentPage),
Title = title
};

shellSection.Items.Add(content);

if (!string.IsNullOrWhiteSpace(title))
{
content.Route = title;
}

return item;
}

protected abstract void Init();
}
}
68 changes: 68 additions & 0 deletions src/Controls/tests/UITests/Tests/Issues/Issue6738.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.AppiumTests.Issues
{
public class Issue6738 : _IssuesUITest
{
const string PushAutomationId = "PushPageButton";
const string InsertAutomationId = "InsertPageButton";
const string ReturnAutomationId = "ReturnPageButton";
const string FlyoutMainId = "Main";
const string FlyoutOtherId = "OtherPage";

public Issue6738(TestDevice device) : base(device)
{
}

public override string Issue => "Flyout Navigation fails when coupled with tabs that have a stack";

// src/Compatibility/ControlGallery/src/Issues.Shared/Issue6738.cs
[Test]
public void FlyoutNavigationBetweenItemsWithNavigationStacks()
{
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.iOS, TestDevice.Mac, TestDevice.Windows });

App.WaitForElement(PushAutomationId);
App.Click(PushAutomationId);
App.WaitForElement(InsertAutomationId);
App.Click(InsertAutomationId);

TapInFlyout(FlyoutOtherId);
TapInFlyout(FlyoutMainId);

App.WaitForElement(ReturnAutomationId);
App.Click(ReturnAutomationId);
App.Back();
App.Back();
}

void TapInFlyout(string text)
{
Thread.Sleep(500);

CheckIfOpen();

try
{
App.Click(text);
}
catch
{
// Give it one more try
CheckIfOpen();
App.Click(text);
}

void CheckIfOpen()
{
if (App.FindElement(text) is null)
{
App.Click(72, 72); // Tap in the menu icon to show the Flyout.
App.WaitForElement(text);
}
}
}
}
}
Loading