1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-16 00:03:22 +00:00

Added UI test project

This commit is contained in:
Alison Fernandes
2022-04-05 00:35:48 +01:00
parent f930028920
commit 88fee155db
20 changed files with 904 additions and 0 deletions

View File

@@ -46,6 +46,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\i
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UiTests", "src\UiTests\UiTests.csproj", "{23FB637B-1705-485F-9464-078FCAF361A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@@ -446,6 +448,36 @@ Global
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|Any CPU.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhone.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhone.Build.0 = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|Any CPU.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhone.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|Any CPU.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhone.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhone.Build.0 = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -464,6 +496,7 @@ Global
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{23FB637B-1705-485F-9464-078FCAF361A8} = {D10CA4A9-F866-40E1-B658-F69051236C71}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}

View File

@@ -0,0 +1,12 @@
using System;
using NUnit.Framework;
namespace Bit.UITests.Categories
{
[AttributeUsage(AttributeTargets.Method)]
#pragma warning disable SA1649 // File name should match first type name
public class SmokeTestAttribute : CategoryAttribute
#pragma warning restore SA1649 // File name should match first type name
{
}
}

View File

@@ -0,0 +1,28 @@
using System;
using Xamarin.UITest;
using Xamarin.UITest.Queries;
namespace Bit.UITests.Extensions
{
public static class IAppExtension
{
public static void Wait(this IApp app, float seconds)
{
var waitTime = DateTime.Now + TimeSpan.FromSeconds(seconds);
app.WaitFor(() => DateTime.Now > waitTime);
}
public static void WaitAndTapElement(this IApp app, Func<AppQuery, AppQuery> elementQuery)
{
app.WaitForElement(elementQuery);
app.Tap(elementQuery);
}
public static void WaitAndTapElement(this IApp app, Func<AppQuery, AppWebQuery> elementQuery)
{
app.WaitForElement(elementQuery);
app.Tap(elementQuery);
}
}
}

View File

