Skip to content
Closed
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
12 changes: 9 additions & 3 deletions UITests/UITests.App/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<testhelpers:TestAutomationHelpersPanel />

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Click Me" Click="Button_Click"/>
<TextBlock x:Name="textBlock"/>
<Frame x:Name="navigationFrame" />

<StackPanel Orientation="Horizontal" Grid.Row="1" >
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, I don't like the use of the buttons here to control the page navigation, we should build this into the infrastructure itself. So the MainPage has a function of understanding how to switch tasks and can evaluate a string and navigate to that page based on reflection or something, similar to how we navigate within the SampleApp currently:

https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/49760c325ecbddab254b61214e5a808e866e51d6/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs#L100

<Button Content="Simple" Click="btnSimple_Click" />
<Button Content="TextBox Mask" Click="btnTextBoxMask_Click" />
</StackPanel>
</Grid>
</Page>
12 changes: 10 additions & 2 deletions UITests/UITests.App/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using UITests.App.Pages;
using Windows.UI.Xaml;

namespace UITests.App
{
public sealed partial class MainPage
Expand All @@ -11,9 +14,14 @@ public MainPage()
InitializeComponent();
}

private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
private void btnSimple_Click(object sender, RoutedEventArgs e)
{
navigationFrame.Navigate(typeof(SimpleTest));
}

private void btnTextBoxMask_Click(object sender, RoutedEventArgs e)
{
textBlock.Text = "Clicked";
navigationFrame.Navigate(typeof(TextBoxMask));
}
}
}
14 changes: 14 additions & 0 deletions UITests/UITests.App/Pages/SimpleTest.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Page
x:Class="UITests.App.Pages.SimpleTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.App.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Click Me" Click="Button_Click"/>
<TextBlock x:Name="textBlock"/>
</StackPanel>
</Page>
39 changes: 39 additions & 0 deletions UITests/UITests.App/Pages/SimpleTest.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace UITests.App.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SimpleTest : Page
{
public SimpleTest()
{
this.InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
textBlock.Text = "Clicked";
}
}
}
52 changes: 52 additions & 0 deletions UITests/UITests.App/Pages/TextBoxMask.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<Page
x:Class="UITests.App.Pages.TextBoxMask"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.App.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button
x:Name="ChangeButton"
Content="Change Target Value"
Click="ChangeButton_Click"
Grid.Column="0" Grid.Row="0"
/>
<TextBox
x:Name="TextBox"
Width="120"
Padding="0,4,0,0"
VerticalAlignment="Center"
extensions:TextBoxMask.CustomMask="5:[0-5]"
extensions:TextBoxMask.Mask="99:59:59"
TextAlignment="Center"
Text="{x:Bind Value, Mode=OneWay}"
Grid.Column="2" Grid.Row="0"
/>
<TextBlock
x:Name="InitialValueTextBlock"
Text="{x:Bind InitialValue}"
HorizontalAlignment="Center"
Grid.Column="0" Grid.Row="2"
/>
<TextBlock
x:Name="NewValueTextBlock"
Text="{x:Bind NewValue}"
HorizontalAlignment="Center"
Grid.Column="2" Grid.Row="2"
/>
</Grid>
</Page>
62 changes: 62 additions & 0 deletions UITests/UITests.App/Pages/TextBoxMask.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace UITests.App.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TextBoxMask : Page, INotifyPropertyChanged
{
private const string INITIAL_VALUE = "12:50:59";
private const string NEW_VALUE = "00:00:00";

private string _value = INITIAL_VALUE;

public string InitialValue => INITIAL_VALUE;

public string NewValue => NEW_VALUE;

public string Value
{
get => _value;
set
{
_value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
}

public TextBoxMask()
{
this.InitializeComponent();
}

public event PropertyChangedEventHandler PropertyChanged;

private void ChangeButton_Click(object sender, RoutedEventArgs e)
{
Value = NEW_VALUE;
}
}
}
16 changes: 15 additions & 1 deletion UITests/UITests.App/UITests.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\SimpleTest.xaml.cs">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azchohfi can we use the SDK Extras to switch to the new-style project here? Don't want to get into merge problems in the future with multiple-tests being written.

Otherwise we can try using the glob syntax instead?

<DependentUpon>SimpleTest.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\TextBoxMask.xaml.cs">
<DependentUpon>TextBoxMask.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand All @@ -159,6 +165,14 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Pages\SimpleTest.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\TextBoxMask.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
Expand Down Expand Up @@ -252,4 +266,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
32 changes: 31 additions & 1 deletion UITests/UITests.Tests.Shared/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ public void TestCleanup()
}

