Skip to content

Commit d775629

Browse files
fforjanhassanuz
authored andcommitted
add NotepadCalculatorTest sample (#903)
1 parent 3a08341 commit d775629

File tree

9 files changed

+561
-0
lines changed

9 files changed

+561
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//******************************************************************************
2+
//
3+
// Copyright (c) 2017 Microsoft Corporation. All rights reserved.
4+
//
5+
// This code is licensed under the MIT License (MIT).
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13+
// THE SOFTWARE.
14+
//
15+
//******************************************************************************
16+
17+
using Microsoft.VisualStudio.TestTools.UnitTesting;
18+
using OpenQA.Selenium.Appium.Windows;
19+
using OpenQA.Selenium.Remote;
20+
using System;
21+
using System.Threading;
22+
23+
namespace NotepadCalculatorTest
24+
{
25+
public class CalculatorSession : IDisposable
26+
{
27+
// Note: append /wd/hub to the URL if you're directing the test at Appium
28+
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
29+
private const string CalculatorAppId = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App";
30+
31+
public WindowsDriver<WindowsElement> Session { get; private set; }
32+
public WindowsElement CalculatorHeader { get; private set; }
33+
public WindowsElement CalculatorResult { get; private set; }
34+
35+
public CalculatorSession()
36+
{
37+
// Create a new session to bring up an instance of the Calculator application
38+
// Note: Multiple calculator windows (instances) share the same process Id
39+
DesiredCapabilities appCapabilities = new DesiredCapabilities();
40+
appCapabilities.SetCapability("app", CalculatorAppId);
41+
appCapabilities.SetCapability("deviceName", "WindowsPC");
42+
this.Session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
43+
Assert.IsNotNull(Session);
44+
45+
// Set implicit timeout to 1.5 seconds to make element search to retry every 500 ms for at most three times
46+
Session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5);
47+
48+
// Identify calculator mode by locating the calculator header
49+
try
50+
{
51+
CalculatorHeader = Session.FindElementByAccessibilityId("Header");
52+
}
53+
catch
54+
{
55+
CalculatorHeader = Session.FindElementByAccessibilityId("ContentPresenter");
56+
}
57+
58+
// Ensure that calculator is in standard mode
59+
if (!CalculatorHeader.Text.Equals("Standard", StringComparison.OrdinalIgnoreCase))
60+
{
61+
Session.FindElementByAccessibilityId("TogglePaneButton").Click();
62+
Thread.Sleep(TimeSpan.FromSeconds(1));
63+
var splitViewPane = Session.FindElementByClassName("SplitViewPane");
64+
splitViewPane.FindElementByName("Standard Calculator").Click();
65+
Thread.Sleep(TimeSpan.FromSeconds(1));
66+
Assert.IsTrue(CalculatorHeader.Text.Equals("Standard", StringComparison.OrdinalIgnoreCase));
67+
}
68+
69+
// Locate the CalculatorResult element
70+
CalculatorResult = Session.FindElementByAccessibilityId("CalculatorResults");
71+
}
72+
73+
public void Dispose()
74+
{
75+
// Close the application and delete the session
76+
if (Session != null)
77+
{
78+
Session.Quit();
79+
Session = null;
80+
CalculatorHeader = null;
81+
CalculatorResult = null;
82+
}
83+
}
84+
}
85+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//******************************************************************************
2+
//
3+
// Copyright (c) 2017 Microsoft Corporation. All rights reserved.
4+
//
5+
// This code is licensed under the MIT License (MIT).
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13+
// THE SOFTWARE.
14+
//
15+
//******************************************************************************
16+
17+
using Microsoft.VisualStudio.TestTools.UnitTesting;
18+
using OpenQA.Selenium.Appium.Windows;
19+
using System.Threading;
20+
using System;
21+
using System.Runtime.CompilerServices;
22+
23+
namespace NotepadCalculatorTest
24+
{
25+
[TestClass]
26+
public class MultiSession
27+
{
28+
private NotepadSession notepadSession;
29+
private CalculatorSession calculatorSession;
30+
31+
[TestMethod]
32+
[DataRow("One", "Plus", "Seven")]
33+
[DataRow("Nine", "Minus", "One")]
34+
[DataRow("Eight", "Divide by", "Eight")]
35+
public void Templatized(string input1, string operation, string input2)
36+
{
37+
// we (re) start with our notepad session
38+
notepadSession.Session.SwitchTo();
39+
notepadSession.NotepadMainEditBox.SendKeys($"{input1} {operation} {input2} = ");
40+
41+
// now let's switch to calculator
42+
calculatorSession.Session.SwitchTo();
43+
44+
// Run sequence of button presses specified above and validate the results
45+
calculatorSession.Session.FindElementByName(input1).Click();
46+
calculatorSession.Session.FindElementByName(operation).Click();
47+
calculatorSession.Session.FindElementByName(input2).Click();
48+
calculatorSession.Session.FindElementByName("Equals").Click();
49+
50+
// and back to notepad for the result
51+
notepadSession.Session.SwitchTo();
52+
notepadSession.NotepadMainEditBox.SendKeys($"{GetCalculatorResultText()}\n");
53+
}
54+
55+
[TestInitialize]
56+
public void TestInitialize()
57+
{
58+
notepadSession = new NotepadSession();
59+
calculatorSession = new CalculatorSession();
60+
}
61+
62+
[TestCleanup]
63+
public void TestCleanup()
64+
{
65+
calculatorSession.Dispose();
66+
notepadSession.Dispose();
67+
}
68+
69+
private string GetCalculatorResultText()
70+
{
71+
return calculatorSession.CalculatorResult.Text.Replace("Display is", string.Empty).Trim();
72+
}
73+
}
74+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.props" Condition="Exists('packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>NotepadCalculatorTest</RootNamespace>
11+
<AssemblyName>NotepadCalculatorTest</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
15+
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
16+
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
17+
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
18+
<IsCodedUITest>False</IsCodedUITest>
19+
<TestProjectType>UnitTest</TestProjectType>
20+
<NuGetPackageImportStamp>
21+
</NuGetPackageImportStamp>
22+
</PropertyGroup>
23+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
24+
<DebugSymbols>true</DebugSymbols>
25+
<DebugType>full</DebugType>
26+
<Optimize>false</Optimize>
27+
<OutputPath>bin\Debug\</OutputPath>
28+
<DefineConstants>DEBUG;TRACE</DefineConstants>
29+
<ErrorReport>prompt</ErrorReport>
30+
<WarningLevel>4</WarningLevel>
31+
</PropertyGroup>
32+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
33+
<DebugType>pdbonly</DebugType>
34+
<Optimize>true</Optimize>
35+
<OutputPath>bin\Release\</OutputPath>
36+
<DefineConstants>TRACE</DefineConstants>
37+
<ErrorReport>prompt</ErrorReport>
38+
<WarningLevel>4</WarningLevel>
39+
</PropertyGroup>
40+
<ItemGroup>
41+
<Reference Include="appium-dotnet-driver, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
42+
<HintPath>packages\Microsoft.WinAppDriver.Appium.WebDriver.1.0.1-Preview\lib\net45\appium-dotnet-driver.dll</HintPath>
43+
</Reference>
44+
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
45+
<HintPath>packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll</HintPath>
46+
</Reference>
47+
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
48+
<HintPath>packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
49+
</Reference>
50+
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
51+
<HintPath>packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
52+
</Reference>
53+
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
54+
<HintPath>packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
55+
</Reference>
56+
<Reference Include="System" />
57+
<Reference Include="System.Configuration" />
58+
<Reference Include="System.Drawing" />
59+
<Reference Include="WebDriver, Version=3.8.0.0, Culture=neutral, processorArchitecture=MSIL">
60+
<HintPath>packages\Selenium.WebDriver.3.8.0\lib\net45\WebDriver.dll</HintPath>
61+
</Reference>
62+
<Reference Include="WebDriver.Support, Version=3.8.0.0, Culture=neutral, processorArchitecture=MSIL">
63+
<HintPath>packages\Selenium.Support.3.8.0\lib\net45\WebDriver.Support.dll</HintPath>
64+
</Reference>
65+
</ItemGroup>
66+
<Choose>
67+
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
68+
<ItemGroup>
69+
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
70+
</ItemGroup>
71+
</When>
72+
<Otherwise />
73+
</Choose>
74+
<ItemGroup>
75+
<Compile Include="NotepadSession.cs" />
76+
<Compile Include="MultiSession.cs" />
77+
<Compile Include="SingleSession.cs" />
78+
<Compile Include="Properties\AssemblyInfo.cs" />
79+
<Compile Include="CalculatorSession.cs" />
80+
</ItemGroup>
81+
<ItemGroup>
82+
<None Include="packages.config" />
83+
<None Include="README.md" />
84+
</ItemGroup>
85+
<Choose>
86+
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
87+
<ItemGroup>
88+
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
89+
<Private>False</Private>
90+
</Reference>
91+
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
92+
<Private>False</Private>
93+
</Reference>
94+
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
95+
<Private>False</Private>
96+
</Reference>
97+
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
98+
<Private>False</Private>
99+
</Reference>
100+
</ItemGroup>
101+
</When>
102+
</Choose>
103+
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
104+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
105+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
106+
<PropertyGroup>
107+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
108+
</PropertyGroup>
109+
<Error Condition="!Exists('packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.props'))" />
110+
<Error Condition="!Exists('packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.targets'))" />
111+
</Target>
112+
<Import Project="packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.targets" Condition="Exists('packages\MSTest.TestAdapter.1.2.0\build\net45\MSTest.TestAdapter.targets')" />
113+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
114+
Other similar extension points exist, see Microsoft.Common.targets.
115+
<Target Name="BeforeBuild">
116+
</Target>
117+
<Target Name="AfterBuild">
118+
</Target>
119+
-->
120+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.29326.143
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotepadCalculatorTest", "NotepadCalculatorTest.csproj", "{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {993F4E37-F1F7-434A-BFF8-F767326C7654}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//******************************************************************************
2+
//
3+
// Copyright (c) 2017 Microsoft Corporation. All rights reserved.
4+
//
5+
// This code is licensed under the MIT License (MIT).
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13+
// THE SOFTWARE.
14+
//
15+
//******************************************************************************
16+
17+
using Microsoft.VisualStudio.TestTools.UnitTesting;
18+
using OpenQA.Selenium.Appium.Windows;
19+
using OpenQA.Selenium.Remote;
20+
using OpenQA.Selenium;
21+
using System;
22+
23+
namespace NotepadCalculatorTest
24+
{
25+
public class NotepadSession :IDisposable
26+
{
27+
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
28+
private const string NotepadAppId = @"C:\Windows\System32\notepad.exe";
29+
30+
public WindowsElement NotepadMainEditBox { get; private set; }
31+
32+
public NotepadSession()
33+
{
34+
35+
// Create a new session to launch Notepad application
36+
DesiredCapabilities appCapabilities = new DesiredCapabilities();
37+
appCapabilities.SetCapability("app", NotepadAppId);
38+
this.Session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
39+
Assert.IsNotNull(Session);
40+
Assert.IsNotNull(Session.SessionId);
41+
42+
// Verify that Notepad is started with untitled new file
43+
Assert.AreEqual("Untitled - Notepad", Session.Title);
44+
45+
// Set implicit timeout to 1.5 seconds to make element search to retry every 500 ms for at most three times
46+
Session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5);
47+
48+
NotepadMainEditBox = Session.FindElementByClassName("Edit");
49+
}
50+
51+
52+
public void Cleanup()
53+
{
54+
// Select all text and delete to clear the edit box
55+
NotepadMainEditBox.SendKeys(Keys.Control + "a" + Keys.Control);
56+
NotepadMainEditBox.SendKeys(Keys.Delete);
57+
Assert.AreEqual(string.Empty, NotepadMainEditBox.Text);
58+
}
59+
60+
public WindowsDriver<WindowsElement> Session { get; }
61+
62+
public void Dispose()
63+
{
64+
// Close the application and delete the session
65+
if (Session != null)
66+
{
67+
NotepadMainEditBox = null;
68+
69+
Session.Close();
70+
71+
try
72+
{
73+
// Dismiss Save dialog if it is blocking the exit
74+
Session.FindElementByName("Don't Save").Click();
75+
}
76+
catch { }
77+
78+
Session.Quit();
79+
}
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)