Skip to content

Commit

Permalink
Changes required for Telerik.DeviceTests
Browse files Browse the repository at this point in the history
Adds what is used from Maui Core|Controls DeviceTests to DeviceTests.Shared
Implements some internal API access using Reflection
Deals with minor nullable vs nonnullable conficts, compiler warnings, etc.

Runs successfully some tests for iOS and Android
  • Loading branch information
panayot-cankov committed Apr 12, 2024
1 parent 638b011 commit 0a53c06
Show file tree
Hide file tree
Showing 22 changed files with 698 additions and 248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public static MauiAppBuilder ConfigureTestBuilder(this MauiAppBuilder mauiAppBui
{
return
mauiAppBuilder
.RemapForControls()
// WARNING: NO idea what RemapForControls does... I hope it reuses some new Handler classes inplace of old handler classes or something like that and we can get away without it.
// .RemapForControls()
.ConfigureLifecycleEvents(lifecycle =>
{
#if IOS || MACCATALYST
Expand Down
302 changes: 156 additions & 146 deletions src/Controls/tests/DeviceTests/ControlsHandlerTestBase.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Task SetupWindowForTests<THandler>(IWindow window, Func<Task> runTests, IMauiCon
rootView.RemoveView(linearLayoutCompat);
// throw new NotImplementedException("Not sure yet why there is no OnUnloadedAsync on the LinearLayoutCompat");
await linearLayoutCompat.OnUnloadedAsync();
if (viewFragment.View != null)
await viewFragment.View.OnUnloadedAsync();
Expand All @@ -75,147 +77,147 @@ Task SetupWindowForTests<THandler>(IWindow window, Func<Task> runTests, IMauiCon
});
}

public bool ToolbarItemsMatch(
IElementHandler handler,
params ToolbarItem[] toolbarItems)
{
var toolbar = GetPlatformToolbar(handler);
var menu = toolbar.Menu;

Assert.Equal(toolbarItems.Length, menu.Size());

for (var i = 0; i < toolbarItems.Length; i++)
{
ToolbarItem toolbarItem = toolbarItems[i];
var primaryCommand = menu.GetItem(i);
Assert.Equal(toolbarItem.Text, $"{primaryCommand.TitleFormatted}");

if (primaryCommand is MenuItemImpl menuItemImpl)
{
if (toolbarItem.Order != ToolbarItemOrder.Secondary)
{
Assert.True(menuItemImpl.RequiresActionButton(), "Secondary Menu Item `SetShowAsAction` not set correctly");
}
else
{
Assert.False(menuItemImpl.RequiresActionButton(), "Primary Menu Item `SetShowAsAction` not set correctly");
}
}
else
{
throw new Exception($"MenuItem type is not MenuItemImpl. Please rework test to work with {primaryCommand}");
}
}

return true;
}

protected AView GetTitleView(IElementHandler handler)
{
var toolbar = GetPlatformToolbar(handler);
var container = toolbar?.GetFirstChildOfType<Controls.Toolbar.Container>();

if (container != null && container.ChildCount > 0)
return container.GetChildAt(0);

return null;
}

protected MaterialToolbar GetPlatformToolbar(IElementHandler handler)
{
if (handler.VirtualView is VisualElement e)
{
handler = e.Window?.Handler ?? handler;
}

if (handler is IWindowHandler wh)
{
handler = wh.VirtualView.Content.Handler;
}

if (handler is Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer sr)
{
var shell = handler.VirtualView as Shell;
var currentPage = shell.CurrentPage;

if (currentPage?.Handler?.PlatformView is AView pagePlatformView)
{
var parentContainer = pagePlatformView.GetParentOfType<CoordinatorLayout>();
var toolbar = parentContainer?.GetFirstChildOfType<MaterialToolbar>();
return toolbar;
}

return null;
}
else
{
return GetPlatformToolbar(handler.MauiContext);
}
}

protected string GetToolbarTitle(IElementHandler handler) =>
GetPlatformToolbar(handler).Title;

protected MaterialToolbar GetPlatformToolbar(IMauiContext mauiContext)
{
var navManager = mauiContext.GetNavigationRootManager();
if (navManager?.RootView is null)
return null;

var appbarLayout =
navManager.RootView.FindViewById<AViewGroup>(Resource.Id.navigationlayout_appbar);

if (appbarLayout is null &&
navManager.RootView is ContainerView cv &&
cv.CurrentView is Shell shell)
{
if (shell.Handler is Controls.Platform.Compatibility.IShellContext sr)
{
var layout = sr.CurrentDrawerLayout;
var content = layout?.GetFirstChildOfType<Controls.Platform.Compatibility.CustomFrameLayout>();
appbarLayout = content?.GetFirstChildOfType<AppBarLayout>();
}
}

var toolBar = appbarLayout?.GetFirstChildOfType<MaterialToolbar>();

toolBar = toolBar ?? navManager.ToolbarElement?.Toolbar?.Handler?.PlatformView as
MaterialToolbar;

if (toolBar is null)
{
appbarLayout =
(navManager?.RootView as AViewGroup)?.GetFirstChildOfType<AppBarLayout>();

toolBar = appbarLayout?.GetFirstChildOfType<MaterialToolbar>();
}

return toolBar;
}

protected Size GetTitleViewExpectedSize(IElementHandler handler)
{
var context = handler.MauiContext.Context;
var toolbar = GetPlatformToolbar(handler.MauiContext).GetFirstChildOfType<Microsoft.Maui.Controls.Toolbar.Container>();
return new Size(context.FromPixels(toolbar.MeasuredWidth), context.FromPixels(toolbar.MeasuredHeight));
}

public bool IsNavigationBarVisible(IElementHandler handler) =>
IsNavigationBarVisible(handler.MauiContext);

public bool IsNavigationBarVisible(IMauiContext mauiContext)
{
return GetPlatformToolbar(mauiContext)?
.LayoutParameters?.Height > 0;
}

protected bool IsBackButtonVisible(IElementHandler handler)
{
if (GetPlatformToolbar(handler)?.NavigationIcon is DrawerArrowDrawable dad)
return dad.Progress == 1;

return false;
}
// public bool ToolbarItemsMatch(
// IElementHandler handler,
// params ToolbarItem[] toolbarItems)
// {
// var toolbar = GetPlatformToolbar(handler);
// var menu = toolbar.Menu;

// Assert.Equal(toolbarItems.Length, menu.Size());

// for (var i = 0; i < toolbarItems.Length; i++)
// {
// ToolbarItem toolbarItem = toolbarItems[i];
// var primaryCommand = menu.GetItem(i);
// Assert.Equal(toolbarItem.Text, $"{primaryCommand.TitleFormatted}");

// if (primaryCommand is MenuItemImpl menuItemImpl)
// {
// if (toolbarItem.Order != ToolbarItemOrder.Secondary)
// {
// Assert.True(menuItemImpl.RequiresActionButton(), "Secondary Menu Item `SetShowAsAction` not set correctly");
// }
// else
// {
// Assert.False(menuItemImpl.RequiresActionButton(), "Primary Menu Item `SetShowAsAction` not set correctly");
// }
// }
// else
// {
// throw new Exception($"MenuItem type is not MenuItemImpl. Please rework test to work with {primaryCommand}");
// }
// }

// return true;
// }

// protected AView GetTitleView(IElementHandler handler)
// {
// var toolbar = GetPlatformToolbar(handler);
// var container = toolbar?.GetFirstChildOfType<Controls.Toolbar.Container>();

// if (container != null && container.ChildCount > 0)
// return container.GetChildAt(0);

// return null;
// }

// protected MaterialToolbar GetPlatformToolbar(IElementHandler handler)
// {
// if (handler.VirtualView is VisualElement e)
// {
// handler = e.Window?.Handler ?? handler;
// }

// if (handler is IWindowHandler wh)
// {
// handler = wh.VirtualView.Content.Handler;
// }

// if (handler is Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer sr)
// {
// var shell = handler.VirtualView as Shell;
// var currentPage = shell.CurrentPage;

// if (currentPage?.Handler?.PlatformView is AView pagePlatformView)
// {
// var parentContainer = pagePlatformView.GetParentOfType<CoordinatorLayout>();
// var toolbar = parentContainer?.GetFirstChildOfType<MaterialToolbar>();
// return toolbar;
// }

// return null;
// }
// else
// {
// return GetPlatformToolbar(handler.MauiContext);
// }
// }

// protected string GetToolbarTitle(IElementHandler handler) =>
// GetPlatformToolbar(handler).Title;

// protected MaterialToolbar GetPlatformToolbar(IMauiContext mauiContext)
// {
// var navManager = mauiContext.GetNavigationRootManager();
// if (navManager?.RootView is null)
// return null;

// var appbarLayout =
// navManager.RootView.FindViewById<AViewGroup>(Resource.Id.navigationlayout_appbar);

// if (appbarLayout is null &&
// navManager.RootView is ContainerView cv &&
// cv.CurrentView is Shell shell)
// {
// if (shell.Handler is Controls.Platform.Compatibility.IShellContext sr)
// {
// var layout = sr.CurrentDrawerLayout;
// var content = layout?.GetFirstChildOfType<Controls.Platform.Compatibility.CustomFrameLayout>();
// appbarLayout = content?.GetFirstChildOfType<AppBarLayout>();
// }
// }

// var toolBar = appbarLayout?.GetFirstChildOfType<MaterialToolbar>();

// toolBar = toolBar ?? navManager.ToolbarElement?.Toolbar?.Handler?.PlatformView as
// MaterialToolbar;

// if (toolBar is null)
// {
// appbarLayout =
// (navManager?.RootView as AViewGroup)?.GetFirstChildOfType<AppBarLayout>();

// toolBar = appbarLayout?.GetFirstChildOfType<MaterialToolbar>();
// }

// return toolBar;
// }

// protected Size GetTitleViewExpectedSize(IElementHandler handler)
// {
// var context = handler.MauiContext.Context;
// var toolbar = GetPlatformToolbar(handler.MauiContext).GetFirstChildOfType<Microsoft.Maui.Controls.Toolbar.Container>();
// return new Size(context.FromPixels(toolbar.MeasuredWidth), context.FromPixels(toolbar.MeasuredHeight));
// }

// public bool IsNavigationBarVisible(IElementHandler handler) =>
// IsNavigationBarVisible(handler.MauiContext);

// public bool IsNavigationBarVisible(IMauiContext mauiContext)
// {
// return GetPlatformToolbar(mauiContext)?
// .LayoutParameters?.Height > 0;
// }

// protected bool IsBackButtonVisible(IElementHandler handler)
// {
// if (GetPlatformToolbar(handler)?.NavigationIcon is DrawerArrowDrawable dad)
// return dad.Progress == 1;

// return false;
// }

class WindowTestFragment : Fragment
{
Expand All @@ -241,7 +243,7 @@ public WindowTestFragment(IMauiContext mauiContext, IWindow window)
public override AView OnCreateView(ALayoutInflater inflater, AViewGroup container, Bundle savedInstanceState)
{
ScopedMauiContext = _mauiContext.MakeScoped(layoutInflater: inflater, fragmentManager: ChildFragmentManager, registerNewNavigationRoot: true);
var handler = (WindowHandlerStub)_window.ToHandler(ScopedMauiContext);
var handler = (WindowHandlerStub)_window.ToHandler2(ScopedMauiContext);

FakeActivityRootView = new FakeActivityRootView(ScopedMauiContext.Context);
FakeActivityRootView.LayoutParameters = new LinearLayoutCompat.LayoutParams(AViewGroup.LayoutParams.MatchParent, AViewGroup.LayoutParams.MatchParent);
Expand All @@ -250,7 +252,15 @@ public override AView OnCreateView(ALayoutInflater inflater, AViewGroup containe

if (_window is Window window)
{
window.ModalNavigationManager.SetModalParentView(FakeActivityRootView);
var modalNavigationManagerClass = typeof(Element).Assembly.GetType("Microsoft.Maui.Controls.Platform.ModalNavigationManager");
var setModalParentView = modalNavigationManagerClass.GetMethod("SetModalParentView", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
var modalNavigationManager = typeof(Window).GetProperty("ModalNavigationManager", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

setModalParentView.Invoke(
modalNavigationManager.GetValue(window),
new object[] {
FakeActivityRootView
});
}

return FakeActivityRootView;
Expand All @@ -260,8 +270,8 @@ public override void OnResume()
{
base.OnResume();

bool isCreated = (_window as Window)?.IsCreated ?? false;
bool isActivated = (_window as Window)?.IsActivated ?? false;
bool isCreated = _window is Window ? (bool)typeof(Window).GetProperty("IsCreated", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(_window) : false;
bool isActivated = _window is Window ? (bool)typeof(Window).GetProperty("IsActivated", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(_window) : false;

if (!isCreated)
_window.Created();
Expand All @@ -275,7 +285,7 @@ public override void OnResume()
public override void OnDestroy()
{
base.OnDestroy();
bool isDestroyed = (_window as Window)?.IsDestroyed ?? false;
bool isDestroyed = _window is Window ? (bool)typeof(Window).GetProperty("IsDestroyed", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(_window) : false;

if (!isDestroyed)
_window.Destroying();
Expand Down
Loading

0 comments on commit 0a53c06

Please sign in to comment.