@@ -0,0 +1,17 @@
using Xamarin.UITest;
namespace Bit.UITests.Helpers
{
public static class AppState
{
public static void CallBackdoor(this IApp app, string paramExample)
{
var args = new object[]
{
paramExample,
};
app.Invoke("Zamboni", args);
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using Xamarin.UITest.Utils;
namespace Bit.UITests.Helpers
{
public class CustomWaitTimes : IWaitTimes
{
private readonly TimeSpan _timeout;
public static readonly TimeSpan DefaultCustomTimeout = TimeSpan.FromSeconds(30);
public CustomWaitTimes()
{
_timeout = DefaultCustomTimeout;
}
public CustomWaitTimes(TimeSpan timeoutTimeSpan)
{
_timeout = timeoutTimeSpan;
}
public TimeSpan GestureCompletionTimeout => _timeout;
public TimeSpan GestureWaitTimeout => _timeout;
public TimeSpan WaitForTimeout => _timeout;
}
}

View File

@@ -0,0 +1,51 @@
using Bit.UITests.Setup;
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
namespace Bit.UITests.Pages.Accounts
{
public class EnvironmentPage : BasePage
{
private readonly Query _saveButton;
private readonly Query _serverUrlInput;
public EnvironmentPage()
: base()
{
if (OnAndroid)
{
_saveButton = x => x.Marked("save_button");
_serverUrlInput = x => x.Marked("server_input");
return;
}
if (OniOS)
{
_saveButton = x => x.Marked("save_button");
_serverUrlInput = x => x.Marked("server_input");
}
}
protected override PlatformQuery Trait => new PlatformQuery
{
Android = x => x.Marked("server_input"),
iOS = x => x.Marked("server_input"),
};
public EnvironmentPage TapSaveAndNavigate()
{
App.Tap(_saveButton);
WaitForPageToLeave();
return this;
}
public EnvironmentPage InputServerUrl(string serverUrl)
{
App.Tap(_serverUrlInput);
App.EnterText(serverUrl);
App.DismissKeyboard();
App.Screenshot("After inserting the server url, I can see the field filled");
return this;
}
}
}

View File

@@ -0,0 +1,50 @@
using Bit.UITests.Setup;
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
namespace Bit.UITests.Pages.Accounts
{
public class HomePage : BasePage
{
private readonly Query _loginButton;
private readonly Query _environmentButton;
public HomePage()
: base()
{
if (OnAndroid)
{
_loginButton = x => x.Marked("homepage_login_button");
//TODO a11y uses the same fields as the UI tests and we're prioritising that
// improve this by getting the app runtime locale and use the i18n service here instead
_environmentButton = x => x.Marked("Options");
//_environmentButton = x => x.Marked("environment_button");
return;
}
if (OniOS)
{
_loginButton = x => x.Marked("homepage_login_button");
_environmentButton = x => x.Marked("Options");
}
}
protected override PlatformQuery Trait => new PlatformQuery
{
Android = x => x.Marked("logo_image"),
iOS = x => x.Marked("logo_image"),
};
public HomePage TapLoginAndNavigate()
{
App.Tap(_loginButton);
return this;
}
public HomePage TapEnvironmentAndNavigate()
{
App.Tap(_environmentButton);
return this;
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using Bit.UITests.Setup;
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
namespace Bit.UITests.Pages.Accounts
{
public class LoginPage : BasePage
{
private readonly Query _loginButton;
private readonly Query _cancelButton;
private readonly Query _passwordVisibilityToggle;
private readonly Query _emailInput;
private readonly Query _passwordInput;
public LoginPage()
: base()
{
if (OnAndroid)
{
_loginButton = x => x.Marked("loginpage_login_button");
_cancelButton = x => x.Marked("cancel_button");
//TODO a11y uses the same fields as the UI tests and we're prioritising that
// improve this by getting the app runtime locale and use the i18n service here instead
_passwordVisibilityToggle = x => x.Marked("Toggle Visibility");
_emailInput = x => x.Marked("email_input");
_passwordInput = x => x.Marked("password_input");
return;
}
if (OniOS)
{
_loginButton = x => x.Marked("loginpage_login_button");
_cancelButton = x => x.Marked("cancel_button");
_passwordVisibilityToggle = x => x.Marked("Toggle Visibility");
_emailInput = x => x.Marked("email_input");
_passwordInput = x => x.Marked("password_input");
}
}
protected override PlatformQuery Trait => new PlatformQuery
{
Android = x => x.Marked("email_input"),
iOS = x => x.Marked("email_input"),
};
public LoginPage TapLoginAndNavigate()
{
App.Tap(_loginButton);
return this;
}
public LoginPage TapCancelAndNavigate()
{
App.Tap(_cancelButton);
return this;
}
public LoginPage TapPasswordVisibilityToggle()
{
App.Tap(_passwordVisibilityToggle);
return this;
}
public LoginPage InputEmail(string email)
{
App.Tap(_emailInput);
App.EnterText(email);
App.DismissKeyboard();
return this;
}
public LoginPage InputPassword(string password)
{
App.Tap(_passwordInput);
App.EnterText(password);
App.DismissKeyboard();
App.Screenshot("After I input the email and password fields, I can see both fields filled");
return this;
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using Bit.UITests.Setup;
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
namespace Bit.UITests.Pages
{
public class ExamplePage : BasePage
{
private readonly Query _loginButton;
private readonly Query _passwordInput;
public ExamplePage()
: base()
{
if (OnAndroid)
{
_loginButton = x => x.Marked("loginpage_login_button");
_passwordInput = x => x.Marked("password_input");
return;
}
if (OniOS)
{
_loginButton = x => x.Marked("loginpage_login_button");
_passwordInput = x => x.Marked("password_input");
}
}
protected override PlatformQuery Trait => new PlatformQuery
{
Android = x => x.Marked("password_input"),
iOS = x => x.Marked("password_input"),
};
public ExamplePage TapLogin()
{
App.Tap(_loginButton);
return this;
}
public ExamplePage InputPassword(string password)
{
App.Tap(_passwordInput);
App.EnterText(password);
App.DismissKeyboard();
App.Screenshot("After I input the email and password fields, I can see both fields filled");
return this;
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Bit.UITests.Setup;
using Query = System.Func<Xamarin.UITest.Queries.AppQuery, Xamarin.UITest.Queries.AppQuery>;
namespace Bit.UITests.Pages
{
public class TabsPage : BasePage
{
private readonly Query _vaultTab;
private readonly Query _sendTab;
public TabsPage()
: base()
{
_vaultTab = x => x.Marked("My Vault");
_sendTab = x => x.Marked("Send");
}
protected override PlatformQuery Trait => new PlatformQuery
{
Android = x => x.Marked("Send"),
iOS = x => x.Marked("Send"),
};
}
}

View File

@@ -0,0 +1,93 @@
using System;
using System.IO;
using System.Reflection;
using Bit.UITests.Helpers;
using Bit.UITests.Setup.SimulatorManager;
using Xamarin.UITest;
namespace Bit.UITests.Setup
{
internal static class AppManager
{
private static readonly string _slnPath = GetSlnPath();
private const string AndroidPackageName = "com.x8bit.bitwarden";
private const string IosBundleId = "com.x8bit.bitwarden";
private static readonly string _apkPath = Path.Combine(_slnPath, "Android", "bin", "Debug", $"{AndroidPackageName}.apk");
private static readonly string _iosPath = Path.Combine("..", "..", "..", $"{IosBundleId}.app");
private static IApp _app;
private static Platform? _platform;
public static IApp App
{
get
{
if (_app == null)
{
throw new NullReferenceException("'AppManager.App' not set. Call 'AppManager.StartApp()' before trying to access it.");
}
return _app;
}
}
public static Platform Platform
{
get
{
if (_platform == null)
{
throw new NullReferenceException("'AppManager.Platform' not set.");
}
return _platform.Value;
}
set => _platform = value;
}
public static void StartApp()
{
Console.WriteLine($"TestEnvironment.IsTestCloud: {TestEnvironment.IsTestCloud}");
Console.WriteLine($"TestEnvironment.Platform: {TestEnvironment.Platform}");
Console.WriteLine($"Platform: {Platform}");
switch (Platform, TestEnvironment.IsTestCloud)
{
case (Platform.Android, false):
_app = ConfigureApp
.Android
.InstalledApp(AndroidPackageName)
//.ApkFile(_apkPath)
.StartApp();
break;
case (Platform.iOS, false):
_app = ConfigureApp
.iOS
.SetDeviceByName("iPhone X") //NOTE Get Devices name in terminal: xcrun instruments -s devices
.AppBundle(_iosPath)
// .InstalledApp(IosBundleId)
.StartApp();
break;
case (Platform.Android, true):
_app = ConfigureApp.Android.WaitTimes(new CustomWaitTimes()).StartApp();
break;
case (Platform.iOS, true):
_app = ConfigureApp.iOS.WaitTimes(new CustomWaitTimes()).StartApp();
break;
}
}
private static string GetSlnPath()
{
string currentFile = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
var fi = new FileInfo(currentFile);
string path = fi.Directory!.Parent!.Parent!.Parent!.FullName;
return path;
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using Bit.UITests.Extensions;
using Bit.UITests.Helpers;
using NUnit.Framework;
using Xamarin.UITest;
namespace Bit.UITests.Setup
{
public abstract class BasePage
{
protected BasePage()
{
AssertOnPage(CustomWaitTimes.DefaultCustomTimeout);
App.Screenshot("On " + GetType().Name);
}
protected IApp App => AppManager.App;
protected bool OnAndroid => AppManager.Platform == Platform.Android;
// ReSharper disable once InconsistentNaming
protected bool OniOS => AppManager.Platform == Platform.iOS;
protected abstract PlatformQuery Trait { get; }
/// <summary>
/// Verifies that the trait is still present. Defaults to no wait.
/// </summary>
/// <param name="timeout">Time to wait before the assertion fails</param>
public void AssertOnPage(TimeSpan? timeout = default(TimeSpan?))
{
var message = "Unable to verify on page: " + GetType().Name;
if (timeout == null)
{
Assert.IsNotEmpty(App.Query(Trait.Current), message);
}
else
{
Assert.DoesNotThrow(() => App.WaitForElement(Trait.Current, timeout: timeout), message);
}
}
/// <summary>
/// Verifies that the trait is no longer present. Defaults to a 5 second wait.
/// </summary>
/// <param name="timeout">Time to wait before the assertion fails</param>
public void WaitForPageToLeave(TimeSpan? timeout = default(TimeSpan?))
{
timeout ??= TimeSpan.FromSeconds(5);
var message = "Unable to verify *not* on page: " + GetType().Name;
Assert.DoesNotThrow(() => App.WaitForNoElement(Trait.Current, timeout: timeout), message);
}
public BasePage Wait(int seconds)
{
App.Wait(seconds);
return this;
}
public BasePage Back()
{
App.Back();
return this;
}
}
}

View File

@@ -0,0 +1,52 @@
using Bit.UITests.Helpers;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using Xamarin.UITest;
namespace Bit.UITests.Setup
{
[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public abstract class BaseTestFixture
{
protected IApp App => AppManager.App;
protected bool OnAndroid => AppManager.Platform == Platform.Android;
protected bool OniOS => AppManager.Platform == Platform.iOS;
protected BaseTestFixture(Platform platform)
{
AppManager.Platform = platform;
}
[SetUp]
public virtual void BeforeEachTest()
{
AppManager.StartApp();
}
[TearDown]
public void TearDown()
{
if (TestContext.CurrentContext.Result.Outcome.Status != TestStatus.Failed)
{
return;
}
if (App == null)
{
return;
}
if (TestEnvironment.Platform != TestPlatform.Local)
{
return;
}
// NOTE uncomment to help debug failing tests
//App.Repl();
}
}
}

View File

@@ -0,0 +1,9 @@
// NOTE C# 9.0 support
// https://stackoverflow.com/a/64749403/859738
// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices
{
#pragma warning disable SA1649 // File name should match first type name
public class IsExternalInit { }
#pragma warning restore SA1649 // File name should match first type name
}

View File

@@ -0,0 +1,39 @@
using System;
using Xamarin.UITest;
using Xamarin.UITest.Queries;
namespace Bit.UITests.Setup
{
public class PlatformQuery
{
Func<AppQuery, AppQuery> _current;
public Func<AppQuery, AppQuery> Current
{
get
{
if (_current == null)
throw new NullReferenceException("Trait not set for current platform");
return _current;
}
}
public Func<AppQuery, AppQuery> Android
{
set
{
if (AppManager.Platform == Platform.Android)
_current = value;
}
}
public Func<AppQuery, AppQuery> iOS
{
set
{
if (AppManager.Platform == Platform.iOS)
_current = value;
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Collections.Generic;
using System.Diagnostics;
namespace Bit.UITests.Setup.SimulatorManager
{
class InstrumentsRunner
{
static string[] GetInstrumentsOutput()
{
const string cmd = "/usr/bin/xcrun";
var startInfo = new ProcessStartInfo
{
FileName = cmd,
Arguments = "instruments -s devices",
RedirectStandardOutput = true,
UseShellExecute = false
};
var proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
var result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
var lines = result.Split('\n');
return lines;
}
public Simulator[] GetListOfSimulators()
{
var simulators = new List<Simulator>();
var lines = GetInstrumentsOutput();
foreach (var line in lines)
{
var sim = new Simulator(line);
if (sim.IsValid())
{
simulators.Add(sim);
}
}
return simulators.ToArray();
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.UITest;
using Xamarin.UITest.Configuration;
namespace Bit.UITests.Setup.SimulatorManager
{
internal static class IosSimulatorsManager
{
public static iOSAppConfigurator SetDeviceByName(this iOSAppConfigurator configurator, string simulatorName)
{
var deviceId = GetDeviceId(simulatorName);
return configurator.DeviceIdentifier(deviceId);
}
public static string GetDeviceId(string simulatorName)
{
if (!TestEnvironment.Platform.Equals(TestPlatform.Local))
{
return string.Empty;
}
// See below for the InstrumentsRunner class.
IEnumerable<Simulator> simulators = new InstrumentsRunner().GetListOfSimulators();
var simulator = simulators.FirstOrDefault(x => x.Name.Contains(simulatorName));
if (simulator == null)
{
throw new ArgumentException("Could not find a device identifier for '" + simulatorName + "'.", "simulatorName");
}
return simulator.GUID;
}
}
}

View File

@@ -0,0 +1,49 @@
namespace Bit.UITests.Setup.SimulatorManager
{
internal class Simulator
{
public Simulator(string line)
{
ParseLine(line);
}
public string Line { get; private set; }
public string GUID { get; private set; }
public string Name { get; private set; }
public bool IsValid()
{
return !string.IsNullOrWhiteSpace(GUID) && !(string.IsNullOrWhiteSpace(Name));
}
public override string ToString()
{
return Line;
}
void ParseLine(string line)
{
GUID = string.Empty;
Name = string.Empty;
Line = string.Empty;
if (string.IsNullOrWhiteSpace(line))
{
return;
}
Line = line.Trim();
var idx1 = line.IndexOf(" [");
if (idx1 < 1)
{
return;
}
Name = Line.Substring(0, idx1).Trim();
GUID = Line.Substring(idx1 + 2, 36).Trim();
}
}
}

View File

@@ -0,0 +1,60 @@
using Bit.UITests.Categories;
using Bit.UITests.Pages;
using Bit.UITests.Pages.Accounts;
using Bit.UITests.Setup;
using NUnit.Framework;
using Xamarin.UITest;
namespace Bit.UiTests.Tests
{
public class LoginTests : BaseTestFixture
{
private const string _testServerUrl = "zamboni";
private const string _email = "zamboni";
private const string _password = "zamboni";
public LoginTests(Platform platform)
: base(platform)
{
}
//[Test]
public void OpenREPL()
{
App.Repl();
}
[Test]
[SmokeTest]
public void WaitForAppToLoad()
{
new HomePage();
App.Screenshot("App loaded with success!");
}
[Test]
public void LoginWithSuccess()
{
new HomePage()
.TapEnvironmentAndNavigate();
new EnvironmentPage()
.InputServerUrl(_testServerUrl)
.TapSaveAndNavigate();
new HomePage()
.TapLoginAndNavigate();
new LoginPage()
.InputEmail(_email)
.InputPassword(_password)
.TapLoginAndNavigate();
new TabsPage();
App.Screenshot("After logging in with success, I can see the vault");
}
}
}

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{23FB637B-1705-485F-9464-078FCAF361A8}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Bit.UiTests</RootNamespace>
<AssemblyName>UiTests</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
<LangVersion>9.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.UITest" Version="3.2.6" />
<PackageReference Include="NUnit" Version="3.13.3" />
</ItemGroup>
<ItemGroup>
<Compile Include="Categories\SmokeTest.cs" />
<Compile Include="Extensions\IAppExtension.cs" />
<Compile Include="Setup\SimulatorManager\InstrumentsRunner.cs" />
<Compile Include="Setup\SimulatorManager\IosSimulatorsManager.cs" />
<Compile Include="Setup\SimulatorManager\Simulator.cs" />
<Compile Include="Setup\AppManager.cs" />
<Compile Include="Setup\BasePage.cs" />
<Compile Include="Setup\BaseTestFixture.cs" />
<Compile Include="Setup\Csharp9Support.cs" />
<Compile Include="Setup\PlatformQuery.cs" />
<Compile Include="Helpers\CustomWaitTimes.cs" />
<Compile Include="Helpers\AppState.cs" />
<Compile Include="Tests\LoginTests.cs" />
<Compile Include="Pages\Accounts\EnvironmentPage.cs" />
<Compile Include="Pages\Accounts\HomePage.cs" />
<Compile Include="Pages\Accounts\LoginPage.cs" />
<Compile Include="Pages\TabsPage.cs" />
<Compile Include="Pages\ExamplePage.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>