tafuji's blog

C#, Xamarin, Azure DevOps を中心に書いています。

Xamarin.UITest Tips - Xamarin.Forms SwipeView

はじめに

この記事では、Xamarin.UITest を利用して、Xamarin.Forms の SwipeView を操作する方法を解説します。

SwipeView のサンプルコード

Xamarin.UITest で操作する SwipeView には、Microsoft の Xamarin.Forms のサンプルの「Swipe direction」を利用します。

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SwipeViewDemos.SwipeViewDirectionPage"
             Title="SwipeView swipe direction demo">
    <StackLayout Margin="20">
         <SwipeView>
            <SwipeView.RightItems>
                <SwipeItems>
                    <SwipeItem Text="Favorite"
                               IconImageSource="favorite.png"
                               BackgroundColor="LightGreen"
                               Invoked="OnFavoriteSwipeItemInvoked" />
                    <SwipeItem Text="Delete"
                               IconImageSource="delete.png"
                               BackgroundColor="LightPink"
                               Invoked="OnDeleteSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.RightItems>
            <Grid HeightRequest="60"
                  WidthRequest="300"
                  BackgroundColor="LightGray">
                <Label Text="Swipe left"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" />
            </Grid>
        </SwipeView>
        <SwipeView>
            <SwipeView.LeftItems>
                <SwipeItems>
                    <SwipeItem Text="Favorite"
                               IconImageSource="favorite.png"
                               BackgroundColor="LightGreen"
                               Invoked="OnFavoriteSwipeItemInvoked" />
                    <SwipeItem Text="Delete"
                               IconImageSource="delete.png"
                               BackgroundColor="LightPink"
                               Invoked="OnDeleteSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.LeftItems>
            <Grid HeightRequest="60"
                  WidthRequest="300"
                  BackgroundColor="LightGray">
                <Label Text="Swipe right"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" />
            </Grid>
        </SwipeView>
        <SwipeView>
            <SwipeView.BottomItems>
                <SwipeItems>
                    <SwipeItem Text="Favorite"
                               IconImageSource="favorite.png"
                               BackgroundColor="LightGreen"
                               Invoked="OnFavoriteSwipeItemInvoked" />
                    <SwipeItem Text="Delete"
                               IconImageSource="delete.png"
                               BackgroundColor="LightPink"
                               Invoked="OnDeleteSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.BottomItems>
            <Grid HeightRequest="60"
                  WidthRequest="300"
                  BackgroundColor="LightGray">
                <Label Text="Swipe up"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" />
            </Grid>
        </SwipeView>
        <SwipeView>
            <SwipeView.TopItems>
                <SwipeItems>
                    <SwipeItem Text="Favorite"
                               IconImageSource="favorite.png"
                               BackgroundColor="LightGreen"
                               Invoked="OnFavoriteSwipeItemInvoked" />
                    <SwipeItem Text="Delete"
                               IconImageSource="delete.png"
                               BackgroundColor="LightPink"
                               Invoked="OnDeleteSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.TopItems>
            <Grid HeightRequest="60"
                  WidthRequest="300"
                  BackgroundColor="LightGray">
                <Label Text="Swipe down"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" />
            </Grid>
        </SwipeView>
        <SwipeView>
            <SwipeView.LeftItems>
                <SwipeItems>
                    <SwipeItem Text="Delete"
                               IconImageSource="delete.png"
                               BackgroundColor="LightPink"
                               Invoked="OnDeleteSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.LeftItems>
            <SwipeView.RightItems>
                <SwipeItems>
                    <SwipeItem Text="Favorite"
                               BackgroundColor="LightGreen"
                               Invoked="OnFavoriteSwipeItemInvoked" />
                    <SwipeItem Text="Share"
                               BackgroundColor="LightYellow"
                               Invoked="OnShareSwipeItemInvoked" />
                </SwipeItems>
            </SwipeView.RightItems>
            <Grid HeightRequest="60"
                  WidthRequest="300"
                  BackgroundColor="LightGray">
                <Label Text="Swipe left or right"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" />
            </Grid>
        </SwipeView>
    </StackLayout>
</ContentPage>

Xamarin.UITest で SwipeView を操作する

SwipeView の UI の構造

Repl を利用して、UI の構造を調べてみると、SwipeView は iOSAndroid で異なるクラスで UI が構築されていることがわかります。

プラットフォーム クラス名
iOS Xamarin_Forms_Platform_iOS_SwipeViewRenderer
Android SwipeViewRenderer

従って、Xamarin.UITest で UI 操作を行うコントロールを取得するには、各プラットフォームで異なるクラス名を利用して、Func<AppQuery, AppQuery> の式を作る必要があります。

左にスワイプする

IApp.SwipeLeftToRight メソッドを利用して、左にスワイプを行うことができます。

string className;
if(platform == Platform.iOS)
{
    className = "Xamarin_Forms_Platform_iOS_SwipeViewRenderer";
}
else
{
    className = "SwipeViewRenderer";
}
app.SwipeRightToLeft(x => x.Class(className).Index(0));

右にスワイプする

IApp.SwipeLeftToRight メソッドを利用して、左にスワイプを行うことができます。

string className;
if (platform == Platform.iOS)
{
    className = "Xamarin_Forms_Platform_iOS_SwipeViewRenderer";
}
else
{
    className = "SwipeViewRenderer";
}
app.SwipeLeftToRight(x => x.Class(className).Index(1));

上にスワイプする

IApp インタフェースには上にスワイプするメソッドがないので、SwipeView コントロールの座標を取得して、コントロールの中心座標から上の方向にIApp.DragCoordinates を利用してドラッグすることで、上方向にスワイプを行うことができます。

// SwipeView の座標と高さを取得する
string className;
if (platform == Platform.iOS)
{
    className = "Xamarin_Forms_Platform_iOS_SwipeViewRenderer";
}
else
{
    className = "SwipeViewRenderer";
}

var control = app.Query(x => x.Class(className).Index(2)).FirstOrDefault();
var centerX = control.Rect.CenterX;
var centerY = control.Rect.CenterY;
var height = control.Rect.Height;

// SwipeView の中心から高さの分だけ上方向にドラッグする
app.DragCoordinates(centerX, centerY, centerX, centerY - height);

下にスワイプする

IApp インタフェースには上にスワイプするメソッドがないので、SwipeView コントロールの座標を取得して、コントロールの中心座標から下の方向にIApp.DragCoordinates を利用してドラッグすることで、下方向にスワイプを行うことができます。

// SwipeView の座標と高さを取得する
string className;
if (platform == Platform.iOS)
{
    className = "Xamarin_Forms_Platform_iOS_SwipeViewRenderer";
}
else
{
    className = "SwipeViewRenderer";
}

var control = app.Query(x => x.Class(className).Index(3)).FirstOrDefault();
var centerX = control.Rect.CenterX;
var centerY = control.Rect.CenterY;
var height = control.Rect.Height;

// SwipeView の中心から高さの分だけ下方向にドラッグする
app.DragCoordinates(centerX, centerY, centerX, centerY + height);

参考資料