[TestMethod]
public void SimpleLaunchTest()
public void SimpleTest()
{
OpenTest("Simple");

var button = new Button(FindElement.ByName("Click Me"));
var textBlock = new TextBlock(FindElement.ById("textBlock"));

Expand All @@ -113,5 +115,33 @@ public void SimpleLaunchTest()

Verify.AreEqual("Clicked", textBlock.GetText());
}

[TestMethod]
public void TestTextBoxMaskBinding_Property()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely want to figure out how we split these into multiple files as well, so we can have multiple test cases per test page. i.e. we can have a test page using the component with a setup or two, and then have multiple smaller test methods to run against it.

Though ideally, we figure out how to manage this without tearing down and re-opening the app each time?

@azchohfi as commented on the other PR, do you know how we'd structure this here or have suggestions?

{
OpenTest("TextBox Mask");

var initialValue = FindElement.ById<TextBlock>("InitialValueTextBlock").GetText();
var textBox = FindElement.ById<Edit>("TextBox");

Verify.AreEqual(initialValue, textBox.GetText());

var changeButton = FindElement.ById<Button>("ChangeButton");

changeButton.Click();
Wait.ForIdle();

var newValue = FindElement.ById<TextBlock>("NewValueTextBlock").GetText();

Verify.AreEqual(newValue, textBox.GetText());
}

private static void OpenTest(string name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so this method should be integrated into the test-harness itself and know how to communicate with the MainPage in order to switch the page in the frame. We don't want to have to rely on adding more custom buttons and things to the main test page in order to do this.

As mentioned in the other PR I think the use of a custom Attribute could be handy if we could make that work. i.e.

    [TestMethod]
    [TestXamlFile("TextBoxMaskTestPage")]
    public void TestTextBoxMaskBinding_Property()
    {

The test harness before each test would read the attribute on it to grab the type name of the page to load, then we'd have to send the test app a message to load that page, and then execute the test.

Not sure if we would need an intermediary UI piece, use the clipboard, or go as heavy as an AppService to do this. Looks like in WinUI they just manipulate the UI similar to how you did it here, just more generally with a command: https://github.com/microsoft/microsoft-ui-xaml/blob/master/test/TestAppUtils/NavigateToTestCommand.cs#L12

And they use their TestSetupHelper to manually control the page at the start of each test: https://github.com/microsoft/microsoft-ui-xaml/blob/master/dev/TabView/InteractionTests/TabViewTests.cs#L49

@azchohfi thoughts? Should we just copy the setup WinUI has or should we try and improve upon this somehow with an attribute on the test method itself to control this?

I'm guessing it is easier if the idea is to better introp to WinUI that we more closely follow their patterns? @ranjeshj any preferences on if we experiment or try to more closely align? Has the current WinUI system been working well or have you been looking to changing it in the future?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I left out that part of why I want to try and simplify these connections is to make it as straight-forward and easy for developers to add integration tests so that we can ensure adding them isn't a big burden to our community.

I think if we could introduce a new attribute based system here, it'd give developers the flexibility to re-use a page easily or setup multiple pages for different scenarios, eh?

It also makes each test easier to maintain and understand as all the test harness initialization is abstracted to the attribute.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically we'd set something up like this to grab the attribute for the base of our test system:

public TestContext TestContext { get; set; }

[TestInitialize]
public void TestInitialize()
{
    Debug.WriteLine("Running Test: " + TestContext.TestName);

    var currentlyRunningMethod = GetType().GetMethod(TestContext.TestName);
    var descriptionAttributes = currentlyRunningMethod.GetCustomAttributes(typeof(DescriptionAttribute), true) as System.Collections.Generic.IEnumerable<DescriptionAttribute>;
    var firstOne = descriptionAttributes.FirstOrDefault();
    if (firstOne != null)
    {
        Debug.WriteLine("Description: " + firstOne.Description);
    }
}

This is just grabbing a description attribute, but would work the same for our custom attribute and use that info to load the appropriate page in the Test App via test control commands as done currently or some other channel (AppService?).

In either case, I think we should have the test app load the requested page on demand vs. trying to determine all the pages ahead of time and load them at the start of the app. I think this would help with the test app starting time? Which would help if you're picking specific tests to run from VS, right?

Thoughts?

{
var btn = new Button(FindElement.ByName(name));
Verify.IsNotNull(btn);
btn.Click();
Wait.ForIdle();
}
}
}