Extends Verify to allow verification of Xamarin UIs.
Leverages Xamarin.UITest to capture the state of an app.
https://nuget.org/packages/Verify.Xamarin/
Given an app with a text control:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/theText"
android:text="Hello World!" />
</RelativeLayout>
To prevent the tool bar header (that contains a clock) from making the snapshots unreliable, it is necessary to make the app full screen when running tests.
Add the following to the main activity:
protected override void OnCreate(Bundle bundle)
{
#if DEBUG
Window.AddFlags(WindowManagerFlags.Fullscreen);
Window.ClearFlags(WindowManagerFlags.ForceNotFullscreen);
#endif
Enable VerifyXamarin once at assembly load time:
VerifyXamarin.Enable();
Setup the app
app = ConfigureApp
.Android
.EnableLocalScreenshots()
.ApkFile(apkPath)
.StartApp();
The current app state can then be verified as follows:
[Test]
public async Task AppUsage()
{
await Verify(app);
}
With the state of the control being rendered as:
[
{
Class: 'DecorView',
Rect: 'w:1080 h:1920 x:0 y:0'
},
{
Class: 'LinearLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'FrameLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Id: 'action_bar_root',
Class: 'FitWindowsLinearLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Id: 'content',
Class: 'ContentFrameLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'CoordinatorLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'AppBarLayout',
Rect: 'w:1080 h:147 x:0 y:0'
},
{
Id: 'toolbar',
Class: 'Toolbar',
Rect: 'w:1080 h:147 x:0 y:0'
},
{
Text: 'SampleXamarin',
Class: 'AppCompatTextView',
Rect: 'w:379 h:71 x:42 y:38'
},
{
Class: 'ActionMenuView',
Rect: 'w:105 h:147 x:975 y:0'
},
{
Label: 'More options',
Class: 'ActionMenuPresenter$OverflowMenuButton',
Rect: 'w:105 h:126 x:975 y:10'
},
{
Class: 'RelativeLayout',
Rect: 'w:1080 h:1647 x:0 y:147'
},
{
Id: 'theText',
Text: 'Hello World!',
Class: 'AppCompatTextView',
Rect: 'w:200 h:51 x:440 y:945'
},
{
Id: 'fab',
Class: 'FloatingActionButton',
Rect: 'w:147 h:147 x:891 y:1605'
},
{
Id: 'navigationBarBackground',
Class: 'View',
Rect: 'w:1080 h:126 x:0 y:1794'
}
]
A control can be verified as follows:
[Test]
public async Task ControlUsage()
{
var appResult = app.Query(x => x.Id("theText"))
.Single();
var data = new ControlData(app, appResult);
await Verify(data);
}
With the state of the control being rendered as:
{
Id: 'theText',
Text: 'Hello World!',
Class: 'AppCompatTextView',
Rect: 'w:200 h:51 x:440 y:945'
}
The rendering of Form elements can very slightly between different OS versions. This can make verification on different machines (eg CI) problematic. There are several approaches to mitigate this:
- Using a custom comparer
Monkey designed by Maxim Kulikov from The Noun Project.