mirror of
https://github.com/Microsoft/calculator.git
synced 2025-07-06 05:01:07 -07:00
Hello GitHub
This commit is contained in:
parent
456fe5e355
commit
c13b8a099e
822 changed files with 276650 additions and 75 deletions
11
.editorconfig
Normal file
11
.editorconfig
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
## IDE-independent coding style via EditorConfig: http://editorconfig.org/
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = crlf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
*.sln merge=binary
|
||||||
|
*.csproj merge=binary
|
||||||
|
*.vbproj merge=binary
|
||||||
|
*.vcxproj merge=binary
|
||||||
|
*.vcproj merge=binary
|
||||||
|
*.dbproj merge=binary
|
||||||
|
*.fsproj merge=binary
|
||||||
|
*.lsproj merge=binary
|
||||||
|
*.wixproj merge=binary
|
||||||
|
*.modelproj merge=binary
|
||||||
|
*.sqlproj merge=binary
|
||||||
|
*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
*.jpg binary
|
||||||
|
*.png binary
|
||||||
|
*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
67
.gitignore
vendored
67
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
@ -24,14 +24,11 @@ bld/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
#wwwroot/
|
#wwwroot/
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
|
||||||
Generated\ Files/
|
|
||||||
|
|
||||||
# MSTest test Results
|
# MSTest test Results
|
||||||
[Tt]est[Rr]esult*/
|
[Tt]est[Rr]esult*/
|
||||||
[Bb]uild[Ll]og.*
|
[Bb]uild[Ll]og.*
|
||||||
|
@ -45,29 +42,20 @@ TestResult.xml
|
||||||
[Rr]eleasePS/
|
[Rr]eleasePS/
|
||||||
dlldata.c
|
dlldata.c
|
||||||
|
|
||||||
# Benchmark Results
|
|
||||||
BenchmarkDotNet.Artifacts/
|
|
||||||
|
|
||||||
# .NET Core
|
# .NET Core
|
||||||
project.lock.json
|
project.lock.json
|
||||||
project.fragment.lock.json
|
project.fragment.lock.json
|
||||||
artifacts/
|
artifacts/
|
||||||
**/Properties/launchSettings.json
|
**/Properties/launchSettings.json
|
||||||
|
|
||||||
# StyleCop
|
|
||||||
StyleCopReport.xml
|
|
||||||
|
|
||||||
# Files built by Visual Studio
|
|
||||||
*_i.c
|
*_i.c
|
||||||
*_p.c
|
*_p.c
|
||||||
*_i.h
|
*_i.h
|
||||||
*.ilk
|
*.ilk
|
||||||
*.meta
|
*.meta
|
||||||
*.obj
|
*.obj
|
||||||
*.iobj
|
|
||||||
*.pch
|
*.pch
|
||||||
*.pdb
|
*.pdb
|
||||||
*.ipdb
|
|
||||||
*.pgc
|
*.pgc
|
||||||
*.pgd
|
*.pgd
|
||||||
*.rsp
|
*.rsp
|
||||||
|
@ -105,9 +93,6 @@ ipch/
|
||||||
*.vspx
|
*.vspx
|
||||||
*.sap
|
*.sap
|
||||||
|
|
||||||
# Visual Studio Trace Files
|
|
||||||
*.e2e
|
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
# TFS 2012 Local Workspace
|
||||||
$tf/
|
$tf/
|
||||||
|
|
||||||
|
@ -128,10 +113,6 @@ _TeamCity*
|
||||||
# DotCover is a Code Coverage Tool
|
# DotCover is a Code Coverage Tool
|
||||||
*.dotCover
|
*.dotCover
|
||||||
|
|
||||||
# AxoCover is a Code Coverage Tool
|
|
||||||
.axoCover/*
|
|
||||||
!.axoCover/settings.json
|
|
||||||
|
|
||||||
# Visual Studio code coverage results
|
# Visual Studio code coverage results
|
||||||
*.coverage
|
*.coverage
|
||||||
*.coveragexml
|
*.coveragexml
|
||||||
|
@ -167,7 +148,7 @@ publish/
|
||||||
# Publish Web Output
|
# Publish Web Output
|
||||||
*.[Pp]ublish.xml
|
*.[Pp]ublish.xml
|
||||||
*.azurePubxml
|
*.azurePubxml
|
||||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
*.pubxml
|
*.pubxml
|
||||||
*.publishproj
|
*.publishproj
|
||||||
|
@ -180,11 +161,11 @@ PublishScripts/
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
# The packages folder can be ignored because of Package Restore
|
# The packages folder can be ignored because of Package Restore
|
||||||
**/[Pp]ackages/*
|
**/packages/*
|
||||||
# except build/, which is used as an MSBuild target.
|
# except build/, which is used as an MSBuild target.
|
||||||
!**/[Pp]ackages/build/
|
!**/packages/build/
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
#!**/[Pp]ackages/repositories.config
|
#!**/packages/repositories.config
|
||||||
# NuGet v3's project.json files produces more ignorable files
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
*.nuget.props
|
*.nuget.props
|
||||||
*.nuget.targets
|
*.nuget.targets
|
||||||
|
@ -202,7 +183,6 @@ AppPackages/
|
||||||
BundleArtifacts/
|
BundleArtifacts/
|
||||||
Package.StoreAssociation.xml
|
Package.StoreAssociation.xml
|
||||||
_pkginfo.txt
|
_pkginfo.txt
|
||||||
*.appx
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
# Visual Studio cache files
|
||||||
# files ending in .cache can be ignored
|
# files ending in .cache can be ignored
|
||||||
|
@ -221,10 +201,6 @@ ClientBin/
|
||||||
*.publishsettings
|
*.publishsettings
|
||||||
orleans.codegen.cs
|
orleans.codegen.cs
|
||||||
|
|
||||||
# Including strong name files can present a security risk
|
|
||||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
|
||||||
#*.snk
|
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
#bower_components/
|
#bower_components/
|
||||||
|
@ -239,8 +215,6 @@ _UpgradeReport_Files/
|
||||||
Backup*/
|
Backup*/
|
||||||
UpgradeLog*.XML
|
UpgradeLog*.XML
|
||||||
UpgradeLog*.htm
|
UpgradeLog*.htm
|
||||||
ServiceFabricBackup/
|
|
||||||
*.rptproj.bak
|
|
||||||
|
|
||||||
# SQL Server files
|
# SQL Server files
|
||||||
*.mdf
|
*.mdf
|
||||||
|
@ -251,7 +225,6 @@ ServiceFabricBackup/
|
||||||
*.rdl.data
|
*.rdl.data
|
||||||
*.bim.layout
|
*.bim.layout
|
||||||
*.bim_*.settings
|
*.bim_*.settings
|
||||||
*.rptproj.rsuser
|
|
||||||
|
|
||||||
# Microsoft Fakes
|
# Microsoft Fakes
|
||||||
FakesAssemblies/
|
FakesAssemblies/
|
||||||
|
@ -263,6 +236,9 @@ FakesAssemblies/
|
||||||
.ntvs_analysis.dat
|
.ntvs_analysis.dat
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
# Typescript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
# Visual Studio 6 build log
|
||||||
*.plg
|
*.plg
|
||||||
|
|
||||||
|
@ -302,9 +278,6 @@ __pycache__/
|
||||||
# tools/**
|
# tools/**
|
||||||
# !tools/packages.config
|
# !tools/packages.config
|
||||||
|
|
||||||
# Tabs Studio
|
|
||||||
*.tss
|
|
||||||
|
|
||||||
# Telerik's JustMock configuration file
|
# Telerik's JustMock configuration file
|
||||||
*.jmconfig
|
*.jmconfig
|
||||||
|
|
||||||
|
@ -314,17 +287,15 @@ __pycache__/
|
||||||
*.odx.cs
|
*.odx.cs
|
||||||
*.xsd.cs
|
*.xsd.cs
|
||||||
|
|
||||||
# OpenCover UI analysis results
|
# Calculator specific
|
||||||
OpenCover/
|
Generated Files/
|
||||||
|
# Don't ignore anything under SpkgDefs or TrexDefs
|
||||||
|
!/SpkgDefs/**
|
||||||
|
!/TrexDefs/**
|
||||||
|
!/build/config/TRexDefs/**
|
||||||
|
|
||||||
# Azure Stream Analytics local run output
|
# Localized strings
|
||||||
ASALocalRun/
|
# LCT files are loc system artifacts that we don't want in our repo.
|
||||||
|
*.lct
|
||||||
|
|
||||||
# MSBuild Binary and Structured Log
|
WorkspaceInfo.xml
|
||||||
*.binlog
|
|
||||||
|
|
||||||
# NVidia Nsight GPU debugger configuration file
|
|
||||||
*.nvuser
|
|
||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
|
||||||
.mfractor/
|
|
||||||
|
|
6
CODE_OF_CONDUCT.md
Normal file
6
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||||
|
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||||
|
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or
|
||||||
|
comments.
|
96
CONTRIBUTING.md
Normal file
96
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
# Contributing to Calculator
|
||||||
|
The Calculator team encourages community feedback and contributions. Thank you for your interest in
|
||||||
|
making Calculator better! There are several ways you can get involved.
|
||||||
|
|
||||||
|
## Reporting issues and suggesting new features
|
||||||
|
If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130&newFeedback=True).
|
||||||
|
Feedback Hub reports automatically include diagnostic data, such as the version of Calculator
|
||||||
|
you're using.
|
||||||
|
|
||||||
|
We are happy to hear your ideas for the future of Calculator. Check the
|
||||||
|
[Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130) and see if others have
|
||||||
|
submitted similar feedback. You can upvote existing feedback or submit a new suggestion.
|
||||||
|
|
||||||
|
We always look at upvoted items in Feedback Hub when we decide what to work on next. We read the
|
||||||
|
comments in both Feedback Hub and GitHub, and we look forward to hearing your input. Remember that
|
||||||
|
all community interactions must abide by the [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
## Finding issues you can help with
|
||||||
|
Looking for something to work on?
|
||||||
|
[Issues marked *up for grabs*](https://microsoft.com/#TODO_MIGRATE_THIS_LINK_AFTER_GITHUB_MIGRATION)
|
||||||
|
are a good place to start.
|
||||||
|
|
||||||
|
Another way you can help is by reproducing issues others have reported.
|
||||||
|
[Issues marked *more info needed*](https://microsoft.com/#TODO_MIGRATE_THIS_LINK_AFTER_GITHUB_MIGRATION)
|
||||||
|
don't have all the information needed to take action. You can try to reproduce the issue on your
|
||||||
|
machine and add more details so we can take action on the report.
|
||||||
|
|
||||||
|
## Contributions we accept
|
||||||
|
We welcome your contributions to the Calculator project, especially to fix bugs and to make
|
||||||
|
improvements which address the top issues reported by Calculator users.
|
||||||
|
|
||||||
|
We have a high bar for new features and changes to the user experience. We prefer to evaluate
|
||||||
|
*prototypes* to ensure that the design meets users' needs before we start discussing implementation
|
||||||
|
details and reviewing code. We follow a [user-centered process for developing features](docs/NewFeatureProcess.md).
|
||||||
|
New features need sponsorship from the Calculator team, but we welcome community contributions at
|
||||||
|
many stages of the process.
|
||||||
|
|
||||||
|
## Making changes to the code
|
||||||
|
|
||||||
|
### Preparing your development environment
|
||||||
|
To learn how to build the code and run tests, follow the instructions in the [README](README.md).
|
||||||
|
|
||||||
|
### Style guidelines
|
||||||
|
The code in this project uses several different coding styles, depending on the age and history of
|
||||||
|
the code. Please attempt to match the style of surrounding code as much as possible. In new
|
||||||
|
components, prefer the patterns described in the [C++ core guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
|
||||||
|
and the [modern C++/WinRT language projections](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/).
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
Your change should include tests to verify new functionality wherever possible. Code should be
|
||||||
|
structured so that it can be unit tested independently of the UI. [Manual test cases](docs/ManualTests.md)
|
||||||
|
should be used where automated testing is not feasible.
|
||||||
|
|
||||||
|
### Git workflow
|
||||||
|
Calculator uses the [GitHub flow](https://guides.github.com/introduction/flow/) where most
|
||||||
|
development happens directly on the `master` branch. The `master` branch should always be in a
|
||||||
|
healthy state which is ready for release.
|
||||||
|
|
||||||
|
If your change is complex, please clean up the branch history before submitting a pull request.
|
||||||
|
You can use [git rebase](https://docs.microsoft.com/en-us/azure/devops/repos/git/rebase#squash-local-commits)
|
||||||
|
to group your changes into a small number of commits which we can review one at a time.
|
||||||
|
|
||||||
|
When completing a pull request, we will generally squash your changes into a single commit. Please
|
||||||
|
let us know if your pull request needs to be merged as separate commits.
|
||||||
|
|
||||||
|
## Submitting a pull request and participating in code review
|
||||||
|
Writing a good description for your pull request is crucial to help reviewers and future
|
||||||
|
maintainers understand your change. More detail is better.
|
||||||
|
- [Link the issue you're addressing in the pull request](https://github.com/blog/957-introducing-issue-mentions).
|
||||||
|
- Describe *why* the change is being made and *why* you've chosen a particular solution.
|
||||||
|
- Describe any manual testing you performed to validate your change.
|
||||||
|
|
||||||
|
Please submit one pull request per issue. Large pull requests which have unrelated changes can be
|
||||||
|
difficult to review.
|
||||||
|
|
||||||
|
After submitting a pull request, members of the calculator team will review your code. We will
|
||||||
|
assign the request to an appropriate reviewer within two days. Any member of the community may
|
||||||
|
participate in the review, but at least one member of the Calculator team will ultimately approve
|
||||||
|
the request.
|
||||||
|
|
||||||
|
Often, multiple iterations will be needed to responding to feedback from reviewers. Try looking at
|
||||||
|
[past pull requests](https://microsoft.com/#TODO_MIGRATE_THIS_LINK_AFTER_GITHUB_MIGRATION) to see
|
||||||
|
what the experience might be like.
|
||||||
|
|
||||||
|
## Contributor License Agreement
|
||||||
|
Before we can review and accept a pull request from you, you'll need to sign a Contributor License
|
||||||
|
Agreement (CLA). The CLA ensures that the community is free to use your contributions. More
|
||||||
|
information about the agreement is available on the [Microsoft web site](https://cla.opensource.microsoft.com/).
|
||||||
|
Signing the CLA is an automated process, and you only need to do it once for Microsoft projects on
|
||||||
|
GitHub.
|
||||||
|
|
||||||
|
You don't need to sign a CLA until you're ready to create a pull request. When your pull request is
|
||||||
|
created, it is classified by a bot. If the change is trivial (i.e. you just fixed a typo) then the
|
||||||
|
bot will label the PR `cla-not-required`. Otherwise, it's classified as `cla-required`. In that
|
||||||
|
case, the system will also tell you how you can sign the CLA. Once you have signed a CLA, the
|
||||||
|
current and all future pull requests will be labeled as `cla-signed`.
|
8
LICENSE
8
LICENSE
|
@ -1,7 +1,7 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE
|
SOFTWARE.
|
||||||
|
|
39
NOTICE.txt
Normal file
39
NOTICE.txt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
THIRD PARTY SOFTWARE NOTICES AND INFORMATION
|
||||||
|
Do Not Translate or Localize
|
||||||
|
|
||||||
|
This software incorporates material from third parties. Microsoft makes certain
|
||||||
|
open source code available at http://3rdpartysource.microsoft.com, or you may
|
||||||
|
send a check or money order for US $5.00, including the product name, the open
|
||||||
|
source component name, and version number, to:
|
||||||
|
|
||||||
|
Source Code Compliance Team
|
||||||
|
Microsoft Corporation
|
||||||
|
One Microsoft Way
|
||||||
|
Redmond, WA 98052
|
||||||
|
USA
|
||||||
|
|
||||||
|
Notwithstanding any other terms, you may reverse engineer this software to the
|
||||||
|
extent required to debug changes to any libraries licensed under the GNU Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Hebrew OpenType Layout logic
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2003, 2007 Ralph Hancock & John Hudson
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
77
README.md
77
README.md
|
@ -1,14 +1,71 @@
|
||||||
|
# Calculator
|
||||||
|
The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows.
|
||||||
|
The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies.
|
||||||
|
|
||||||
# Contributing
|
Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Windows Store.](https://www.microsoft.com/store/apps/9WZDNCRFHVN5)
|
||||||
|
|
||||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
<!-- TODO: Replace with something else or remove if builds are not public -->
|
||||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
[](https://microsoft.visualstudio.com/Apps/_build?definitionId=3539)
|
||||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
|
||||||
|
|
||||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|

|
||||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
|
||||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
|
||||||
|
|
||||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
## Features
|
||||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
- Standard Calculator functionality which offers basic operations and evaluates commands immediately as they are entered.
|
||||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
- Scientific Calculator functionality which offers expanded operations and evaluates commands using order of operations.
|
||||||
|
- Programmer Calculator functionality which offers common mathematical operations for developers including conversion between common bases.
|
||||||
|
- Calculation history and memory capabilities.
|
||||||
|
- Conversion between many units of measurement.
|
||||||
|
- Currency conversion based on data retrieved from [Bing](https://www.bing.com).
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
Prerequisites:
|
||||||
|
- Your computer must be running Windows 10, version 1803 or newer
|
||||||
|
- Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient)
|
||||||
|
- Install the "Universal Windows Platform Development" workload
|
||||||
|
- Install the optional "C++ Universal Windows Platform tools" component
|
||||||
|
- Install the latest Windows 10 SDK
|
||||||
|
|
||||||
|

|
||||||
|
- Install the [XamlStyler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension
|
||||||
|
|
||||||
|
<!-- TODO: Replace with external link -->
|
||||||
|
- Get the code:
|
||||||
|
```
|
||||||
|
git clone https://microsoft.visualstudio.com/DefaultCollection/Apps/_git/calculator.app
|
||||||
|
```
|
||||||
|
|
||||||
|
- Open [src\Calculator.sln](\src\Calculator.sln) in Visual Studio to build and run the Calculator app.
|
||||||
|
- For a general description of the Calculator project architecture see [ApplicationArchitecture.md](docs\ApplicationArchitecture.md).
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
To run tests in Visual Studio, install [TDP](https://osgwiki.com/wiki/TDP) <!-- TODO 19570630: Replace with internal docs or remove once we know what we are doing with tests --> and use the TAEF explorer pane.
|
||||||
|
|
||||||
|
Calculator has two primary sets of tests:
|
||||||
|
- [CalculatorUnitTests.vcxproj](\src\CalculatorUnitTests\CalculatorUnitTests.vcxproj) - Unit Tests
|
||||||
|
- [UIAutomationTests.csproj](\src\UIAutomationTests\UIAutomationTests.csproj) - UI Automation using [MitaLite](http://osgwiki.com/mitalite) <!-- TODO: Replace with link to the MitaLite open source repository -->
|
||||||
|
|
||||||
|
## Exploring the repo
|
||||||
|
- [Build](\build) - Scripts which run during the build
|
||||||
|
- [Docs](\Docs) - Documentation for developers
|
||||||
|
- [Loc](\Loc) - Localization settings and files
|
||||||
|
- [PDP](\PDP) - Information about the app for the Store's Product Description Page
|
||||||
|
- [SpkgDefs](\SpkgDefs) - Definitions for building [test packages](https://osgwiki.com/wiki/Test_Package) <!-- TODO: Replace with external link or remove once we know what we are doing with tests -->
|
||||||
|
- [Src](\src) - Main folder for source code
|
||||||
|
- [Tools](\tools) - Scripts and tools to aid in development
|
||||||
|
- [TRexDefs](\TRexDefs) - Definitions for running tests using [TReX](https://osgwiki.com/wiki/TReX) <!-- TODO: Replace with external link or remove once we know what we are doing with tests -->
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Want to contribute? The team encourages community feedback and contributions. Please follow our [contributing guidelines](\CONTRIBUTING.md).
|
||||||
|
|
||||||
|
If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130).
|
||||||
|
If you want to submit an issue to this repository, please read the
|
||||||
|
[issue reporting guidelines](\IssueTracking.md).
|
||||||
|
|
||||||
|
<!-- Uncomment when we finalize licensing
|
||||||
|
# License
|
||||||
|
The Calculator project is released under the *Insert license info and link here*
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- TODO: Remove or replace with the decided on external mechanism to contact the team -->
|
||||||
|
## Contact
|
||||||
|
Questions? Reach out to the PAX Essential Experiences App email alias: <paxeeapps@microsoft.com>
|
15
Tools/PGO/Microsoft.WindowsCalculator.PGO.nuspec
Normal file
15
Tools/PGO/Microsoft.WindowsCalculator.PGO.nuspec
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.WindowsCalculator.PGO</id>
|
||||||
|
<version>$version$</version>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<owners>sourceapps</owners>
|
||||||
|
<projectUrl>https://microsoft.visualstudio.com/Apps/_git/calculator.app</projectUrl>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<description>A package containing the required files for Profile Guided Optimization for Calculator.</description>
|
||||||
|
<copyright>Microsoft Corporation. All rights reserved.</copyright>
|
||||||
|
<tags>pgo</tags>
|
||||||
|
<language>en-US</language>
|
||||||
|
</metadata>
|
||||||
|
</package>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<PGOBuildMode Condition="'$(PGOBuildMode)'==''">Optimize</PGOBuildMode>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<VC_PGO_RunTime_Dir>$(VCToolsInstallDir)bin\Host$(PlatformShortName)\$(PlatformShortName)</VC_PGO_RunTime_Dir>
|
||||||
|
<VC_PGO_RunTime_Dir Condition="'$(Platform)'=='ARM' or '$(Platform)'=='ARM64'">$(VCToolsInstallDir)bin\$(PlatformShortName)</VC_PGO_RunTime_Dir>
|
||||||
|
<ProfileGuidedDatabaseFileName>$(MSBuildThisFileDirectory)..\..\tools\$(PlatformShortName)\Calculator.pgd</ProfileGuidedDatabaseFileName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Enable PGO optimization only for Release builds. -->
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Release' and '$(PGOBuildMode)' == 'Instrument'">
|
||||||
|
<Link>
|
||||||
|
<LinkTimeCodeGeneration>PGInstrument</LinkTimeCodeGeneration>
|
||||||
|
<AdditionalDependencies Condition="'$(Platform)'=='ARM'">$(VC_ReferencesPath_VC_ARM)\pgort.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalDependencies Condition="'$(Platform)'=='ARM64'">$(VC_ReferencesPath_VC_ARM64)\pgort.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalDependencies Condition="'$(Platform)'=='Win32'">$(VC_ReferencesPath_VC_x86)\pgort.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalDependencies Condition="'$(Platform)'=='x64'">$(VC_ReferencesPath_VC_x64)\pgort.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<!-- Include pgort140.dll in the app package -->
|
||||||
|
<ItemGroup Condition="'$(Configuration)' == 'Release' and '$(PGOBuildMode)' == 'Instrument'">
|
||||||
|
<None Include="$(VC_PGO_RunTime_Dir)\pgort140.dll">
|
||||||
|
<Link>%(Filename)%(Extension)</Link>
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
<InProject>false</InProject>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- Enable PGO optimization only for if the pgds file exists. -->
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Release' and '$(PGOBuildMode)' == 'Optimize' and Exists('$(ProfileGuidedDatabaseFileName)')">
|
||||||
|
<Link>
|
||||||
|
<LinkTimeCodeGeneration>PGUpdate</LinkTimeCodeGeneration>
|
||||||
|
<ProfileGuidedDatabase>$(ProfileGuidedDatabaseFileName)</ProfileGuidedDatabase>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
</Project>
|
13
build/config/LocConfigPackageEs.xml
Normal file
13
build/config/LocConfigPackageEs.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Modules>
|
||||||
|
<Module
|
||||||
|
name="Microsoft.Windows.Apps.Calculator"
|
||||||
|
tdbuildteamid="86">
|
||||||
|
<File
|
||||||
|
location="Calculator"
|
||||||
|
path="%TFS_SOURCESDIRECTORY%\src\Calculator\Resources\en-US\Resources.resw" />
|
||||||
|
<File
|
||||||
|
location="Calculator"
|
||||||
|
path="%TFS_SOURCESDIRECTORY%\src\Calculator\Resources\en-US\CEngineStrings.resw" />
|
||||||
|
</Module>
|
||||||
|
</Modules>
|
5
build/config/SignConfig.xml
Normal file
5
build/config/SignConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<SignConfigXML>
|
||||||
|
<job platform="" configuration="" certSubject="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" jobname="EngFunSimpleSign" approvers="gstolt;vigarg">
|
||||||
|
<file src="__INPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" signType="136020001" dest="__OUTPATHROOT__\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle" />
|
||||||
|
</job>
|
||||||
|
</SignConfigXML>
|
30
build/config/TRexDefs/amd64/performance.xml
Normal file
30
build/config/TRexDefs/amd64/performance.xml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE AMD64 Desktop WinPerf Test Run</BuildLogName>
|
||||||
|
<TemplateId>134858</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Performance_AMD64.testlist</RelativeFilePath>
|
||||||
|
<!-- Needed to be able to process multiple results for the same test case but not have reliability run checked on the task -->
|
||||||
|
<OptionalMetadataItems>
|
||||||
|
<OptionalMetadataItem>
|
||||||
|
<Key>VSTS\IsReliabilityRun</Key>
|
||||||
|
<Value>True</Value>
|
||||||
|
</OptionalMetadataItem>
|
||||||
|
</OptionalMetadataItems>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
24
build/config/TRexDefs/amd64/rs4_release.xml
Normal file
24
build/config/TRexDefs/amd64/rs4_release.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS4_RELEASE AMD64 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139642</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_AMD64.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs4_release</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
25
build/config/TRexDefs/amd64/rs5_release.xml
Normal file
25
build/config/TRexDefs/amd64/rs5_release.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!-- RS5_RELEASE Desktop x64 VM run -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS5_RELEASE AMD64 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139642</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_AMD64.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs5_release</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
44
build/config/TRexDefs/amd64/rs_apps_validate.xml
Normal file
44
build/config/TRexDefs/amd64/rs_apps_validate.xml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE AMD64 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139642</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_AMD64.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs_apps_validate</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE AMD64 WCOS Test Run</BuildLogName>
|
||||||
|
<TemplateId>153648</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>WCOS_AMD64.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs_apps_validate</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
31
build/config/TRexDefs/arm/performance.xml
Normal file
31
build/config/TRexDefs/arm/performance.xml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!--RS_PRERELEASE ARM WinCoreOS WinPerf run. -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_PRERELEASE ARM WindowsCore WinPerf Test Run</BuildLogName>
|
||||||
|
<TemplateId>135258</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Performance_ARM.testlist</RelativeFilePath>
|
||||||
|
<!-- Needed to be able to process multiple results for the same test case but not have reliability run checked on the task -->
|
||||||
|
<OptionalMetadataItems>
|
||||||
|
<OptionalMetadataItem>
|
||||||
|
<Key>VSTS\IsReliabilityRun</Key>
|
||||||
|
<Value>True</Value>
|
||||||
|
</OptionalMetadataItem>
|
||||||
|
</OptionalMetadataItems>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
26
build/config/TRexDefs/arm/rs_apps_validate.xml
Normal file
26
build/config/TRexDefs/arm/rs_apps_validate.xml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!-- RS_APPS_VALIDATE WindowsCore ARM Device run -->
|
||||||
|
<!-- Disabling this until we have a testlist template -->
|
||||||
|
<!--<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE ARM WCOS Test Run</BuildLogName>
|
||||||
|
<TemplateId>140487</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_ARM.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs_apps_validate</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>-->
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
25
build/config/TRexDefs/x86/rs4_release.xml
Normal file
25
build/config/TRexDefs/x86/rs4_release.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!-- RS_APPS_VALIDATE Desktop x86 VM run -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE x86 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139643</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_x86.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs4_release</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
25
build/config/TRexDefs/x86/rs5_release.xml
Normal file
25
build/config/TRexDefs/x86/rs5_release.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!-- RS_PRERELEASE Desktop x86 VM run -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE x86 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139643</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_x86.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs5_release</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
46
build/config/TRexDefs/x86/rs_apps_validate.xml
Normal file
46
build/config/TRexDefs/x86/rs_apps_validate.xml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<TReXRunConfigurations>
|
||||||
|
|
||||||
|
<!-- RS_APPS_VALIDATE Desktop x86 VM run -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_APPS_VALIDATE x86 DesktopVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>139643</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>Desktop_x86.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs_apps_validate</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
<!-- RS_APPS_VALIDATE WindowsCore x86 VM run -->
|
||||||
|
<TReXRunConfiguration>
|
||||||
|
<BuildLogName>RS_PRERELEASE x86 WindowsCoreVM Test Run</BuildLogName>
|
||||||
|
<TemplateId>153715</TemplateId>
|
||||||
|
<Owner>paxeedev</Owner>
|
||||||
|
<PrivateRun>true</PrivateRun>
|
||||||
|
<CopyFirstJobSettingWithJobOverride>true</CopyFirstJobSettingWithJobOverride>
|
||||||
|
<RelativeFilePath>WCOS_x86.testlist</RelativeFilePath>
|
||||||
|
<Branch>rs_apps_validate</Branch>
|
||||||
|
<WorkflowParameters>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
<WorkflowParameter>
|
||||||
|
<Key>_AlternatePackageRoot</Key>
|
||||||
|
<Value>\\pkges\release\TAEF\validation.taef.provenance\1812.20007-develop\UniversalTestPackages;\\edge-svcs\Release\MITALite\Apps_eng.mitalite_ci\Latest.tst</Value>
|
||||||
|
</WorkflowParameter>
|
||||||
|
</WorkflowParameters>
|
||||||
|
</TReXRunConfiguration>
|
||||||
|
|
||||||
|
</TReXRunConfigurations>
|
12
build/config/TestLists/ARM/Desktop_ARM.testlist
Normal file
12
build/config/TestLists/ARM/Desktop_ARM.testlist
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||||
|
"TestMDs": [
|
||||||
|
{
|
||||||
|
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm\\fre\\Calculator.UITests.testmd",
|
||||||
|
"ExecutionProfile": "All"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FilePath": "CalculatorUnitTests\\Prebuilt\\Test\\arm\\fre\\CalculatorUnitTests.testmd",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
9
build/config/TestLists/ARM/Performance_ARM.testlist
Normal file
9
build/config/TestLists/ARM/Performance_ARM.testlist
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||||
|
"TestMDs": [
|
||||||
|
{
|
||||||
|
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm\\fre\\Calculator.UITests.testmd",
|
||||||
|
"ExecutionProfile": "Performance"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
12
build/config/TestLists/ARM/WCOS_ARM.testlist
Normal file
12
build/config/TestLists/ARM/WCOS_ARM.testlist
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||||
|
"TestMDs": [
|
||||||
|
{
|
||||||
|
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm\\fre\\Calculator.UITests.testmd",
|
||||||
|
"ExecutionProfile": "All"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FilePath": "CalculatorUnitTests\\Prebuilt\\Test\\arm\\fre\\CalculatorUnitTests.testmd",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
12
build/config/TestLists/ARM64/Desktop_ARM64.testlist
Normal file
12
build/config/TestLists/ARM64/Desktop_ARM64.testlist
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||||
|
"TestMDs": [
|
||||||
|
{
|
||||||
|
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm64\\fre\\Calculator.UITests.testmd",
|
||||||
|
"ExecutionProfile": "All"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FilePath": "CalculatorUnitTests\\Prebuilt\\Test\\arm64\\fre\\CalculatorUnitTests.testmd",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
12
build/config/TestLists/ARM64/WCOS_ARM64.testlist
Normal file
12
build/config/TestLists/ARM64/WCOS_ARM64.testlist
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||||
|
"TestMDs": [
|
||||||
|
{
|
||||||
|
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm64\\fre\\Calculator.UITests.testmd",
|
||||||
|
"ExecutionProfile": "All"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FilePath": "CalculatorUnitTests\\Prebuilt\\Test\\arm64\\fre\\CalculatorUnitTests.testmd",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
28
build/config/rs_apps_utils.json
Normal file
28
build/config/rs_apps_utils.json
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"Branch": [
|
||||||
|
{
|
||||||
|
"collection":"microsoft",
|
||||||
|
"project":"OS",
|
||||||
|
"repo":"os",
|
||||||
|
"name":"official/rs_apps_utils",
|
||||||
|
"CheckinFiles": [
|
||||||
|
{
|
||||||
|
"source":"vpack/app/calculator.app.man",
|
||||||
|
"path": "/redist/mspartners/ipa/Calculator",
|
||||||
|
"type": "File"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source":"vpack/app/calculator.app.man",
|
||||||
|
"path": "/onecoreuap/redist/mspartners/ipa/Calculator",
|
||||||
|
"type": "File"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Email": [
|
||||||
|
{
|
||||||
|
"sendTo":"paxeedev",
|
||||||
|
"sendOnErrorOnly": "True"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
28
build/config/rs_apps_validate.json
Normal file
28
build/config/rs_apps_validate.json
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"Branch": [
|
||||||
|
{
|
||||||
|
"collection":"microsoft",
|
||||||
|
"project":"OS",
|
||||||
|
"repo":"os",
|
||||||
|
"name":"official/rs_apps_validate",
|
||||||
|
"CheckinFiles": [
|
||||||
|
{
|
||||||
|
"source":"vpack/app/calculator.app.man",
|
||||||
|
"path": "/redist/mspartners/ipa/Calculator",
|
||||||
|
"type": "File"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source":"vpack/app/calculator.app.man",
|
||||||
|
"path": "/onecoreuap/redist/mspartners/ipa/Calculator",
|
||||||
|
"type": "File"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Email": [
|
||||||
|
{
|
||||||
|
"sendTo":"paxeedev",
|
||||||
|
"sendOnErrorOnly": "True"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
44
build/pipelines/azure-pipelines.ci.yaml
Normal file
44
build/pipelines/azure-pipelines.ci.yaml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#
|
||||||
|
# Continuous Integration (CI)
|
||||||
|
# This pipeline builds and validate the app in all supported configurations. If the build was
|
||||||
|
# queued to validate a pull request, we build and test only x64.
|
||||||
|
#
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
- servicing/*
|
||||||
|
pr:
|
||||||
|
- master
|
||||||
|
- servicing/*
|
||||||
|
|
||||||
|
name: 0.$(Date:yyMM).$(Date:dd)$(Rev:rr).0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- template: ./templates/build-app-public.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
- template: ./templates/build-app-public.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x86
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/build-app-public.yaml
|
||||||
|
parameters:
|
||||||
|
platform: ARM
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/build-app-public.yaml
|
||||||
|
parameters:
|
||||||
|
platform: ARM64
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/run-unit-tests.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
- template: ./templates/run-unit-tests.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x86
|
||||||
|
|
||||||
|
- template: ./templates/package-appxbundle.yaml
|
44
build/pipelines/azure-pipelines.loc.yaml
Normal file
44
build/pipelines/azure-pipelines.loc.yaml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#
|
||||||
|
# Localization
|
||||||
|
# This pipeline uploads English strings files to the localization service, downloads any translated
|
||||||
|
# files which are available, and checks them in to git. This pipeline relies on Microsoft-internal
|
||||||
|
# resources to run.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Expects a variable called LocServiceKey to contain the OAuth client secret for Touchdown.
|
||||||
|
|
||||||
|
trigger: none
|
||||||
|
pr: none
|
||||||
|
|
||||||
|
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Localize
|
||||||
|
pool:
|
||||||
|
name: Package ES Custom Demands Lab A
|
||||||
|
demands:
|
||||||
|
- ClientAlias -equals PKGESUTILAPPS
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
- task: PkgESSetupBuild@10
|
||||||
|
displayName: Initialize Package ES
|
||||||
|
inputs:
|
||||||
|
productName: Calculator
|
||||||
|
branchVersion: true
|
||||||
|
|
||||||
|
- task: PkgESTouchdownLocService@10
|
||||||
|
displayName: Package ES Touchdown Loc Service
|
||||||
|
inputs:
|
||||||
|
IsCallToServiceStepSelected: true
|
||||||
|
IsCheckedInFileSelected: true
|
||||||
|
CheckinFilesAtOriginFilePath: true
|
||||||
|
GitLocPath: Loc/Resources
|
||||||
|
LocConfigFile: build/config/LocConfigPackageEs.xml
|
||||||
|
AuthenticationMode: OAuth
|
||||||
|
ClientApplicationID: d3dd8113-65b3-4526-bdca-a00a7d1c37ba
|
||||||
|
ApplicationKeyID: $(LocServiceKey)
|
||||||
|
SendToLoc: true
|
48
build/pipelines/azure-pipelines.release.yaml
Normal file
48
build/pipelines/azure-pipelines.release.yaml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#
|
||||||
|
# Release
|
||||||
|
# This pipeline builds a version of the app in a production configuration to be released to the
|
||||||
|
# Store and the Windows image. This pipeline relies on Microsoft-internal resources to run.
|
||||||
|
#
|
||||||
|
|
||||||
|
trigger: none
|
||||||
|
pr: none
|
||||||
|
|
||||||
|
variables:
|
||||||
|
versionMajor: 10
|
||||||
|
versionMinor: 1901
|
||||||
|
versionBuild: $[counter('10.1901.*', 500)]
|
||||||
|
versionPatch: 0
|
||||||
|
|
||||||
|
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- template: ./templates/build-app-internal.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
- template: ./templates/build-app-internal.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x86
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/build-app-internal.yaml
|
||||||
|
parameters:
|
||||||
|
platform: ARM
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/build-app-internal.yaml
|
||||||
|
parameters:
|
||||||
|
platform: ARM64
|
||||||
|
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
|
||||||
|
- template: ./templates/run-unit-tests.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
- template: ./templates/run-unit-tests.yaml
|
||||||
|
parameters:
|
||||||
|
platform: x86
|
||||||
|
|
||||||
|
- template: ./templates/package-appxbundle.yaml
|
||||||
|
|
||||||
|
- template: ./templates/prepare-release-internalonly.yaml
|
62
build/pipelines/templates/build-app-internal.yaml
Normal file
62
build/pipelines/templates/build-app-internal.yaml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# This template contains a job to build the app for a single architecture and run static analysis
|
||||||
|
# tools on the binaries.
|
||||||
|
# The app is built in a production configuration to be released to the Store and the Windows image.
|
||||||
|
# This job relies on Microsoft-internal resources to run.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
platform: ''
|
||||||
|
condition: ''
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Build${{ parameters.platform }}
|
||||||
|
displayName: Build ${{ parameters.platform }}
|
||||||
|
condition: ${{ parameters.condition }}
|
||||||
|
pool:
|
||||||
|
name: Package ES Custom Demands Lab A
|
||||||
|
demands:
|
||||||
|
- msbuild
|
||||||
|
- visualstudio
|
||||||
|
- ClientAlias -equals PKGESUTILAPPS
|
||||||
|
variables:
|
||||||
|
BuildConfiguration: Release
|
||||||
|
BuildPlatform: ${{ parameters.platform }}
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
- task: UniversalPackages@0
|
||||||
|
displayName: Download internals package
|
||||||
|
inputs:
|
||||||
|
command: download
|
||||||
|
downloadDirectory: $(Build.SourcesDirectory)
|
||||||
|
vstsFeed: WindowsApps
|
||||||
|
vstsFeedPackage: calculator-internals
|
||||||
|
vstsPackageVersion: 0.0.7
|
||||||
|
|
||||||
|
- template: ./build-single-architecture.yaml
|
||||||
|
parameters:
|
||||||
|
extraMsBuildArgs: '/p:IsStoreBuild=true'
|
||||||
|
|
||||||
|
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3
|
||||||
|
displayName: Run BinSkim
|
||||||
|
inputs:
|
||||||
|
inputType: Basic
|
||||||
|
analyzeTarget: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator\*
|
||||||
|
analyzeVerbose: true
|
||||||
|
analyzeHashes: true
|
||||||
|
continueOnError: true
|
||||||
|
|
||||||
|
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1
|
||||||
|
displayName: Run PoliCheck
|
||||||
|
inputs:
|
||||||
|
targetType: F
|
||||||
|
|
||||||
|
- task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
|
||||||
|
displayName: Publish security analysis logs
|
||||||
|
|
||||||
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
|
displayName: Detect open source components
|
||||||
|
inputs:
|
||||||
|
sourceScanPath: $(Agent.BuildDirectory)
|
27
build/pipelines/templates/build-app-public.yaml
Normal file
27
build/pipelines/templates/build-app-public.yaml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# This template contains a job to build the app for a single architecture.
|
||||||
|
# Only the contents of the public repository are built; internal resources are not used.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
platform: ''
|
||||||
|
condition: ''
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Build${{ parameters.platform }}
|
||||||
|
displayName: Build ${{ parameters.platform }}
|
||||||
|
condition: ${{ parameters.condition }}
|
||||||
|
pool:
|
||||||
|
name: Package ES Custom Demands Lab A
|
||||||
|
demands:
|
||||||
|
- msbuild
|
||||||
|
- visualstudio
|
||||||
|
- ClientAlias -equals PKGESUTILAPPS
|
||||||
|
variables:
|
||||||
|
BuildConfiguration: Release
|
||||||
|
BuildPlatform: ${{ parameters.platform }}
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
- template: ./build-single-architecture.yaml
|
53
build/pipelines/templates/build-single-architecture.yaml
Normal file
53
build/pipelines/templates/build-single-architecture.yaml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# This template contains steps to build the app for a single architecture.
|
||||||
|
# The job containing these steps must set the variables 'BuildConfiguration' and 'BuildPlatform'.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
extraMsBuildArgs: ''
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: NuGetToolInstaller@0
|
||||||
|
displayName: Use NuGet 4.7.1
|
||||||
|
inputs:
|
||||||
|
versionSpec: 4.7.1
|
||||||
|
checkLatest: true
|
||||||
|
|
||||||
|
# In most accounts, you can just use 'NuGetCommand' instead of this GUID.
|
||||||
|
# In the microsoft.visualstudio.com account, NuGetCommand is ambiguous so the GUID is needed.
|
||||||
|
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||||
|
displayName: NuGet restore src/Calculator.sln
|
||||||
|
inputs:
|
||||||
|
command: custom
|
||||||
|
arguments: restore src/Calculator.sln -Verbosity Detailed -NonInteractive
|
||||||
|
|
||||||
|
- task: PowerShell@2
|
||||||
|
displayName: Set version number in AppxManifest
|
||||||
|
inputs:
|
||||||
|
filePath: $(Build.SourcesDirectory)\build\scripts\UpdateAppxManifestVersion.ps1
|
||||||
|
arguments: '-AppxManifest $(Build.SourcesDirectory)\src\Calculator\Package.appxmanifest -Version $(Build.BuildNumber)'
|
||||||
|
|
||||||
|
- task: VSBuild@1
|
||||||
|
displayName: 'Build solution src/Calculator.sln'
|
||||||
|
inputs:
|
||||||
|
solution: src/Calculator.sln
|
||||||
|
vsVersion: 15.0
|
||||||
|
msbuildArgs: /bl:$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator.binlog /p:OutDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\ /p:GenerateProjectSpecificOutputFolder=true /p:AppVersion=$(Build.BuildNumber) ${{ parameters.extraMsBuildArgs }}
|
||||||
|
platform: $(BuildPlatform)
|
||||||
|
configuration: $(BuildConfiguration)
|
||||||
|
clean: true
|
||||||
|
maximumCpuCount: true
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish drop artifact
|
||||||
|
inputs:
|
||||||
|
artifactName: drop
|
||||||
|
pathToPublish: $(Build.BinariesDirectory)
|
||||||
|
parallel: true
|
||||||
|
|
||||||
|
- task: PublishSymbols@2
|
||||||
|
displayName: Publish symbols
|
||||||
|
inputs:
|
||||||
|
symbolsFolder: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)
|
||||||
|
searchPattern: '**/*.pdb'
|
||||||
|
symbolServerType: teamServices
|
||||||
|
treatNotIndexedAsWarning: true
|
||||||
|
symbolsArtifactName: $(System.teamProject)/$(Build.BuildNumber)_$(BuildPlatform)$(BuildConfiguration)
|
61
build/pipelines/templates/package-appxbundle.yaml
Normal file
61
build/pipelines/templates/package-appxbundle.yaml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# This template contains a job which takes .appx packages which were built separately for each
|
||||||
|
# architecture (arm, x86, etc.) and combines them into a single .appxbundle.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Package
|
||||||
|
dependsOn:
|
||||||
|
- Buildx64
|
||||||
|
- Buildx86
|
||||||
|
- BuildARM
|
||||||
|
- BuildARM64
|
||||||
|
condition: |
|
||||||
|
and
|
||||||
|
(
|
||||||
|
in(dependencies.Buildx64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||||
|
in(dependencies.Buildx86.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||||
|
in(dependencies.BuildARM.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||||
|
in(dependencies.BuildARM64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
|
||||||
|
)
|
||||||
|
pool:
|
||||||
|
name: Package ES Custom Demands Lab A
|
||||||
|
demands:
|
||||||
|
- msbuild
|
||||||
|
- visualstudio
|
||||||
|
- ClientAlias -equals PKGESUTILAPPS
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
- task: DownloadBuildArtifacts@0
|
||||||
|
displayName: Download all .appx artifacts
|
||||||
|
inputs:
|
||||||
|
artifactName: drop
|
||||||
|
itemPattern: '**/*.appx'
|
||||||
|
|
||||||
|
- task: PowerShell@2
|
||||||
|
displayName: Generate AppxBundle mapping
|
||||||
|
inputs:
|
||||||
|
filePath: $(Build.SourcesDirectory)\build\scripts\CreateAppxBundleMapping.ps1
|
||||||
|
arguments: '-InputPath $(Build.ArtifactStagingDirectory)\drop\Release -ProjectName Calculator -OutputFile $(Build.BinariesDirectory)\AppxBundleMapping.txt'
|
||||||
|
|
||||||
|
- script: '"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\MakeAppx.exe" bundle /v /bv %BUNDLEVERSION% /f %MAPPINGFILEPATH% /p %OUTPUTPATH%'
|
||||||
|
displayName: Make AppxBundle
|
||||||
|
env:
|
||||||
|
BUNDLEVERSION: $(Build.BuildNumber)
|
||||||
|
MAPPINGFILEPATH: $(Build.BinariesDirectory)\AppxBundleMapping.txt
|
||||||
|
OUTPUTPATH: $(Build.BinariesDirectory)\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||||
|
|
||||||
|
- task: CopyFiles@2
|
||||||
|
displayName: Copy AppxBundle to staging directory
|
||||||
|
inputs:
|
||||||
|
sourceFolder: $(Build.BinariesDirectory)
|
||||||
|
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||||
|
targetFolder: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish AppxBundle artifact
|
||||||
|
inputs:
|
||||||
|
artifactName: appxBundle
|
||||||
|
pathToPublish: $(Build.ArtifactStagingDirectory)\appxBundle
|
111
build/pipelines/templates/prepare-release-internalonly.yaml
Normal file
111
build/pipelines/templates/prepare-release-internalonly.yaml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
# This template contains a job which builds artifacts needed to release the app to the store and to
|
||||||
|
# Windows using Microsoft-internal systems. It relies Microsoft-internal resources and will not
|
||||||
|
# work outside of Microsoft.
|
||||||
|
# Specifically, this job:
|
||||||
|
# - Signs the bundle using a secure system. If you want to build your own, use SignTool following
|
||||||
|
# the example in the continuous integration pipeline.
|
||||||
|
# - Builds VPacks for including the app in the Windows OS build. Azure DevOps Universal Packages
|
||||||
|
# offers similar capabilities.
|
||||||
|
# - Creates StoreBroker packages containing Microsoft Store assets. Although the Store assets for
|
||||||
|
# this app are not open source, the StoreBroker tool is available at
|
||||||
|
# https://github.com/Microsoft/StoreBroker.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: WindowsInternalRelease
|
||||||
|
dependsOn: Package
|
||||||
|
pool:
|
||||||
|
name: Package ES Custom Demands Lab A
|
||||||
|
demands:
|
||||||
|
- ClientAlias -equals PKGESUTILAPPS
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
# This must be the first task in the job definition, since it modifies the build environment
|
||||||
|
# in ways other tasks would not expect (for example, it clears the artifacts directory).
|
||||||
|
- task: PkgESSetupBuild@10
|
||||||
|
displayName: Initialize Package ES
|
||||||
|
inputs:
|
||||||
|
productName: Calculator
|
||||||
|
disableWorkspace: true
|
||||||
|
env:
|
||||||
|
XES_DISABLEPROV: true
|
||||||
|
|
||||||
|
- task: DownloadBuildArtifacts@0
|
||||||
|
displayName: Download appxBundle artifact
|
||||||
|
inputs:
|
||||||
|
artifactName: appxBundle
|
||||||
|
|
||||||
|
- task: PkgESCodeSign@10
|
||||||
|
displayName: Send bundle to Package ES code signing service
|
||||||
|
inputs:
|
||||||
|
signConfigXml: build\config\SignConfig.xml
|
||||||
|
inPathRoot: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||||
|
outPathRoot: $(Build.ArtifactStagingDirectory)\appxBundleSigned
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish AppxBundleSigned artifact
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: $(Build.ArtifactStagingDirectory)\appxBundleSigned
|
||||||
|
artifactName: AppxBundleSigned
|
||||||
|
|
||||||
|
- task: CopyFiles@2
|
||||||
|
displayName: Copy signed AppxBundle to vpack staging folder
|
||||||
|
inputs:
|
||||||
|
sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned
|
||||||
|
targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
|
||||||
|
|
||||||
|
- task: PkgESVPack@10
|
||||||
|
displayName: Create and push vpack for app
|
||||||
|
env:
|
||||||
|
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||||
|
inputs:
|
||||||
|
sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
|
||||||
|
description: VPack for the Calculator Application
|
||||||
|
pushPkgName: calculator.app
|
||||||
|
version: $(versionMajor).$(versionMinor).$(versionBuild)
|
||||||
|
owner: paxeeapps
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish vpack\app artifact with vpack manifest
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME)
|
||||||
|
artifactName: vpack\app
|
||||||
|
|
||||||
|
# TODO (macool): create and push internal test packages and test config
|
||||||
|
|
||||||
|
- task: UniversalPackages@0
|
||||||
|
displayName: Download internals package
|
||||||
|
inputs:
|
||||||
|
command: download
|
||||||
|
downloadDirectory: $(Build.SourcesDirectory)
|
||||||
|
vstsFeed: WindowsApps
|
||||||
|
vstsFeedPackage: calculator-internals
|
||||||
|
vstsPackageVersion: 0.0.7
|
||||||
|
|
||||||
|
- task: PkgESStoreBrokerPackage@10
|
||||||
|
displayName: Create StoreBroker Packages
|
||||||
|
env:
|
||||||
|
XES_SERIALPOSTBUILDREADY: True
|
||||||
|
inputs:
|
||||||
|
addToFlight: false
|
||||||
|
configPath: tools/Build/StoreBroker/SBCalculatorConfig.json
|
||||||
|
PDPRootPath: $(Build.SourcesDirectory)\PDP
|
||||||
|
imagesRootPath: $(Build.SourcesDirectory)\PDPMediaRoot
|
||||||
|
appxPath: $(Build.ArtifactStagingDirectory)\appxBundleSigned\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||||
|
useArtifactServiceForMedia: true
|
||||||
|
outPath: $(Build.ArtifactStagingDirectory)\StoreBrokerPayload
|
||||||
|
paToken: $(System.AccessToken)
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish StoreBrokerPayload artifact
|
||||||
|
inputs:
|
||||||
|
artifactName: storeBrokerPayload
|
||||||
|
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload
|
||||||
|
|
||||||
|
- task: PkgESLateTasks@10
|
||||||
|
displayName: Run PackageES LateTasks
|
||||||
|
env:
|
||||||
|
XES_DISABLEPROV: true
|
54
build/pipelines/templates/run-unit-tests.yaml
Normal file
54
build/pipelines/templates/run-unit-tests.yaml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# This template contains jobs to run unit tests on the interactive test agents.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
platform: ''
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: UnitTests${{ parameters.platform }}
|
||||||
|
displayName: UnitTests ${{ parameters.platform }}
|
||||||
|
dependsOn: Build${{ parameters.platform }}
|
||||||
|
pool:
|
||||||
|
name: Essential Experiences Interactive
|
||||||
|
workspace:
|
||||||
|
clean: outputs
|
||||||
|
steps:
|
||||||
|
- checkout: none
|
||||||
|
|
||||||
|
- powershell: Write-Host "##vso[task.setvariable variable=agentInstanceId;isOutput=true]$($env:AgentName -replace '\D+' -as [int])"
|
||||||
|
name: LogAgentStep
|
||||||
|
displayName: Log this agent's instance for later cleanup
|
||||||
|
env:
|
||||||
|
AgentName: $(Agent.Name)
|
||||||
|
|
||||||
|
- task: DownloadBuildArtifacts@0
|
||||||
|
displayName: Download CalculatorUnitTests
|
||||||
|
inputs:
|
||||||
|
artifactName: drop
|
||||||
|
itemPattern: drop/Release/${{ parameters.platform }}/CalculatorUnitTests_VS/AppPackages/CalculatorUnitTests_Test/**
|
||||||
|
|
||||||
|
- task: PowerShell@2
|
||||||
|
displayName: Install Certificate
|
||||||
|
inputs:
|
||||||
|
filePath: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\Add-AppDevPackage.ps1
|
||||||
|
arguments: -CertificatePath $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.cer -Force
|
||||||
|
|
||||||
|
- task: VSTest@2
|
||||||
|
displayName: Run CalculatorUnitTests
|
||||||
|
inputs:
|
||||||
|
testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx
|
||||||
|
otherConsoleOptions: /Platform:${{ parameters.platform }}
|
||||||
|
|
||||||
|
- job: CleanUpUnitTests${{ parameters.platform }}
|
||||||
|
dependsOn: UnitTests${{ parameters.platform }}
|
||||||
|
condition: and(always(), ne(dependencies.UnitTests${{ parameters.platform }}.Outputs['LogAgentStep.agentInstanceId'], ''))
|
||||||
|
pool: server
|
||||||
|
variables:
|
||||||
|
agentInstanceId: $[ dependencies.UnitTests${{ parameters.platform }}.outputs['LogAgentStep.agentInstanceId'] ]
|
||||||
|
steps:
|
||||||
|
- task: InvokeRESTAPI@1
|
||||||
|
displayName: Reimage test machine
|
||||||
|
inputs:
|
||||||
|
connectionType: connectedServiceNameARM
|
||||||
|
azureServiceConnection: macool-sandbox-interactiveDesktopRS5
|
||||||
|
urlSuffix: subscriptions/012a8008-c00f-45b3-9828-41ebba30141d/resourceGroups/interactiveDesktopRS5/providers/Microsoft.Compute/virtualMachineScaleSets/essential/reimage?api-version=2018-10-01
|
||||||
|
body: '{ "instanceIds": ["$(agentInstanceId)"] }'
|
98
build/scripts/CreateAppxBundleMapping.ps1
Normal file
98
build/scripts/CreateAppxBundleMapping.ps1
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
# Licensed under the MIT License.
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Generates a mapping file to be used with the MakeAppx tool. It generates the file based on
|
||||||
|
a folder structure grouped by architecture then by project, like this example:
|
||||||
|
|
||||||
|
drop\
|
||||||
|
ARM\
|
||||||
|
Project\
|
||||||
|
AppPackages\
|
||||||
|
Project_ARM.appx
|
||||||
|
Project_scale-100.appx
|
||||||
|
x64\
|
||||||
|
Project\
|
||||||
|
AppPackages\
|
||||||
|
Project_x64.appx
|
||||||
|
Project_scale-100.appx
|
||||||
|
|
||||||
|
.PARAMETER InputPath
|
||||||
|
The path where appx packages to bundle are located.
|
||||||
|
|
||||||
|
.PARAMETER ProjectName
|
||||||
|
The folder name within each architecture to search recursively for appx packages. The appx files
|
||||||
|
must also have the ProjectName in their file names.
|
||||||
|
|
||||||
|
.PARAMETER OutputFile
|
||||||
|
The path to write the generated mapping file.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Create-AppxBundleMapping -InputPath "C:\drop" -ProjectName "CalculatorApp" -OutputFile "C:\Temp\AppxBundleMapping.txt"
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]
|
||||||
|
$InputPath,
|
||||||
|
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]
|
||||||
|
$ProjectName,
|
||||||
|
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]
|
||||||
|
$OutputFile
|
||||||
|
)
|
||||||
|
|
||||||
|
# List all appx packages by architecture
|
||||||
|
$architectures = @(Get-ChildItem -Path $InputPath -Directory | Foreach-Object Name | Foreach-Object ToLower)
|
||||||
|
if ($architectures.Count -lt 1)
|
||||||
|
{
|
||||||
|
throw "No architecture-specific folders found in $InputPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaultArchitecture = $architectures[0]
|
||||||
|
$packages = @{}
|
||||||
|
foreach ($architecture in $architectures)
|
||||||
|
{
|
||||||
|
$projectPath = [IO.Path]::Combine($InputPath, $architecture, $ProjectName)
|
||||||
|
$packages[$architecture] = Get-ChildItem -Path $projectPath -Recurse -Filter *$ProjectName*.appx
|
||||||
|
|
||||||
|
if ($packages[$architecture].Count -lt 1)
|
||||||
|
{
|
||||||
|
throw "No .appx files found for architecture $architecture in $projectPath"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# List appx packages which are common to all architectures
|
||||||
|
$commonPackages = $packages[$defaultArchitecture]
|
||||||
|
foreach ($architecture in $architectures)
|
||||||
|
{
|
||||||
|
$commonPackages = $packages[$architecture] | Where {$commonPackages.Name -Contains $_.Name}
|
||||||
|
}
|
||||||
|
|
||||||
|
# List appx packages which are architecture-specific and verify that there is exactly one per
|
||||||
|
# architecture.
|
||||||
|
$architectureSpecificPackages = @()
|
||||||
|
if ($architectures.Count -gt 1)
|
||||||
|
{
|
||||||
|
foreach ($architecture in $architectures)
|
||||||
|
{
|
||||||
|
$uniquePackages = $packages[$architecture] | Where {$commonPackages.Name -NotContains $_.Name}
|
||||||
|
if ($uniquePackages.Count -ne 1)
|
||||||
|
{
|
||||||
|
throw "Found multiple architecture-specific packages for architecture $($architecture): $($uniquePackages.Name)"
|
||||||
|
}
|
||||||
|
$architectureSpecificPackages += $uniquePackages[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write the mapping file
|
||||||
|
Set-Content $OutputFile "[Files]"
|
||||||
|
foreach ($package in ($architectureSpecificPackages + $commonPackages))
|
||||||
|
{
|
||||||
|
$mapping = "`"$($package.FullName)`" `"$($package.Name)`""
|
||||||
|
Write-Host $mapping
|
||||||
|
Add-Content $OutputFile $mapping
|
||||||
|
}
|
31
build/scripts/UpdateAppxManifestVersion.ps1
Normal file
31
build/scripts/UpdateAppxManifestVersion.ps1
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
# Licensed under the MIT License.
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Updates the version number in an AppxManifest file.
|
||||||
|
|
||||||
|
.PARAMETER AppxManifest
|
||||||
|
The path to the AppxManifest file.
|
||||||
|
|
||||||
|
.PARAMETER Version
|
||||||
|
The version number to write into the file.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Update-AppxManifestVersion -AppxManifest "C:\App\Package.appxmanifest" -Version "3.2.1.0"
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[ValidateScript({Test-Path $_ -PathType 'Leaf'})]
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]
|
||||||
|
$AppxManifest,
|
||||||
|
|
||||||
|
[ValidateScript({[version]$_})]
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]
|
||||||
|
$Version
|
||||||
|
)
|
||||||
|
|
||||||
|
$xmlDoc = [XML](Get-Content $AppxManifest)
|
||||||
|
$xmlDoc.Package.Identity.setAttribute("Version", $Version);
|
||||||
|
$xmlDoc.Save($AppxManifest)
|
188
docs/ApplicationArchitecture.md
Normal file
188
docs/ApplicationArchitecture.md
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
# Application Architecture
|
||||||
|
|
||||||
|
Windows Calculator is a [C++/CX][C++/CX] application, built for the Universal Windows Platform ([UWP][What is UWP?]).
|
||||||
|
Calculator uses the [XAML][XAML Overview] UI framework, and the project follows the Model-View-ViewModel ([MVVM][MVVM])
|
||||||
|
design pattern. This document discusses each of the layers and how they are related to the three Visual Studio projects
|
||||||
|
that build into the final Calculator application.
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
* [View](#view)
|
||||||
|
* [VisualStates](#visualstates)
|
||||||
|
* [Data-Binding](#data-binding)
|
||||||
|
* [ViewModel](#viewmodel)
|
||||||
|
* [PropertyChanged Events](#propertychanged-events)
|
||||||
|
* [Model](#model)
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
## View
|
||||||
|
|
||||||
|
The View layer is contained in the [Calculator project][Calculator folder]. This project contains mostly XAML files
|
||||||
|
and various custom controls that support the UI. [App.xaml][App.xaml] contains many of the [static][StaticResource] and
|
||||||
|
[theme][ThemeResource] resources that the other XAML files will reference. Its code-behind file, [App.xaml.cpp][App.xaml.cpp],
|
||||||
|
contains the main entry point to the application. On startup, it navigates to the main page.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
rootFrame->Navigate(MainPage::typeid, argument)
|
||||||
|
```
|
||||||
|
|
||||||
|
In Calculator, there is only one concrete [Page][Page] class: [MainPage.xaml][MainPage.xaml]. `MainPage` is the root
|
||||||
|
container for all the other application UI elements. As you can see, there's not much content. `MainPage` uses a
|
||||||
|
`NavigationView` control to display the toggleable navigation menu, and empty containers for delay-loaded UI elements.
|
||||||
|
Of the many modes that Calculator shows in its menu, there are actually only three XAML files that `MainPage` needs to
|
||||||
|
manage in order to support all modes. They are:
|
||||||
|
|
||||||
|
* [Calculator.xaml][Calculator.xaml]: This [UserControl] is itself a container for the [Standard][CalculatorStandardOperators.xaml],
|
||||||
|
[Scientific][CalculatorScientificOperators.xaml], and [Programmer][CalculatorProgrammerOperators.xaml] modes.
|
||||||
|
* [DateCalculator.xaml][DateCalculator.xaml]: Everything needed for the DateCalculator mode.
|
||||||
|
* [UnitConverter.xaml][UnitConverter.xaml]: One `UserControl` to support every Converter mode.
|
||||||
|
|
||||||
|
### VisualStates
|
||||||
|
|
||||||
|
[VisualStates][VisualState] are used to change the size, position, and appearance ([Style][Style]) of UI elements
|
||||||
|
in order to create an adaptive, responsive UI. A transition to a new `VisualState` is often triggered by specific
|
||||||
|
window sizes. Here are a few important examples of `VisualStates` in Calculator. Note that it is not a
|
||||||
|
complete list. When making UI changes, make sure you are considering the various `VisualStates` and layouts that
|
||||||
|
Calculator defines.
|
||||||
|
|
||||||
|
#### History/Memory Dock Panel expansion
|
||||||
|
|
||||||
|
In the Standard, Scientific, and Programmer modes, the History/Memory panel is exposed as a flyout in small window sizes.
|
||||||
|
Once the window is resized to have enough space, the panel becomes docked along the edge of the window.
|
||||||
|
|
||||||
|
<img src="Images\VisualStates\Standard1.gif" height="400" />
|
||||||
|
|
||||||
|
#### Scientific mode, inverse function button presence
|
||||||
|
|
||||||
|
In the Scientific mode, for small window sizes there is not enough room to show all the function buttons. The mode
|
||||||
|
hides some of the buttons and provides a Shift (↑) button to toggle the visibility of the collapsed rows. When the
|
||||||
|
window size is large enough, the buttons are re-arranged to display all function buttons at the same time.
|
||||||
|
|
||||||
|
<img src="Images\VisualStates\Scientific1.gif" height="400" />
|
||||||
|
|
||||||
|
#### Unit Converter aspect ratio adjustment
|
||||||
|
|
||||||
|
In the Unit Converter mode, the converter inputs and the numberpad will re-arrange depending on if the window is in
|
||||||
|
a Portrait or Landscape aspect ratio.
|
||||||
|
|
||||||
|
<img src="Images\VisualStates\Converter1.gif" height="400" />
|
||||||
|
|
||||||
|
### Data-Binding
|
||||||
|
|
||||||
|
Calculator uses [data binding][Data Binding] to dynamically update the properties of UI elements. If this concept
|
||||||
|
is new for you, it's also worth reading about [data binding in depth][Data binding in depth].
|
||||||
|
|
||||||
|
The [x:Bind][x:Bind] markup extension is a newer replacement for the older [Binding][Binding] style. You may see both
|
||||||
|
styles in the Calculator codebase. Prefer `x:Bind` in new contributions because it has better performance. If you need
|
||||||
|
to add or modify an existing `Binding`, updating to `x:Bind` is a great first step. Make sure to read and understand
|
||||||
|
the difference between the two styles, as there are some subtle behavioral changes. Refer to the
|
||||||
|
[binding feature comparison][BindingComparison] to learn more.
|
||||||
|
|
||||||
|
------------
|
||||||
|
## ViewModel
|
||||||
|
|
||||||
|
The ViewModel layer is contained in the [CalcViewModel][CalcViewModel folder] project. ViewModels provide a source of
|
||||||
|
data for the UI to bind against and act as the intermediary separating pure business logic from UI components that
|
||||||
|
should not care about the model's implementation. Just as the View layer consists of a hierarchy of XAML files, the
|
||||||
|
ViewModel consists of a hierarchy of ViewModel files. The relationship between XAML and ViewModel files is often 1:1.
|
||||||
|
Here are the noteable ViewModel files to start exploring with:
|
||||||
|
|
||||||
|
* [ApplicationViewModel.h][ApplicationViewModel.h]: The ViewModel for [MainPage.xaml][MainPage.xaml]. This ViewModel
|
||||||
|
is the root of the other mode-specific ViewModels. The application changes between modes by updating the `Mode` property
|
||||||
|
of the `ApplicationViewModel`. The ViewModel will make sure the appropriate ViewModel for the new mode is initialized.
|
||||||
|
* [StandardCalculatorViewModel.h][StandardCalculatorViewModel.h]: The ViewModel for [Calculator.xaml][Calculator.xaml].
|
||||||
|
This ViewModel exposes functionality for the main three Calculator modes: Standard, Scientific, and Programmer.
|
||||||
|
* [DateCalculatorViewModel.h][DateCalculatorViewModel.h]: The ViewModel for [DateCalculator.xaml][DateCalculator.xaml].
|
||||||
|
* [UnitConverterViewModel.h][UnitConverterViewModel.h]: The ViewModel for [UnitConverter.xaml][UnitConverter.xaml].
|
||||||
|
This ViewModel implements the logic to support every converter mode, including Currency Converter.
|
||||||
|
|
||||||
|
### PropertyChanged Events
|
||||||
|
|
||||||
|
In order for [data binding](#data-binding) to work, ViewModels need a way to inform the XAML framework about
|
||||||
|
updates to their member properties. Most ViewModels in the project do so by implementing the
|
||||||
|
[INotifyPropertyChanged][INotifyPropertyChanged] interface. The interface requires that the class provides a
|
||||||
|
[PropertyChanged event][PropertyChanged]. Clients of the ViewModel (such as the UI), can register for the
|
||||||
|
`PropertyChanged` event from the ViewModel, then re-evaluate bindings or handle the event in code-behind when the
|
||||||
|
ViewModel decides to raise the event. ViewModels in the Calculator codebase generally uses a macro, defined in the
|
||||||
|
[Utils.h][Utils.h] utility file, to implement the `INotifyPropertyChanged` interface. Here is a standard
|
||||||
|
implementation, taken from [ApplicationViewModel.h][ApplicationViewModel.h].
|
||||||
|
|
||||||
|
```C++
|
||||||
|
[Windows::UI::Xaml::Data::Bindable]
|
||||||
|
public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApplicationViewModel();
|
||||||
|
|
||||||
|
OBSERVABLE_OBJECT();
|
||||||
|
```
|
||||||
|
|
||||||
|
The `OBSERVABLE_OBJECT()` macro defines the required `PropertyChanged` event. It also defines a private
|
||||||
|
`RaisePropertyChanged` helper function for the class. The function takes a property name and raises a
|
||||||
|
`PropertyChanged` event for that property.
|
||||||
|
|
||||||
|
Properties that are intended to be the source for a data binding are also typically implemented with a macro. Here is
|
||||||
|
one such property from `ApplicationViewModel`:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
OBSERVABLE_PROPERTY_RW(Platform::String^, CategoryName);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `OBSERVABLE_PROPERTY_RW` macro defines a Read/Write property that will raise a `PropertyChanged` event if its value
|
||||||
|
changes. Read/Write means the property exposes both a public getter and setter. For efficiency and to avoid raising
|
||||||
|
unnecessary `PropertyChanged` events, the setter for these types of properties will check if the new value is
|
||||||
|
different from the previous value before raising the event.
|
||||||
|
|
||||||
|
From this example, either `ApplicationViewModel` or clients of the class can simply assign to the `CategoryName`
|
||||||
|
property and a `PropertyChanged` event will be raised, allowing the UI to respond to the new `CategoryName` value.
|
||||||
|
|
||||||
|
--------
|
||||||
|
## Model
|
||||||
|
|
||||||
|
The Model for the Calculator modes is contained in the [CalcManager][CalcManager folder] project.
|
||||||
|
<!-- TODO joshuako: Add the docs -->
|
||||||
|
|
||||||
|
[References]:####################################################################################################
|
||||||
|
|
||||||
|
[C++/CX]: https://docs.microsoft.com/en-us/cpp/cppcx/visual-c-language-reference-c-cx
|
||||||
|
[What is UWP?]: https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide
|
||||||
|
[XAML Overview]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/xaml-overview
|
||||||
|
[MVVM]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
|
||||||
|
|
||||||
|
[Calculator folder]: ..\src\Calculator
|
||||||
|
[App.xaml]: ..\src\Calculator\App.xaml
|
||||||
|
[App.xaml.cpp]: ..\src\Calculator\App.xaml.cpp
|
||||||
|
[StaticResource]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/staticresource-markup-extension
|
||||||
|
[ThemeResource]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/themeresource-markup-extension
|
||||||
|
[Page]: https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.Page
|
||||||
|
[UserControl]: https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.UserControl
|
||||||
|
[MainPage.xaml]: ..\src\Calculator\Views\MainPage.xaml
|
||||||
|
[Calculator.xaml]: ..\src\Calculator\Views\Calculator.xaml
|
||||||
|
[CalculatorStandardOperators.xaml]: ..\src\Calculator\Views\CalculatorStandardOperators.xaml
|
||||||
|
[CalculatorScientificOperators.xaml]: ..\src\Calculator\Views\CalculatorScientificOperators.xaml
|
||||||
|
[CalculatorProgrammerOperators.xaml]: ..\src\Calculator\Views\CalculatorProgrammerOperators.xaml
|
||||||
|
[DateCalculator.xaml]: ..\src\Calculator\Views\DateCalculator.xaml
|
||||||
|
[UnitConverter.xaml]: ..\src\Calculator\Views\UnitConverter.xaml
|
||||||
|
|
||||||
|
[VisualState]: https://docs.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#adaptive-layouts-with-visual-states-and-state-triggers
|
||||||
|
[Style]: https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles
|
||||||
|
|
||||||
|
[Data Binding]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
|
||||||
|
[Data binding in depth]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
|
||||||
|
[x:Bind]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
|
||||||
|
[Binding]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/binding-markup-extension
|
||||||
|
[BindingComparison]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth#xbind-and-binding-feature-comparison
|
||||||
|
|
||||||
|
[CalcViewModel folder]: ..\src\CalcViewModel
|
||||||
|
[ApplicationViewModel.h]: ..\src\CalcViewModel\ApplicationViewModel.h
|
||||||
|
[StandardCalculatorViewModel.h]: ..\src\CalcViewModel\StandardCalculatorViewModel.h
|
||||||
|
[DateCalculatorViewModel.h]: ..\src\CalcViewModel\DateCalculatorViewModel.h
|
||||||
|
[UnitConverterViewModel.h]: ..\src\CalcViewModel\UnitConverterViewModel.h
|
||||||
|
|
||||||
|
[INotifyPropertyChanged]: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.data.inotifypropertychanged
|
||||||
|
[PropertyChanged]: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.data.inotifypropertychanged.propertychanged
|
||||||
|
[Utils.h]: ..\src\CalcViewModel\Common\Utils.h
|
||||||
|
|
||||||
|
[CalcManager folder]: ..\src\CalcManager
|
BIN
docs/Images/CalculatorScreenshot.png
Normal file
BIN
docs/Images/CalculatorScreenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
docs/Images/VSInstallationScreenshot.png
Normal file
BIN
docs/Images/VSInstallationScreenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
BIN
docs/Images/VisualStates/Converter1.gif
Normal file
BIN
docs/Images/VisualStates/Converter1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 MiB |
BIN
docs/Images/VisualStates/Scientific1.gif
Normal file
BIN
docs/Images/VisualStates/Scientific1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 MiB |
BIN
docs/Images/VisualStates/Standard1.gif
Normal file
BIN
docs/Images/VisualStates/Standard1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 MiB |
353
docs/ManualTests.md
Normal file
353
docs/ManualTests.md
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
# Calculator Manual Tests
|
||||||
|
These manual tests are run before every release of the Calculator app.
|
||||||
|
|
||||||
|
## Smoke Tests
|
||||||
|
|
||||||
|
### Calculators
|
||||||
|
|
||||||
|
### Math in Standard Calculator
|
||||||
|
|
||||||
|
**Test 1**
|
||||||
|
Steps:
|
||||||
|
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
|
||||||
|
Expected: “6” shows up in the display
|
||||||
|
2. Input “4”, “-“, “2”, “=” using the in-app buttons
|
||||||
|
*Expected: “2” shows up in the display*
|
||||||
|
|
||||||
|
**Test 2**
|
||||||
|
Steps:
|
||||||
|
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
|
||||||
|
2. Navigate to the History pane, and verify that “3 + 3 = 6” shows up in the pane
|
||||||
|
3. Input “MS” using the in-app buttons
|
||||||
|
4. Navigate to the Memory pane
|
||||||
|
*Expected: “6” shows up in the pane*
|
||||||
|
|
||||||
|
### Math in Scientific Calculator
|
||||||
|
|
||||||
|
**Test 1**
|
||||||
|
Steps:
|
||||||
|
1. From the Scientific Calculator page, input “3”, “^”, “3”, “Enter” on the keyboard
|
||||||
|
*Expected: “27” shows up in the display*
|
||||||
|
|
||||||
|
**Test 2**
|
||||||
|
Steps:
|
||||||
|
1. Input “5”, “n!“, “=” using the in-app buttons
|
||||||
|
*Expected: “120” shows up in the display*
|
||||||
|
|
||||||
|
### Math in Programmer Calculator
|
||||||
|
|
||||||
|
**Test 1**
|
||||||
|
Steps:
|
||||||
|
1. From the Programmer Calculator page, input “1”, “&”, “0”, “Enter” on the keyboard
|
||||||
|
*Expected: “0” shows up in the display*
|
||||||
|
|
||||||
|
**Test 2**
|
||||||
|
Steps:
|
||||||
|
1. Input “15” using the in-app buttons and select “HEX”
|
||||||
|
*Expected: “F” shows up in the display and the letters A-F show up as in-app buttons*
|
||||||
|
|
||||||
|
### Converters
|
||||||
|
|
||||||
|
**Converter Usage**
|
||||||
|
Steps:
|
||||||
|
1. From the Length Converter page, select “kilometers” as the unit type in the input field and input “5” using the keyboard
|
||||||
|
2. Select “miles” as the unit type in the output field
|
||||||
|
*Expected: The output starts with is “3.106856”*
|
||||||
|
|
||||||
|
|
||||||
|
## Basic Verification Tests
|
||||||
|
|
||||||
|
**Launch App Test**
|
||||||
|
Steps:
|
||||||
|
1. Press the Windows key.
|
||||||
|
2. Navigate to "all apps".
|
||||||
|
3. Look for "Calculator".
|
||||||
|
4. Click to launch the "Calculator" app.
|
||||||
|
*Expected: The calculator app launches gracefully.*
|
||||||
|
|
||||||
|
|
||||||
|
**All Calculators Test: Verify All Numbers & Input Methods**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Standard" Calculator.
|
||||||
|
3. Mouse Input
|
||||||
|
*Expected: All numbers work via mouse click.*
|
||||||
|
4. Keyboard Input:
|
||||||
|
*Expected: All numbers work via number pad.*
|
||||||
|
5. Navigate to "Scientific" Calculator and Repeat Steps 3-5
|
||||||
|
*Expected: Steps 3-5 pass in Scientific mode*
|
||||||
|
6. Navigate to "Programmer" Calculator and Repeat Steps 3-5
|
||||||
|
*Expected: Steps 3-5 pass in Programmer mode*
|
||||||
|
|
||||||
|
|
||||||
|
**All Calculators Test: Verify Basic Arithmetic Functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Standard" Calculator.
|
||||||
|
3. Using the Number Pad and Mouse perform the following arithmetic functions and verify the result.
|
||||||
|
a. (+) Addition
|
||||||
|
b. (-) Subtraction
|
||||||
|
c. (x) Multiplication
|
||||||
|
d. (÷) Division
|
||||||
|
e. (1/x) Reciprocal
|
||||||
|
f. (√) Square Root
|
||||||
|
g. (x²) Squared
|
||||||
|
h. (x³) Cubed
|
||||||
|
i. (%) Percent
|
||||||
|
j. (±) Positive / Negative
|
||||||
|
k. (=) Equals
|
||||||
|
l. Delete Button (flag with x in it)
|
||||||
|
m. [CE] Clear
|
||||||
|
n. [C] Global Clear
|
||||||
|
o. (.) Decimal
|
||||||
|
4. Navigate to "Scientific" Calculator and Repeat Steps 3-19.
|
||||||
|
5. Navigate to "Programmer" Calculator and Repeat Steps 3-18 (No Decimal in Programming Calc).
|
||||||
|
|
||||||
|
|
||||||
|
**Scientific Calculator Test: Verify advanced arithmetic functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Scientific" Calculator.
|
||||||
|
3. Using the Number Pad and Mouse perform the following arithmetic functions and verify the result.
|
||||||
|
a. (xʸ) Xth Power of Y
|
||||||
|
b. (y√x) Y Root of X
|
||||||
|
c. (10ˣ) 10 Power of X
|
||||||
|
d. (ex) E Power of X
|
||||||
|
e. (π) Pi
|
||||||
|
f. (n!) Factorial
|
||||||
|
g. (Ln) Natural Logarithm
|
||||||
|
h. (Log) Logarithm
|
||||||
|
i. (Exp) Exponential
|
||||||
|
j. (dms) Degrees, Minutes, Seconds
|
||||||
|
k. (deg) Degrees
|
||||||
|
l. (Mod) Modulo
|
||||||
|
m. “( )" Parenthesis
|
||||||
|
|
||||||
|
|
||||||
|
**All Calulators Test: Verify memory functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Standard" Calculator.
|
||||||
|
3. Perform a calculation and press the MS button.
|
||||||
|
4. If small scale, Select the (M) with the drop down arrow
|
||||||
|
*Expected: Calculation from previous step is present.*
|
||||||
|
5. Click the (M+) Add to Memory.
|
||||||
|
*Expected: Previous calculation is added to itself.*
|
||||||
|
6. Click the (M-) Subtract from Memory.
|
||||||
|
*Expected: Previous calculation is subtracted from the base calculation.*
|
||||||
|
7. Click the (MR) Memory Recall.
|
||||||
|
*Expected: Previous calculation is made primary (This is not available in the Programmer mode).*
|
||||||
|
8. Check the MC button.
|
||||||
|
*Expected: The stored information is cleared.*
|
||||||
|
9. Navigate to "Scientific" Calculator and Repeat Steps 3-8.
|
||||||
|
*Expected: All in "Scientific" mode.*
|
||||||
|
10. Navigate to "Programmer" Calculator and Repeat Steps 3-8.
|
||||||
|
*Expected: All in "Programmer" mode.*
|
||||||
|
|
||||||
|
|
||||||
|
**Scientific Calculator Test: Verify trigonometric functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Scientific" Calculator.
|
||||||
|
3. Using the Number Pad and Mouse perform the following trigonometric functions and verify the result.
|
||||||
|
3. Sine (sin)
|
||||||
|
4. Cosine (cos)
|
||||||
|
5. Tangent (tan)
|
||||||
|
6. Inverse Sine (sin-1)
|
||||||
|
7. Inverse Cosine (cos-1)
|
||||||
|
8. Inverse Tangent (tan-1) Inverse Tangent:
|
||||||
|
9. Press (HYP) for Hyperbolic trig functions:
|
||||||
|
*Expected: Trig function buttons show hyperbolic trig functions.*
|
||||||
|
10. Hyperbolic Sine (sinh)
|
||||||
|
11. Hyperbolic Tangent (tanh)
|
||||||
|
12. Hyperbolic Cosine (cosh)
|
||||||
|
13. Inverse Hyperbolic Sine (sinh-1)
|
||||||
|
14. Inverse Hyperbolic Tangent (tanh-1)
|
||||||
|
15. Inverse Hyperbolic Cosine (cosh-1)
|
||||||
|
|
||||||
|
|
||||||
|
**Programmer Calculator Test: Verify logical functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app
|
||||||
|
2. Navigate to "Programmer" Calculator.
|
||||||
|
3. Using the Number Pad and Mouse perform the following trigonometric functions and verify the result.
|
||||||
|
4. Rotate Left (RoL) Logical Operator:
|
||||||
|
01011001 rol 3 = 11001010.
|
||||||
|
5. Rotate Right (RoR) Logical Operator:
|
||||||
|
01011001 RoR 3 = 00101011.
|
||||||
|
6. (Lsh) Logical Operator:
|
||||||
|
(10 multiplied by 2 three times)
|
||||||
|
10 Lsh 3 = gives 80.
|
||||||
|
10.345 Lsh 3 = also gives 80.
|
||||||
|
7. (Rsh) Logical Operator:
|
||||||
|
(16 divided by 2 twice)
|
||||||
|
16 Rsh 2 = gives 4.
|
||||||
|
16.999 Rsh 2 = also gives 4.
|
||||||
|
7. (Or) Logical Operator
|
||||||
|
101 OR 110 = gives 111.
|
||||||
|
9. Exclusive Or (Xor) Logical Operator:
|
||||||
|
101 XOR 110 = gives 11.
|
||||||
|
9. (Not) Logical Operator
|
||||||
|
NOT 1001100111001001 =
|
||||||
|
0110011000110110.
|
||||||
|
10. (And) Logical Operator
|
||||||
|
101 AND 110 = gives 100.
|
||||||
|
11. (Mod) Logical Operator
|
||||||
|
Remainder of integer division (Modulo x)
|
||||||
|
12. "( )" Parenthesis
|
||||||
|
|
||||||
|
|
||||||
|
**All Calculators and Converters Test: Verify scaling functions and languages**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. For All Modes: While scaling in both directions to capacity
|
||||||
|
*Expected: Elements like Memory and History are shifted or integrated appropriately.*
|
||||||
|
3. In Any Mode: While at the Smallest scale, Select the Menu Button
|
||||||
|
*Expected: The menu items are scrollable with nothing overlapping.*
|
||||||
|
4. While in the Menu: Check the About Page
|
||||||
|
*Expected: Everything in the about page fits into its window*
|
||||||
|
5. For Scientific Mode: At a Larger Scale
|
||||||
|
*Expected: All buttons are present and the up arrow is grayed out.*
|
||||||
|
6. For Scientific Mode: At a Smaller Scale
|
||||||
|
*Expected: All buttons are present and the up arrow is able to be toggled.*
|
||||||
|
7. For Programmer Mode: At a Any Scale
|
||||||
|
*Expected: All buttons are present and the up arrow is able to be toggled.*
|
||||||
|
8. For Converter Mode: While Scaling
|
||||||
|
*Expected: The number pad and input areas move around each other gracefully.*
|
||||||
|
9. Changing Language: Open Settings app > Time & language > Region & language > Add a language > Select a Right to Left (RTL) language such as Hebrew > Install the associated files> Set it to the system default.
|
||||||
|
10. Set the system number format preference: Open a Run dialog (WIN + R) > type ‘intl.cpl’ > Enter > In the format dropdown list > Select Hebrew > Apply.
|
||||||
|
11. Initiating the change: Package has completed installing > Sign out > Sign in. (This change to the app may also require a reinstallation of the build)
|
||||||
|
12. Repeat Steps 2-6 again in a (RTL) language.
|
||||||
|
*Expected: No elements fall out of intended boundaries.*
|
||||||
|
|
||||||
|
|
||||||
|
**All Calculators Test: Verify toggling functions**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. For Standard & Scientific Modes: While in the Smallest scale, verify that the History Icon brings up the history panel gracefully and is displayed appropriately.
|
||||||
|
For Scientific Mode: At a Smaller Scale
|
||||||
|
Verify the following:
|
||||||
|
3. Grad / Deg / Rad
|
||||||
|
Perform a trig function
|
||||||
|
*Expected: The answer to the function is in the selected grad/deg/rad. Repeat for each of the modes.*
|
||||||
|
4. (Hyp) Hyperbolic
|
||||||
|
*Expected: Sin toggles to Sinh, Cos toggles to Cosh, Tan toggles to Tanh.*
|
||||||
|
5. (F-E key) Floating Point Notation & Scientific Notation.
|
||||||
|
*Expected: Display toggles between floating point and Scientific notation.*
|
||||||
|
For Programmer Mode
|
||||||
|
Verify the following:
|
||||||
|
6. "Bit Toggling Keypad":
|
||||||
|
*Expected: In app keypad changes to represent Bits (1s and 0s).*
|
||||||
|
7. "QWORD / DWORD / WORD / BYTE":
|
||||||
|
*Expected: Toggles as expected.*
|
||||||
|
8. "Hex" Hexadecimal:
|
||||||
|
*Expected: A B C D E F become active and user can use them. A maximum of 16 characters can be entered.*
|
||||||
|
9. "Dec" Decimal:
|
||||||
|
*Expected: A B C D E F are inactive. A maximum of 19 characters can be entered.*
|
||||||
|
10. "Oct" Octal:
|
||||||
|
*Expected: A B C D E F 8 9 are inactive. A maximum of 22 characters can be entered.*
|
||||||
|
11. "Bin" Binary:
|
||||||
|
*Expected: A B C D E F 2 3 4 5 6 7 8 9 are inactive. A maximum of 64 characters can be entered.*
|
||||||
|
|
||||||
|
|
||||||
|
**Date Calculation Test: Verify dates can be calculated.**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Date Calculation" Calculator.
|
||||||
|
3. With "Difference between dates" Selected
|
||||||
|
Change the various date input fields
|
||||||
|
*Expected: From and To reflect dates input respectively.*
|
||||||
|
5. With "Add or Subtract days" Selected
|
||||||
|
Change the various date input fields
|
||||||
|
*Expected: Verify changes made to both add and subtract reflect input respectively.*
|
||||||
|
|
||||||
|
|
||||||
|
**Currency Converter Test: Verify conversion & updating current currency rates.**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
2. Navigate to "Currency Converter" Calculator.
|
||||||
|
3. Select 2 Currency types from the dropdowns & enter a "1" into a conversion slot.
|
||||||
|
*Expected: The currency is slotted properly and converted rate matches the ratio provided under the selected currency types.*
|
||||||
|
4. Click "Updated"
|
||||||
|
*Expected: Display matches PC's date and time.*
|
||||||
|
5. After at least a minute: Select "Update rates" & Check "Updated" again:
|
||||||
|
*Expected: The "Update Rates" button changes the date and time to match the computer's current date and time.*
|
||||||
|
|
||||||
|
|
||||||
|
**All Calculators Test: Hotkeys: Verify Hot Key function.**
|
||||||
|
Steps:
|
||||||
|
1. Launch the "Calculator" app.
|
||||||
|
For All Applicable Modes:
|
||||||
|
Verify the following:
|
||||||
|
2. Press **Alt +1** to Enter "Standard" mode
|
||||||
|
*Expected: Move to "Standard" screen.*
|
||||||
|
3. Press **Alt +2** to Enter "Scientific" mode
|
||||||
|
*Expected: Move to "Scientific" screen.*
|
||||||
|
4. Press **Alt +3** to Enter "Programmer" mode
|
||||||
|
*Expected: Move to "Programming" screen.*
|
||||||
|
5. Press **Alt +4** to Enter "Date Calculation" mode
|
||||||
|
*Expected: Move to "Date Calculation" screen.*
|
||||||
|
6. Press **Ctrl +M** to Store in Memory
|
||||||
|
7. Press **Ctrl +P** to Add to Active Memory
|
||||||
|
8. Press **Ctrl +Q** to Subtract form Active Memory
|
||||||
|
9. Press **Ctrl +R** to Recall from Memory
|
||||||
|
10. Press **Ctrl +L** to Clear from Memory
|
||||||
|
11. Press **Delete** to Clear Current Input 'CE'
|
||||||
|
12. Press **Esc** to Full Clear Input 'C'
|
||||||
|
13. Press **F9** to Toggle '±'
|
||||||
|
14. Press **R** to Select '1/x'
|
||||||
|
15. Press **@** to Select '√'
|
||||||
|
16. Press **Ctrl + H** to Toggle History Panel
|
||||||
|
*Expected: Function when in small scale window.*
|
||||||
|
17. Press **Up arrow** to Move up History Panel
|
||||||
|
*Expected: Function when in small scale window.*
|
||||||
|
18. Press **Down arrow** to Move Down History Panel
|
||||||
|
*Expected: Function when in small scale window.*
|
||||||
|
19. Press **Ctrl + Shift + D** to Clear History Panel
|
||||||
|
*Expected: Function when in small scale window.*
|
||||||
|
20. Press **Spacebar** to Repeat Last Input:
|
||||||
|
Verify the following in Scientific Mode
|
||||||
|
21. Press **F3** to Select 'DEG'
|
||||||
|
22. Press **F4** to Select 'RAD'
|
||||||
|
23. Press **F5** to Select 'GRAD'
|
||||||
|
24. Press **Ctrl +G** to Select '10ˣ'
|
||||||
|
25. Press **Ctrl +Y** to Select 'y√x'
|
||||||
|
26. Press **Shift +O** to Select 'sin-1'
|
||||||
|
27. Press **Shift + S** to Select 'cos-1'
|
||||||
|
28. Press **Shift +T** to Select 'tan-1'
|
||||||
|
29. Press **Ctrl +O** to Select 'Cosh'
|
||||||
|
30. Press **Ctrl +S** to Select 'Sinh'
|
||||||
|
31. Press **Ctrl +T** to Select 'Tanh'
|
||||||
|
32. Press **D** to Select 'Mod'
|
||||||
|
33. Press **L** to Select 'log'
|
||||||
|
34. Press **M** to Select 'dms'
|
||||||
|
35. Press **N** to Select 'ln'
|
||||||
|
36. Press **Ctrl +N** to Select 'ex'
|
||||||
|
37. Press **O** to Select 'Cos'
|
||||||
|
38. Press **P** to Select 'π'
|
||||||
|
39. Press **Q** to Select 'x²'
|
||||||
|
40. Press **S** to Select 'Sin'
|
||||||
|
41. Press **T** to Select 'Tan'
|
||||||
|
42. Press **V** to Toggle 'F-E'
|
||||||
|
43. Press **X** to Select 'Exp'
|
||||||
|
44. Press **Y** or **^** to Select 'xʸ'
|
||||||
|
45. Press **#** to Select 'x³'
|
||||||
|
46. Press **!** to Select 'n!'
|
||||||
|
Verify the following in Programmer Mode
|
||||||
|
47. Press **F2** to Select 'DWORD'
|
||||||
|
48. Press **F3** to Select 'WORD'
|
||||||
|
49. Press **F4** to Select 'BYTE'
|
||||||
|
50. Press **F5** to Select 'HEX'
|
||||||
|
51. Press **F6** to Select 'DEC'
|
||||||
|
52. Press **F7** to Select 'OCT'
|
||||||
|
53. Press **F8** to Select 'BIN'
|
||||||
|
54. Press **F12** to Select 'QWORD'
|
||||||
|
55. Press **A-F** to Input in HEX
|
||||||
|
56. Press **J** to Select 'RoL'
|
||||||
|
57. Press **K** to Select 'RoR'
|
||||||
|
58. Press **<** to Select 'Lsh'
|
||||||
|
59. Press **>** to Select 'Rsh'
|
||||||
|
60. Press **%** to Select 'Mod'
|
||||||
|
61. Press ** | ** to Select 'Or'
|
||||||
|
62. Press **~** to Select 'Not'
|
||||||
|
63. Press **&** to Select 'And'
|
149
docs/NewFeatureProcess.md
Normal file
149
docs/NewFeatureProcess.md
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
# New feature process
|
||||||
|
|
||||||
|
## When should I follow this process?
|
||||||
|
You need to follow this process for any change which "users will notice". This applies especially
|
||||||
|
to new features and major visual changes.
|
||||||
|
|
||||||
|
You do not need to follow this process for bug fixes, performance improvements, or changes to the
|
||||||
|
development tools. To contribute these changes, discuss the issue with the team and then submit a
|
||||||
|
pull request.
|
||||||
|
|
||||||
|
## Step 1: Create an issue and discuss with the community
|
||||||
|
New features are submitted in Feedback Hub. In Feedback Hub you can upvote existing feedback or
|
||||||
|
submit your own. We also encourage discussion on open issues in Feedback Hub and in GitHub.
|
||||||
|
|
||||||
|
## Step 2: Wait for Microsoft product team sponsorship
|
||||||
|
New features must have a sponsor from the Microsoft product team. We can only work on a few ideas
|
||||||
|
at a time, so some good feature ideas might remain open but unassigned to a sponsor.
|
||||||
|
|
||||||
|
## Step 3: Scoping and feature pitch
|
||||||
|
Once we've decided to sponsor a feature, a member of the Microsoft team will write a
|
||||||
|
*feature pitch*. The feature pitch concisely describes our point of view on the problem and will
|
||||||
|
typically include these sections:
|
||||||
|
|
||||||
|
* **Problem Statement**: What problem are we trying to solve? Who’s the customer? Is there a
|
||||||
|
customer need or pain point we need to remedy? Is there a business goal or metric we are trying
|
||||||
|
to improve? Do we have a hypothesis we want to prove or disprove?
|
||||||
|
* **Evidence or User Insights**: Why should we do this? Potential sources of data: Feedback Hub,
|
||||||
|
GitHub, request from another team, telemetry data, anecdotes from listening to customers in
|
||||||
|
person, user research, market or competitive research
|
||||||
|
* **Proposal**: How will the solution/feature help us solve the problem? How will the
|
||||||
|
solution/feature meet the customer’s needs? How will the solution/feature improve the metrics?
|
||||||
|
Who’s the target audience?
|
||||||
|
* **Risks**: This section may not be necessary if covered by the problem statement. What is the
|
||||||
|
risk if we don’t do this work? What is the risk if we do?
|
||||||
|
* **Goals**: What you want to accomplish with this feature. Typical examples include
|
||||||
|
“User Can *perform some task*”
|
||||||
|
* **Non-Goals**: Things we are explicitly not doing or supporting or that are out of scope,
|
||||||
|
including any reasoning to why.
|
||||||
|
|
||||||
|
The feature pitch may also include a low-fidelity concept which will be refined during the
|
||||||
|
prototyping process.
|
||||||
|
|
||||||
|
We will edit the issue description on GitHub to include the feature pitch.
|
||||||
|
|
||||||
|
## Step 4: Prototyping
|
||||||
|
After the goals are written, we think of a variety of ways to address these goals and build
|
||||||
|
*prototypes* to try them out. We welcome community participation in this process.
|
||||||
|
|
||||||
|
Prototypes can take many forms. For many ideas, making changes directly to the app code (without
|
||||||
|
spending too much time making the code robust or maintainable) can be a fast and effective way to
|
||||||
|
try out new ideas. Or you might prefer to use design software, or even pencil and paper. Work from
|
||||||
|
low-fidelity to high-fidelity—try a few ideas for the overall approach before making your
|
||||||
|
preferred design pixel-perfect.
|
||||||
|
|
||||||
|
An important part of the prototyping process is sharing our work along the way, getting feedback,
|
||||||
|
and iterating on the design. Drawings, links to code, and other work-in-progress can be added to
|
||||||
|
the wiki for this project. Progress updates will be posted in the issues section.
|
||||||
|
|
||||||
|
During the investigation phase, we might discover that the idea isn't feasible or doesn't align
|
||||||
|
with our product roadmap. If this happens, we'll document what we learned and close the issue.
|
||||||
|
|
||||||
|
## Step 5: Prototype review
|
||||||
|
Once there is a high-fidelity design which addresses the goals described in the original pitch, the
|
||||||
|
Microsoft product team will review the prototype and ensure all items on this checklist are
|
||||||
|
addressed:
|
||||||
|
|
||||||
|
- [ ] Is there a high-fidelity design which gives reviewers a clear idea of how the feature will
|
||||||
|
look and function when implemented?
|
||||||
|
- [ ] Has the plan been shared with the community (documented on the wiki and updates posted in the
|
||||||
|
original issue) and have others been given an opportunity to provide suggestions?
|
||||||
|
- [ ] Are [Fluent design principles](https://docs.microsoft.com/en-us/windows/uwp/design/fluent-design-system/)
|
||||||
|
followed? If we do something which deviates from the guidelines, do we have a good reason?
|
||||||
|
- [ ] Does the design include provisions for [all users](https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/designing-inclusive-software)
|
||||||
|
and [all cultures](https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/guidelines-and-checklist-for-globalizing-your-app)?
|
||||||
|
- [ ] Is it technically feasible to build this feature? Take a look at the "before committing"
|
||||||
|
checklist below and identify any issues which are likely to be blockers.
|
||||||
|
|
||||||
|
## Step 6: Implementation
|
||||||
|
A feature can be implemented by the original proposer, the Microsoft team sponsor, or by other
|
||||||
|
community members. Code contributions and testing help are greatly appreciated. Please let us know
|
||||||
|
in the issue comments if you're actively working on a feature so we can ensure it's assigned to
|
||||||
|
you.
|
||||||
|
|
||||||
|
You might be able to reuse code written during the prototype process, although there will typically
|
||||||
|
be more work required to make the solution robust. Once the code is ready, you can begin
|
||||||
|
[submitting pull requests](../CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## Step 7: Technical review
|
||||||
|
As with all changes, the code for new features will be reviewed by a member of the Microsoft team
|
||||||
|
before being checked in to the master branch.
|
||||||
|
|
||||||
|
New features often need a more thorough technical review than bug fixes. When reviewing code for
|
||||||
|
new features, the Microsoft team considers at least these items:
|
||||||
|
|
||||||
|
- [ ] All items on the [Accessibility checklist](https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/accessibility-checklist)
|
||||||
|
should be addressed.
|
||||||
|
- [ ] All items on the [Globalization checklist](https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/guidelines-and-checklist-for-globalizing-your-app)
|
||||||
|
should be addressed.
|
||||||
|
- [ ] The change should be tested on the oldest version of Windows that the app supports. You can
|
||||||
|
find this version number in AppxManifest.xml. Any calls to APIs newer than that version should be
|
||||||
|
[conditionally enabled](https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/version-adaptive-apps).
|
||||||
|
- [ ] The change should use only supported APIs. If there are any questions about whether legacy or
|
||||||
|
undocumented APIs are in use, the [Windows App Certification Kit](https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/windows-app-certification-kit)
|
||||||
|
should be run to check.
|
||||||
|
- [ ] The change should save the user's progress if the app is
|
||||||
|
[suspended and resumed](https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-suspend-resume).
|
||||||
|
Code to handle these cases should be
|
||||||
|
[tested in the Visual Studio debugger](https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-trigger-suspend-resume-and-background-events-for-windows-store-apps-in-visual-studio).
|
||||||
|
- [ ] If the change [has customizations for particular device families](https://docs.microsoft.com/en-us/uwp/extension-sdks/device-families-overview),
|
||||||
|
it should be tested on those device families.
|
||||||
|
- [ ] The change should be tested with the app window resized to the smallest possible size.
|
||||||
|
- [ ] The change should be tested with light, dark, and high contrast themes. It should honor the
|
||||||
|
user's preferred [accent color](https://docs.microsoft.com/en-us/windows/uwp/design/style/color#accent-color-palette).
|
||||||
|
- [ ] If the change adds new libraries or other dependencies:
|
||||||
|
- [ ] If the library is packaged with the app, the increased size of the binaries should be
|
||||||
|
measured.
|
||||||
|
- [ ] If the library is not maintained by Microsoft, the Microsoft team will need to set up a
|
||||||
|
plan to monitor the upstream library for changes like security fixes.
|
||||||
|
- [ ] If the library is being used under an open-source license, we must comply with the license
|
||||||
|
and credit third parties appropriately.
|
||||||
|
- [ ] If the change adds code which runs during the app's startup path, or adds new XAML elements
|
||||||
|
which are loaded at startup:
|
||||||
|
- [ ] Run the perf tests to measure any increase in startup time. Move work out of the startup
|
||||||
|
path if possible.
|
||||||
|
- [ ] If the change adds additional logging:
|
||||||
|
- [ ] All logging should use [TraceLogging](https://docs.microsoft.com/en-us/windows/desktop/tracelogging/trace-logging-about).
|
||||||
|
- [ ] Unnecessary log events should be removed, or configured so that they are collected only when
|
||||||
|
needed to debug issues or measure feature usage.
|
||||||
|
- [ ] If the change reads user data from files or app settings:
|
||||||
|
- [ ] Verify that state saved in a previous version of the app can be used with the new version.
|
||||||
|
- [ ] If the change makes network requests:
|
||||||
|
- [ ] Microsoft must plan to keep these dependencies secure and functional for the lifetime of
|
||||||
|
the app (which might be several years).
|
||||||
|
- [ ] The app should be fully functional if some network requests are slow or fail. Tools like
|
||||||
|
[Fiddler](http://docs.telerik.com/fiddler/knowledgebase/fiddlerscript/perftesting)
|
||||||
|
can be used to simulate slow or failed requests.
|
||||||
|
|
||||||
|
## Step 8: Final product review and merge to master
|
||||||
|
After the technical review is complete, the product team will review the finished product to make
|
||||||
|
sure the final implementation is ready to release to Windows customers.
|
||||||
|
|
||||||
|
## Step 9: Release
|
||||||
|
The release process is handled internally by the Microsoft team. When we release, we create a
|
||||||
|
`servicing` branch from master. We merge changes into servicing branches only to fix severe bugs.
|
||||||
|
|
||||||
|
Releases are distributed through the Microsoft Store, first to Windows Insiders and then to all
|
||||||
|
supported Windows 10 devices once we are confident in the update's quality. We usually ship an
|
||||||
|
update every month. After the app has been released to the Microsoft Store, it will be part of
|
||||||
|
the next major update to Windows 10 (especially for new devices).
|
131
internal/Calculator.TestPackage/Calculator.TestPackage.csproj
Normal file
131
internal/Calculator.TestPackage/Calculator.TestPackage.csproj
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{24767C43-CD5A-4DC9-8D6B-429F255524E5}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Calculator.TestPackage</RootNamespace>
|
||||||
|
<AssemblyName>Calculator.TestPackage</AssemblyName>
|
||||||
|
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||||
|
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||||
|
<NuGetTargetMoniker>.NETCore,Version=v5.0</NuGetTargetMoniker>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17763.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<!-- The app doesn't contain any tests so we don't generate a testmd -->
|
||||||
|
<NoTestMD>true</NoTestMD>
|
||||||
|
<NoPackage Condition="'$(IsTFSBuild)' != 'True'">True</NoPackage>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\x86</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\x86</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\x64</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\x64</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\arm</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\arm</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM64' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\ARM64\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM64' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\ARM64\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Calculator.TestPackage.wm.xml" />
|
||||||
|
<None Include="project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Calculator\Calculator.vcxproj">
|
||||||
|
<Project>{9447424a-0e05-4911-beb8-e0354405f39a}</Project>
|
||||||
|
<Name>Calculator</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0' ">
|
||||||
|
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- Redefine build target as we don't want to build anything. -->
|
||||||
|
<Target Name="Build" />
|
||||||
|
<Target Name="Clean" />
|
||||||
|
<Target Name="Rebuild" />
|
||||||
|
<!-- Append the appx properties to the custom macros as we use this in the testmd.definition file. -->
|
||||||
|
<Target Name="AppendUniversalTestCustomMacros" BeforeTargets="BuildUniversalTest">
|
||||||
|
<ItemGroup>
|
||||||
|
<AppxBundleOutput Include="$(OutDir)..\Calculator\AppPackages\**\*.appxbundle" />
|
||||||
|
<AppxPackagePublicKeyFile Include="$(OutDir)..\Calculator\AppPackages\**\*.cer" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<AppxPackageTestDir>@(AppxBundleOutput->'%(RootDir)%(Directory)')</AppxPackageTestDir>
|
||||||
|
<UniversalTestCustomMacros Condition="'$(Configuration)'=='Debug'">$(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\$(PlatformTarget)\Microsoft.VCLibs.$(PlatformTarget).Debug.14.00.appx;</UniversalTestCustomMacros>
|
||||||
|
<UniversalTestCustomMacros Condition="'$(Configuration)'=='Release'">$(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\$(PlatformTarget)\Microsoft.VCLibs.$(PlatformTarget).14.00.appx;</UniversalTestCustomMacros>
|
||||||
|
<UniversalTestCustomMacros>$(UniversalTestCustomMacros)AppxPackageWinUIDependency=$(AppxPackageTestDir)Dependencies\$(PlatformTarget)\Microsoft.UI.Xaml.2.0.appx;</UniversalTestCustomMacros>
|
||||||
|
<UniversalTestCustomMacros>$(UniversalTestCustomMacros)AppxPackagePublicKeyFile=@(AppxPackagePublicKeyFile->'%(FullPath)');AppxBundleOutput=@(AppxBundleOutput->'%(FullPath)');</UniversalTestCustomMacros>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--Copyright (c) Microsoft Corporation. All rights reserved.-->
|
||||||
|
<identity
|
||||||
|
xmlns="urn:Microsoft.CompPlat/ManifestSchema.v1.00"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
name="App"
|
||||||
|
namespace="Calculator"
|
||||||
|
owner="Microsoft">
|
||||||
|
<files>
|
||||||
|
<file
|
||||||
|
source="$(AppxBundleOutput)"
|
||||||
|
destinationDir="$(runtime.testbin)"
|
||||||
|
name="Calculator.appxbundle" />
|
||||||
|
<file
|
||||||
|
source="$(AppxPackagePublicKeyFile)"
|
||||||
|
destinationDir="$(runtime.testbin)"
|
||||||
|
name="Calculator.cer" />
|
||||||
|
<file
|
||||||
|
source="$(AppxPackageVCLibsDependency)"
|
||||||
|
destinationDir="$(runtime.testbin)"
|
||||||
|
name="Microsoft.VCLibs.appx" />
|
||||||
|
<file
|
||||||
|
source="$(AppxPackageWinUIDependency)"
|
||||||
|
destinationDir="$(runtime.testbin)"
|
||||||
|
name="Microsoft.UI.Xaml.appx" />
|
||||||
|
</files>
|
||||||
|
</identity>
|
13
internal/Calculator.TestPackage/project.json
Normal file
13
internal/Calculator.TestPackage/project.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.TestInfrastructure.UniversalTest": "1.0.20181107.1"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcore50": {}
|
||||||
|
},
|
||||||
|
"runtimes": {
|
||||||
|
"win10-arm": {},
|
||||||
|
"win10-x64": {},
|
||||||
|
"win10-x86": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{A43517B5-8BE3-4312-913F-004978C34444}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Calculator.UIAutomationLibrary</RootNamespace>
|
||||||
|
<AssemblyName>Calculator.UIAutomationLibrary</AssemblyName>
|
||||||
|
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||||
|
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||||
|
<NuGetTargetMoniker>.NETCore,Version=v5.0</NuGetTargetMoniker>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17763.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="CalculatorAppLauncher.cs" />
|
||||||
|
<Compile Include="Components\App\CalculatorAppLfm.cs" />
|
||||||
|
<Compile Include="Components\App\CalculatorAppPom.cs" />
|
||||||
|
<Compile Include="Components\ContentDialogLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\CalculatorBasePom.cs" />
|
||||||
|
<Compile Include="Components\Pages\AboutFlyoutLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\AboutFlyoutPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\DateCalculatorLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\DateCalculatorPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\UnitConverterLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\UnitConverterPom.cs" />
|
||||||
|
<Compile Include="Components\Shared\HistoryLfm.cs" />
|
||||||
|
<Compile Include="Components\Shared\HistoryPom.cs" />
|
||||||
|
<Compile Include="Components\Shared\ICanFocusWithClicks.cs" />
|
||||||
|
<Compile Include="Components\Shared\MemoryLfm.cs" />
|
||||||
|
<Compile Include="Components\Shared\MemoryPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\NavBarLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\NavBarPom.cs" />
|
||||||
|
<Compile Include="Components\Shared\NumberPadPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\ProgrammerCalculatorLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\ProgrammerCalculatorPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\ScientificCalculatorLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\ScientificCalculatorPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\StandardCalculatorLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\StandardCalculatorPom.cs" />
|
||||||
|
<Compile Include="Components\Pages\MainPageLfm.cs" />
|
||||||
|
<Compile Include="Components\Pages\MainPagePom.cs" />
|
||||||
|
<Compile Include="Utilities\Impersonator.cs" />
|
||||||
|
<Compile Include="Utilities\PerfTestConstants.cs" />
|
||||||
|
<Compile Include="Tests\BasicCalculationTest.cs" />
|
||||||
|
<Compile Include="Tests\ScientificCalculationTest.cs" />
|
||||||
|
<Compile Include="Utilities\EtwHelper.cs" />
|
||||||
|
<Compile Include="Utilities\InstallHelper.cs" />
|
||||||
|
<Compile Include="Components\ContentDialogPom.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Utilities\Constants.cs" />
|
||||||
|
<Compile Include="Utilities\NativeMethods.cs" />
|
||||||
|
<Compile Include="Utilities\ServiceHelper.cs" />
|
||||||
|
<Compile Include="Utilities\UIObjectExtensions.cs" />
|
||||||
|
<Compile Include="Utilities\Utilities.cs" />
|
||||||
|
<Compile Include="Utilities\WindowHelper.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0' ">
|
||||||
|
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!--additional imports-->
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Etw.Managed;
|
||||||
|
using Microsoft.OneCoreUap.Test.AppModel;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Calculator.UIAutomationLibrary.Components;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class that can open and close the Calculator app.
|
||||||
|
/// </summary>
|
||||||
|
public static class CalculatorAppLauncher
|
||||||
|
{
|
||||||
|
public const string CoreWindowClassName = "Windows.UI.Core.CoreWindow";
|
||||||
|
|
||||||
|
// This doesn't actually work right now becaue popup will disappear
|
||||||
|
// Bug 13713223: ContentDialog/Popup does not show up in the UIA tree when Windows.Current.Content has an AutomationName set.
|
||||||
|
// public static readonly UICondition TopLevelWindowUICondition = UICondition.CreateFromId(Constants.TopLevelWindowAutomationId);
|
||||||
|
public static readonly UICondition CoreWindowUICondition = UICondition.CreateFromClassName(CoreWindowClassName)
|
||||||
|
.AndWith(UICondition.CreateFromName(Constants.AppWindowName));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Launch the app
|
||||||
|
/// </summary>
|
||||||
|
public static CalculatorAppLfm Launch()
|
||||||
|
{
|
||||||
|
Log.Comment("Launching Calculator and waiting for first page load...");
|
||||||
|
|
||||||
|
// Need to set this for the MITALite Tap~ methods to work on high DPI screens.
|
||||||
|
UAPApp.SetTestDPIAwareness();
|
||||||
|
|
||||||
|
// We want to be able to see any element in the tree
|
||||||
|
Context.RawContext.Activate();
|
||||||
|
|
||||||
|
// Set default wait timeout.
|
||||||
|
MS.Internal.Mita.Foundation.Waiters.Waiter.DefaultTimeout = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
// Enable Mita internal logging.
|
||||||
|
MS.Internal.Mita.Foundation.Utilities.Log.OutImplementation = (s, a) => { Log.Comment($"- [MitaLite] { string.Format(s, a) }"); };
|
||||||
|
|
||||||
|
using (EtwWaiter appLaunchWaiter = new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.AppLaunchEndETWEventName))
|
||||||
|
{
|
||||||
|
var viewDescriptor = NavigationHelper.LaunchApplication(Constants.PackageAppUserModelId);
|
||||||
|
appLaunchWaiter.Wait(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
|
Window calculatorWindow = new Window(UIObject.Root.Descendants.Find(CoreWindowUICondition));
|
||||||
|
Debug.Assert(calculatorWindow.ClassName == CoreWindowClassName);
|
||||||
|
|
||||||
|
// Move our window to the foreground.
|
||||||
|
WindowHelper.SetAsForeground(calculatorWindow.GetTopLevelWindow());
|
||||||
|
|
||||||
|
return new CalculatorAppLfm(new CalculatorAppPom(calculatorWindow), viewDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Microsoft.OneCoreUap.Test.AppModel;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class CalculatorAppLfm
|
||||||
|
{
|
||||||
|
private readonly IViewDescriptor viewDescriptor;
|
||||||
|
|
||||||
|
public CalculatorAppLfm(CalculatorAppPom objectModel, IViewDescriptor viewDescriptor)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
this.viewDescriptor = viewDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorAppPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public MainPageLfm MainPageLfm
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new MainPageLfm(this.ObjectModel.MainPagePom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
// ObjectModel is essentially the window ui object.
|
||||||
|
if (this.viewDescriptor != null)
|
||||||
|
{
|
||||||
|
NavigationHelper.CloseApplication(this.viewDescriptor.AUMID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class CalculatorAppPom : UIObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="CalculatorAppPom"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">UIObject for the calculator app window.</param>
|
||||||
|
public CalculatorAppPom(UIObject uiObject)
|
||||||
|
: base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public MainPagePom MainPagePom
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new MainPagePom(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class ContentDialogLfm
|
||||||
|
{
|
||||||
|
public ContentDialogLfm(ContentDialogPom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentDialogPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void InvokePrimary()
|
||||||
|
{
|
||||||
|
this.ObjectModel.PrimaryButton.Invoke();
|
||||||
|
}
|
||||||
|
public void InvokeSecondary()
|
||||||
|
{
|
||||||
|
this.ObjectModel.SecondaryButton.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvokeClose()
|
||||||
|
{
|
||||||
|
this.ObjectModel.CloseButton.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class ContentDialogPom : UIObject
|
||||||
|
{
|
||||||
|
private static readonly UICondition textScrollViewerCondition = UICondition.CreateFromId("ContentScrollViewer");
|
||||||
|
private static readonly UICondition titleTextBlockCondition = UICondition.CreateFromClassName("TextBlock");
|
||||||
|
|
||||||
|
private static readonly UICondition primaryButtonCondition =
|
||||||
|
UICondition.CreateFromClassName("Button")
|
||||||
|
.AndWith(UICondition.CreateFromId("PrimaryButton"));
|
||||||
|
private static readonly UICondition secondaryButtonCondition =
|
||||||
|
UICondition.CreateFromClassName("Button")
|
||||||
|
.AndWith(UICondition.CreateFromId("SecondaryButton"));
|
||||||
|
private static readonly UICondition closeButtonCondition =
|
||||||
|
UICondition.CreateFromClassName("Button")
|
||||||
|
.AndWith(UICondition.CreateFromId("CloseButton"));
|
||||||
|
|
||||||
|
public ContentDialogPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button PrimaryButton
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new Button(this.Children.Find(primaryButtonCondition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button SecondaryButton
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new Button(this.Children.Find(secondaryButtonCondition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button CloseButton
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new Button(this.Children.Find(closeButtonCondition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var scrollViewer = this.Children.Find(textScrollViewerCondition);
|
||||||
|
var textBlock = scrollViewer.Children.Find(titleTextBlockCondition);
|
||||||
|
return textBlock.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class AboutFlyoutLfm : ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
private const string FlyoutId = "FlyoutNav";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AboutFlyoutLfm" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectModel">The AboutFlyoutPom that represents the About flyout panel.</param>
|
||||||
|
public AboutFlyoutLfm(AboutFlyoutPom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AboutFlyoutPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void FocusWithClicks()
|
||||||
|
{
|
||||||
|
this.ObjectModel.Title.DoubleClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
this.ObjectModel.SendKeys("{ESC}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class AboutFlyoutPom : UIObject
|
||||||
|
{
|
||||||
|
private const string TitleId = "Header";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AboutFlyoutPom" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the navigation menu.</param>
|
||||||
|
public AboutFlyoutPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIObject Title
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new UIObject(this.Descendants.Find(TitleId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Display section of the calculator modes.
|
||||||
|
/// </summary>
|
||||||
|
public class CalculatorBasePom : UIObject
|
||||||
|
{
|
||||||
|
private const string ExpressionContainerId = "CalculatorExpression";
|
||||||
|
private const string NormalOutputId = "normalOutput";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StandardCalculatorPom" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the standard calculator.</param>
|
||||||
|
public CalculatorBasePom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextBlock Expression
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TextBlock(this.Descendants.Find(ExpressionContainerId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIEventWaiter GetExpressionChangedWaiter()
|
||||||
|
{
|
||||||
|
return new PropertyChangedEventWaiter(this.Expression, UIProperty.Get("Name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextBlock Display
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TextBlock(this.Descendants.Find(NormalOutputId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIEventWaiter GetDisplayChangedWaiter()
|
||||||
|
{
|
||||||
|
return new PropertyChangedEventWaiter(this.Display, UIProperty.Get("Name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class DateCalculatorLfm
|
||||||
|
{
|
||||||
|
public DateCalculatorLfm(DateCalculatorPom dateCalculatorPom)
|
||||||
|
{
|
||||||
|
this.ObjectModel = dateCalculatorPom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateCalculatorPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void EnsureDateDifferenceMode()
|
||||||
|
{
|
||||||
|
this.OpenModeSelector();
|
||||||
|
this.ObjectModel.ModeSelector.AllItems[0].Select();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnsureAddSubtractMode()
|
||||||
|
{
|
||||||
|
this.OpenModeSelector();
|
||||||
|
this.ObjectModel.ModeSelector.AllItems[1].Select();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenModeSelector()
|
||||||
|
{
|
||||||
|
using (var waiter = this.ObjectModel.ModeSelector.GetExpandedWaiter())
|
||||||
|
{
|
||||||
|
this.ObjectModel.ModeSelector.Expand();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class DateCalculatorPom : UIObject
|
||||||
|
{
|
||||||
|
private const string ModeSelectorId = "DateCalculationOption";
|
||||||
|
|
||||||
|
public DateCalculatorPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComboBox ModeSelector
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new ComboBox(this.Descendants.Find(ModeSelectorId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Etw.Managed;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class MainPageLfm : ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
public MainPageLfm(MainPagePom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainPagePom ObjectModel { get; }
|
||||||
|
|
||||||
|
public NavBarLfm OpenNavBar()
|
||||||
|
{
|
||||||
|
using (EtwWaiter waiter = this.ObjectModel.GetNavBarOpenedWaiter())
|
||||||
|
{
|
||||||
|
this.ObjectModel.NavButton.Invoke();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NavBarLfm(this.ObjectModel.NavBarPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseNavBar()
|
||||||
|
{
|
||||||
|
this.ObjectModel.NavBarPom.CloseButton.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FocusWithClicks()
|
||||||
|
{
|
||||||
|
this.ObjectModel.Header.DoubleClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardCalculatorLfm NavigateToStandardCalculator()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectStandard();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StandardCalculatorLfm(this.ObjectModel.StandardCalculatorPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScientificCalculatorLfm NavigateToScientificCalculator()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectScientific();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ScientificCalculatorLfm(this.ObjectModel.ScientificCalculatorPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgrammerCalculatorLfm NavigateToProgrammerCalculator()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectProgrammer();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ProgrammerCalculatorLfm(this.ObjectModel.ProgrammerCalculatorPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateCalculatorLfm NavigateToDateCalculator()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectDate();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DateCalculatorLfm(this.ObjectModel.DateCalculatorPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToCurrencyConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectCurrency();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToVolumeConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectVolume();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToLengthConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectLength();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToWeightConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectWeight();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToTemperatureConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectTemperature();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToEnergyConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectEnergy();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToAreaConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectArea();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToSpeedConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectSpeed();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToTimeConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectTime();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToPowerConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectPower();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToDataConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectData();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToPressureConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectPressure();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterLfm NavigateToAngleConverter()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (var waiter = this.ObjectModel.GetModeChangedWaiter())
|
||||||
|
{
|
||||||
|
navBar.SelectAngle();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnitConverterLfm(this.ObjectModel.UnitConverterPom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AboutFlyoutLfm OpenAboutFlyout()
|
||||||
|
{
|
||||||
|
var navBar = this.OpenNavBar();
|
||||||
|
using (EtwWaiter waiter = new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.AboutFlyoutOpenedETWEventName))
|
||||||
|
{
|
||||||
|
navBar.SelectAbout();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AboutFlyoutLfm(this.ObjectModel.AboutFlyoutPom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Etw.Managed;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Physical Object Model for the app window.
|
||||||
|
/// POM is the implementation model of the app.
|
||||||
|
/// See following references to POM:
|
||||||
|
/// * https://blogs.msdn.microsoft.com/wltester/2011/11/14/object-model-design/
|
||||||
|
/// * https://blogs.msdn.microsoft.com/micahel/2005/06/03/how-do-i-invoke-thee-let-me-count-the-ways-the-physical-object-model/
|
||||||
|
/// See https://en.wikipedia.org/wiki/Model-based_testing for model-based testing.
|
||||||
|
/// </summary>
|
||||||
|
public class MainPagePom : UIObject
|
||||||
|
{
|
||||||
|
private const string NavButtonId = "TogglePaneButton";
|
||||||
|
private const string SplitViewPaneRootId = "PaneRoot";
|
||||||
|
private const string NavBarFlyoutId = "FlyoutNav";
|
||||||
|
private const string HeaderId = "Header";
|
||||||
|
private const string AboutPageFlyoutId = "AboutPageFlyout";
|
||||||
|
|
||||||
|
public MainPagePom(UIObject uiObject)
|
||||||
|
: base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button NavButton => new Button(this.Descendants.Find(UICondition.CreateFromId(NavButtonId)));
|
||||||
|
|
||||||
|
public UIObject Header => new UIObject(this.Descendants.Find(HeaderId));
|
||||||
|
|
||||||
|
public NavBarPom NavBarPom => new NavBarPom(this.Children.Find(SplitViewPaneRootId));
|
||||||
|
|
||||||
|
public EtwWaiter GetNavBarOpenedWaiter() => new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.NavBarOpenedETWEventName);
|
||||||
|
|
||||||
|
public StandardCalculatorPom StandardCalculatorPom => new StandardCalculatorPom(this);
|
||||||
|
|
||||||
|
public ScientificCalculatorPom ScientificCalculatorPom => new ScientificCalculatorPom(this);
|
||||||
|
|
||||||
|
public ProgrammerCalculatorPom ProgrammerCalculatorPom => new ProgrammerCalculatorPom(this);
|
||||||
|
|
||||||
|
public DateCalculatorPom DateCalculatorPom => new DateCalculatorPom(this);
|
||||||
|
|
||||||
|
public UnitConverterPom UnitConverterPom => new UnitConverterPom(this);
|
||||||
|
|
||||||
|
public AboutFlyoutPom AboutFlyoutPom => new AboutFlyoutPom(this.Descendants.Find(AboutPageFlyoutId));
|
||||||
|
|
||||||
|
public EtwWaiter GetModeChangedWaiter() => new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.AppModeChangeEndETWEventName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Windows.Automation;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Patterns;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the NavBar of the Calculator app.
|
||||||
|
/// </summary>
|
||||||
|
public class NavBarLfm : ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="NavBarLfm" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectModel">The NavBarPom that represents the NavBar.</param>
|
||||||
|
public NavBarLfm(NavBarPom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavBarPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void SelectStandard()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.StandardMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectScientific()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.ScientificMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectProgrammer()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.ProgrammerMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectDate()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.DateMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectCurrency()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.CurrencyMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectVolume()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.VolumeMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectLength()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.LengthMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectWeight()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.WeightMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectTemperature()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.TemperatureMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectEnergy()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.EnergyMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectArea()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.AreaMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectSpeed()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.SpeedMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectTime()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.TimeMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectPower()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.PowerMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectData()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.DataMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectPressure()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.PressureMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectAngle()
|
||||||
|
{
|
||||||
|
SelectItem(this.ObjectModel.AngleMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectAbout()
|
||||||
|
{
|
||||||
|
this.ObjectModel.AboutButton.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
this.ObjectModel.CloseButton.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FocusWithClicks()
|
||||||
|
{
|
||||||
|
// To focus (for AccSpot) without changing anything, click to the right of the close button.
|
||||||
|
Button button = this.ObjectModel.CloseButton;
|
||||||
|
int xPos = button.BoundingRectangle.Width + Constants.ClickMargin;
|
||||||
|
int yPos = button.BoundingRectangle.Height / 2;
|
||||||
|
button.DoubleClick(PointerButtons.Primary, xPos, yPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectItem(ListViewItem item)
|
||||||
|
{
|
||||||
|
if (item.IsSelected)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the navigation menu.
|
||||||
|
/// </summary>
|
||||||
|
public class NavBarPom : UIObject
|
||||||
|
{
|
||||||
|
private const string StandardId = "Standard";
|
||||||
|
private const string ScientificId = "Scientific";
|
||||||
|
private const string ProgrammerId = "Programmer";
|
||||||
|
private const string DateId = "Date";
|
||||||
|
private const string CurrencyId = "Currency";
|
||||||
|
private const string VolumeId = "Volume";
|
||||||
|
private const string LengthId = "Length";
|
||||||
|
private const string WeightId = "Weight";
|
||||||
|
private const string TemperatureId = "Temperature";
|
||||||
|
private const string EnergyId = "Energy";
|
||||||
|
private const string AreaId = "Area";
|
||||||
|
private const string SpeedId = "Speed";
|
||||||
|
private const string TimeId = "Time";
|
||||||
|
private const string PowerId = "Power";
|
||||||
|
private const string DataId = "Data";
|
||||||
|
private const string PressureId = "Pressure";
|
||||||
|
private const string AngleId = "Angle";
|
||||||
|
private const string AboutId = "AboutButton";
|
||||||
|
private const string CloseId = "TogglePaneButton";
|
||||||
|
private const string FlyoutListViewId = "MenuItemsHost";
|
||||||
|
private const string ConverterSectionId = "Converter";
|
||||||
|
private const string ConverterTextKey = "ConverterModeText";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="NavBarPom" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the navigation menu.</param>
|
||||||
|
public NavBarPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListViewItem StandardMenuItem => ScrollAndGetItem(StandardId);
|
||||||
|
|
||||||
|
public ListViewItem ScientificMenuItem => ScrollAndGetItem(ScientificId);
|
||||||
|
|
||||||
|
public ListViewItem ProgrammerMenuItem => ScrollAndGetItem(ProgrammerId);
|
||||||
|
|
||||||
|
public ListViewItem DateMenuItem => ScrollAndGetItem(DateId);
|
||||||
|
|
||||||
|
public ListViewItem CurrencyMenuItem => ScrollAndGetItem(CurrencyId);
|
||||||
|
|
||||||
|
public ListViewItem VolumeMenuItem => ScrollAndGetItem(VolumeId);
|
||||||
|
|
||||||
|
public ListViewItem LengthMenuItem => ScrollAndGetItem(LengthId);
|
||||||
|
|
||||||
|
public ListViewItem WeightMenuItem => ScrollAndGetItem(WeightId);
|
||||||
|
|
||||||
|
public ListViewItem TemperatureMenuItem => ScrollAndGetItem(TemperatureId);
|
||||||
|
|
||||||
|
public ListViewItem EnergyMenuItem => ScrollAndGetItem(EnergyId);
|
||||||
|
|
||||||
|
public ListViewItem AreaMenuItem => ScrollAndGetItem(AreaId);
|
||||||
|
|
||||||
|
public ListViewItem SpeedMenuItem => ScrollAndGetItem(SpeedId);
|
||||||
|
|
||||||
|
public ListViewItem TimeMenuItem => ScrollAndGetItem(TimeId);
|
||||||
|
|
||||||
|
public ListViewItem PowerMenuItem => ScrollAndGetItem(PowerId);
|
||||||
|
|
||||||
|
public ListViewItem DataMenuItem => ScrollAndGetItem(DataId);
|
||||||
|
|
||||||
|
public ListViewItem PressureMenuItem => ScrollAndGetItem(PressureId);
|
||||||
|
|
||||||
|
public ListViewItem AngleMenuItem => ScrollAndGetItem(AngleId);
|
||||||
|
|
||||||
|
public Button AboutButton => new Button(this.Descendants.Find(AboutId));
|
||||||
|
|
||||||
|
public Button CloseButton => new Button(this.Parent.Children.Find(CloseId));
|
||||||
|
|
||||||
|
public ListView ModeListView => new ListView(this.Descendants.Find(FlyoutListViewId));
|
||||||
|
|
||||||
|
private ListViewItem ScrollAndGetItem(string id)
|
||||||
|
{
|
||||||
|
ListViewItem item;
|
||||||
|
var res = this.ModeListView.AllItems.TryFind(id, out item);
|
||||||
|
|
||||||
|
item.ScrollIntoView();
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class ProgrammerCalculatorLfm
|
||||||
|
{
|
||||||
|
public ProgrammerCalculatorLfm(ProgrammerCalculatorPom programmerCalculatorPom)
|
||||||
|
{
|
||||||
|
this.ObjectModel = programmerCalculatorPom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgrammerCalculatorPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void EnsureFullKeypad()
|
||||||
|
{
|
||||||
|
if (!this.ObjectModel.FullKeypadButton.IsSelected)
|
||||||
|
{
|
||||||
|
this.ObjectModel.FullKeypadButton.Select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnsureBitTogglingKeypad()
|
||||||
|
{
|
||||||
|
if (!this.ObjectModel.BitFlipKeypadButton.IsSelected)
|
||||||
|
{
|
||||||
|
this.ObjectModel.BitFlipKeypadButton.Select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeBitLength()
|
||||||
|
{
|
||||||
|
this.ObjectModel.GetCurrentBitLengthButton().Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryLfm OpenMemory()
|
||||||
|
{
|
||||||
|
MemoryLfm lfm = new MemoryLfm(this.ObjectModel.MemoryControls);
|
||||||
|
lfm.OpenBody();
|
||||||
|
return lfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FiveMemorySet()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
this.ObjectModel.NumberPad.FiveButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ObjectModel.MemoryControls.SetButton.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class ProgrammerCalculatorPom : UIObject
|
||||||
|
{
|
||||||
|
private const string FullKeypadButtonId = "fullKeypad";
|
||||||
|
private const string BitFlipKeypadButtonId = "bitFlip";
|
||||||
|
private const string CalculatorResultsId = "CalculatorResults";
|
||||||
|
private const string NumberPadId = "NumberPad";
|
||||||
|
|
||||||
|
private readonly string[] BitLengthButtonIds =
|
||||||
|
{
|
||||||
|
"qwordButton",
|
||||||
|
"dwordButton",
|
||||||
|
"wordButton",
|
||||||
|
"byteButton"
|
||||||
|
};
|
||||||
|
|
||||||
|
public ProgrammerCalculatorPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberPadPom NumberPad => new NumberPadPom(this.Descendants.Find(NumberPadId));
|
||||||
|
|
||||||
|
public MemoryPom MemoryControls => new MemoryPom(this);
|
||||||
|
|
||||||
|
public RadioButton FullKeypadButton => new RadioButton(this.Descendants.Find(FullKeypadButtonId));
|
||||||
|
|
||||||
|
public RadioButton BitFlipKeypadButton => new RadioButton(this.Descendants.Find(BitFlipKeypadButtonId));
|
||||||
|
|
||||||
|
public TextBlock Display => new TextBlock(this.Descendants.Find(CalculatorResultsId));
|
||||||
|
|
||||||
|
public UIEventWaiter GetDisplayChangedWaiter() => this.Display.GetNameChangedWaiter();
|
||||||
|
|
||||||
|
public Button GetCurrentBitLengthButton()
|
||||||
|
{
|
||||||
|
// There are four bit length buttons, with only one visible at a time.
|
||||||
|
UIObject button = null;
|
||||||
|
foreach (var buttonId in this.BitLengthButtonIds)
|
||||||
|
{
|
||||||
|
if (this.Descendants.TryFind(buttonId, out button))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Button(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Standard calculator view.
|
||||||
|
/// </summary>
|
||||||
|
public class ScientificCalculatorLfm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ScientificCalculatorLfm" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the scientific Calculator.</param>
|
||||||
|
public ScientificCalculatorLfm(ScientificCalculatorPom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScientificCalculatorPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void Press1()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking 1");
|
||||||
|
this.ObjectModel.OneButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Press2()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking 2");
|
||||||
|
this.ObjectModel.NumberPad.TwoButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Press3()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking 3");
|
||||||
|
this.ObjectModel.ThreeButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Press4()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking 4");
|
||||||
|
this.ObjectModel.FourButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PressSqrt()
|
||||||
|
{
|
||||||
|
// When invoking sqrt, both the expression changes.
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking sqrt");
|
||||||
|
this.ObjectModel.SqrtButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PressMinus()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking minus");
|
||||||
|
this.ObjectModel.MinusButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PressPlus()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking plus");
|
||||||
|
this.ObjectModel.PlusButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PressEquals()
|
||||||
|
{
|
||||||
|
// When invoking equals, both the display and the expression change.
|
||||||
|
using (UIEventWaiter expressionWaiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
using (UIEventWaiter displayWaiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking equals");
|
||||||
|
this.ObjectModel.EqualButton.Invoke();
|
||||||
|
expressionWaiter.TryWait();
|
||||||
|
displayWaiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnePlusTwoEnter()
|
||||||
|
{
|
||||||
|
Press1();
|
||||||
|
PressPlus();
|
||||||
|
Press2();
|
||||||
|
PressEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MemorySet() => this.ObjectModel.MemoryControls.SetButton.Invoke();
|
||||||
|
|
||||||
|
public MemoryLfm OpenMemory()
|
||||||
|
{
|
||||||
|
MemoryLfm lfm = new MemoryLfm(this.ObjectModel.MemoryControls);
|
||||||
|
lfm.OpenBody();
|
||||||
|
return lfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HistoryLfm OpenHistory()
|
||||||
|
{
|
||||||
|
HistoryLfm lfm = new HistoryLfm(this.ObjectModel.HistoryControls);
|
||||||
|
lfm.OpenBody();
|
||||||
|
return lfm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Scientific Calculator
|
||||||
|
/// </summary>
|
||||||
|
public class ScientificCalculatorPom : CalculatorBasePom
|
||||||
|
{
|
||||||
|
private const string NumberPadId = "NumberPad";
|
||||||
|
private const string StandardOperatorsId = "StandardOperators";
|
||||||
|
private const string DisplayControlsId = "DisplayControls";
|
||||||
|
private const string ScientificFunctionsId = "ScientificFunctions";
|
||||||
|
private const string OneButtonId = "num1Button";
|
||||||
|
private const string ThreeButtonId = "num3Button";
|
||||||
|
private const string FourButtonId = "num4Button";
|
||||||
|
private const string SqrtButtonId = "squareRootButton";
|
||||||
|
private const string MinusButtonId = "minusButton";
|
||||||
|
private const string PlusButtonId = "plusButton";
|
||||||
|
private const string EqualButtonId = "equalButton";
|
||||||
|
private const string ClearButtonId = "clearButton";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ScientificCalculatorPom" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the scientific calculator.</param>
|
||||||
|
public ScientificCalculatorPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIObject StandardOperatorsGroup => this.Descendants.Find(StandardOperatorsId);
|
||||||
|
|
||||||
|
public UIObject DisplayControlsGroup => this.Descendants.Find(DisplayControlsId);
|
||||||
|
|
||||||
|
public UIObject ScientificFunctionsGroup => this.Descendants.Find(ScientificFunctionsId);
|
||||||
|
|
||||||
|
public Button OneButton => this.NumberPad.OneButton;
|
||||||
|
|
||||||
|
public Button ThreeButton => this.NumberPad.ThreeButton;
|
||||||
|
|
||||||
|
public Button FourButton => this.NumberPad.FourButton;
|
||||||
|
|
||||||
|
public Button SqrtButton => new Button(this.ScientificFunctionsGroup.Children.Find(SqrtButtonId));
|
||||||
|
|
||||||
|
public Button MinusButton => new Button(this.StandardOperatorsGroup.Children.Find(MinusButtonId));
|
||||||
|
|
||||||
|
public Button PlusButton => new Button(this.StandardOperatorsGroup.Children.Find(PlusButtonId));
|
||||||
|
|
||||||
|
public Button EqualButton => new Button(this.StandardOperatorsGroup.Children.Find(EqualButtonId));
|
||||||
|
|
||||||
|
public Button ClearButton => new Button(this.DisplayControlsGroup.Children.Find(ClearButtonId));
|
||||||
|
|
||||||
|
public NumberPadPom NumberPad => new NumberPadPom(this.Descendants.Find(NumberPadId));
|
||||||
|
|
||||||
|
public HistoryPom HistoryControls => new HistoryPom(this);
|
||||||
|
|
||||||
|
public MemoryPom MemoryControls => new MemoryPom(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Standard calculator view.
|
||||||
|
/// </summary>
|
||||||
|
public class StandardCalculatorLfm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StandardCalculatorLfm" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the Standard Calculator.</param>
|
||||||
|
public StandardCalculatorLfm(StandardCalculatorPom objectModel)
|
||||||
|
{
|
||||||
|
this.ObjectModel = objectModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardCalculatorPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void OnePlusTwoEnter()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking 1");
|
||||||
|
this.ObjectModel.NumPad.OneButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Pressing +");
|
||||||
|
this.ObjectModel.SendKeys("{ADD}");
|
||||||
|
// PropertyChangeWaiter is unreliable for the first name changed notification
|
||||||
|
// Bug 17624996: PropertyChanged event not fired when Name is updated for the first time for a control with custom automation peer.
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Pressing 2");
|
||||||
|
this.ObjectModel.SendKeys("2");
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
// When pressing enter, both the display and the expression change.
|
||||||
|
using (UIEventWaiter expressionWaiter = this.ObjectModel.GetExpressionChangedWaiter())
|
||||||
|
using (UIEventWaiter displayWaiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Invoking equals");
|
||||||
|
this.ObjectModel.EqualButton.Invoke();
|
||||||
|
expressionWaiter.TryWait();
|
||||||
|
displayWaiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
Log.Comment("Pressing escape");
|
||||||
|
this.ObjectModel.ClearButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearFiveMemorySet()
|
||||||
|
{
|
||||||
|
this.Clear();
|
||||||
|
using (UIEventWaiter waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
this.ObjectModel.NumPad.FiveButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ObjectModel.MemoryControls.SetButton.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryLfm OpenMemory()
|
||||||
|
{
|
||||||
|
MemoryLfm lfm = new MemoryLfm(this.ObjectModel.MemoryControls);
|
||||||
|
lfm.OpenBody();
|
||||||
|
return lfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HistoryLfm OpenHistory()
|
||||||
|
{
|
||||||
|
HistoryLfm lfm = new HistoryLfm(this.ObjectModel.HistoryControls);
|
||||||
|
lfm.OpenBody();
|
||||||
|
return lfm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Standard Calculator
|
||||||
|
/// </summary>
|
||||||
|
public class StandardCalculatorPom : CalculatorBasePom
|
||||||
|
{
|
||||||
|
private const string CalculatorResultsId = "CalculatorResults";
|
||||||
|
private const string ExpressionContainerId = "CalculatorExpression";
|
||||||
|
private const string NumberPadId = "NumberPad";
|
||||||
|
private const string StandardOperatorsId = "StandardOperators";
|
||||||
|
private const string DisplayControlsId = "DisplayControls";
|
||||||
|
private const string EqualButtonId = "equalButton";
|
||||||
|
private const string ClearButtonId = "clearButton";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StandardCalculatorPom" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiObject">The UIObject that is the root of the standard calculator.</param>
|
||||||
|
public StandardCalculatorPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberPadPom NumPad => new NumberPadPom(this.Descendants.Find(NumberPadId));
|
||||||
|
|
||||||
|
public MemoryPom MemoryControls => new MemoryPom(this);
|
||||||
|
|
||||||
|
public HistoryPom HistoryControls => new HistoryPom(this);
|
||||||
|
|
||||||
|
public UIObject StandardOperatorsGroup => this.Descendants.Find(StandardOperatorsId);
|
||||||
|
|
||||||
|
public UIObject DisplayControlsGroup => this.Descendants.Find(DisplayControlsId);
|
||||||
|
|
||||||
|
public Button EqualButton => new Button(this.StandardOperatorsGroup.Children.Find(EqualButtonId));
|
||||||
|
|
||||||
|
public Button ClearButton => new Button(this.DisplayControlsGroup.Children.Find(ClearButtonId));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class UnitConverterLfm
|
||||||
|
{
|
||||||
|
public UnitConverterLfm(UnitConverterPom unitConverterPom)
|
||||||
|
{
|
||||||
|
this.ObjectModel = unitConverterPom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitConverterPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void Eight()
|
||||||
|
{
|
||||||
|
using (var waiter = this.ObjectModel.GetDisplayChangedWaiter())
|
||||||
|
{
|
||||||
|
this.ObjectModel.NumberPad.EightButton.Invoke();
|
||||||
|
waiter.TryWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class UnitConverterPom : UIObject
|
||||||
|
{
|
||||||
|
private const string DisplayId = "Value1";
|
||||||
|
private const string NumberPadId = "numberPad";
|
||||||
|
|
||||||
|
public UnitConverterPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberPadPom NumberPad => new NumberPadPom(this.Descendants.Find(NumberPadId));
|
||||||
|
|
||||||
|
public TextBlock Display => new TextBlock(this.Descendants.Find(DisplayId));
|
||||||
|
|
||||||
|
public PropertyChangedEventWaiter GetDisplayChangedWaiter() => this.Display.GetNameChangedWaiter();
|
||||||
|
|
||||||
|
public ElementAddedWaiter GetDisplayElementAddedWaiter() => new ElementAddedWaiter(this, Scope.Descendants, DisplayId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Etw.Managed;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class HistoryLfm : ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
public HistoryLfm(HistoryPom historyPom)
|
||||||
|
{
|
||||||
|
this.ObjectModel = historyPom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HistoryPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void FocusWithClicks()
|
||||||
|
{
|
||||||
|
// On the Programming calc, the default click location can land on the first memory item, dismissing the flyout.
|
||||||
|
// Instead, click just below, in the gutter to the left of the trash can.
|
||||||
|
var body = this.ObjectModel.Body;
|
||||||
|
int height = body.BoundingRectangle.Height;
|
||||||
|
body.DoubleClick(PointerButtons.Primary, Constants.ClickMargin, height + Constants.ClickMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenBody()
|
||||||
|
{
|
||||||
|
using (EtwWaiter waiter = new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.HistoryBodyOpenedETWEventName))
|
||||||
|
{
|
||||||
|
// Only one exists at a given time.
|
||||||
|
if (this.ObjectModel.IsHistoryButtonVisible)
|
||||||
|
{
|
||||||
|
if (!this.ObjectModel.IsBodyOpen)
|
||||||
|
{
|
||||||
|
this.ObjectModel.HistoryButton.Invoke();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!this.ObjectModel.HistoryPivot.IsSelected)
|
||||||
|
{
|
||||||
|
this.ObjectModel.HistoryPivot.Click();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class HistoryPom : UIObject
|
||||||
|
{
|
||||||
|
private const string HistoryButtonId = "HistoryButton";
|
||||||
|
private const string HistoryPivotId = "HistoryLabel";
|
||||||
|
private const string BodyId = "HistoryListView";
|
||||||
|
|
||||||
|
public HistoryPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button HistoryButton => new Button(this.Descendants.Find(HistoryButtonId));
|
||||||
|
|
||||||
|
public bool IsHistoryButtonVisible => this.DoesDescendantExist(HistoryButtonId);
|
||||||
|
|
||||||
|
public TabItem HistoryPivot => new TabItem(this.Descendants.Find(HistoryPivotId));
|
||||||
|
|
||||||
|
public UIObject Body => this.Descendants.Find(BodyId);
|
||||||
|
|
||||||
|
public bool IsBodyOpen => this.DoesDescendantExist(BodyId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public interface ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sets focus on an object by clicking on it, without causing further action.
|
||||||
|
/// Supports AccSpot scans by raising click events.
|
||||||
|
/// </summary>
|
||||||
|
void FocusWithClicks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Etw.Managed;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class MemoryLfm : ICanFocusWithClicks
|
||||||
|
{
|
||||||
|
public MemoryLfm(MemoryPom memoryPom)
|
||||||
|
{
|
||||||
|
this.ObjectModel = memoryPom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryPom ObjectModel { get; }
|
||||||
|
|
||||||
|
public void FocusWithClicks()
|
||||||
|
{
|
||||||
|
// On the Programming calc, the default click location can land on the first memory item, dismissing the flyout.
|
||||||
|
// Instead, click just below, in the gutter to the left of the trash can.
|
||||||
|
var body = this.ObjectModel.Body;
|
||||||
|
int height = body.BoundingRectangle.Height;
|
||||||
|
body.DoubleClick(PointerButtons.Primary, Constants.ClickMargin, height + Constants.ClickMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenBody()
|
||||||
|
{
|
||||||
|
using (EtwWaiter waiter = new EtwWaiter(Constants.CalculatorETWProviderGUID, Constants.MemoryBodyOpenedETWEventName))
|
||||||
|
{
|
||||||
|
// Only one exists at a given time
|
||||||
|
if (this.ObjectModel.IsMemoryButtonVisible)
|
||||||
|
{
|
||||||
|
if (!this.ObjectModel.IsBodyOpen)
|
||||||
|
{
|
||||||
|
this.ObjectModel.MemoryButton.Invoke();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!this.ObjectModel.MemoryPivot.IsSelected)
|
||||||
|
{
|
||||||
|
this.ObjectModel.MemoryPivot.Click();
|
||||||
|
waiter.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class MemoryPom : UIObject
|
||||||
|
{
|
||||||
|
private const string ClearMemoryButtonId = "ClearMemoryButton";
|
||||||
|
private const string RecallButtonId = "MemRecall";
|
||||||
|
private const string PlusButtonId = "MemPlus";
|
||||||
|
private const string MinusButtonId = "MemMinus";
|
||||||
|
private const string SetButtonId = "memButton";
|
||||||
|
private const string MemoryButtonId = "MemoryButton";
|
||||||
|
private const string MemoryPivotId = "MemoryLabel";
|
||||||
|
private const string BodyId = "MemoryListView";
|
||||||
|
|
||||||
|
public MemoryPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button ClearButton => new Button(this.Descendants.Find(ClearMemoryButtonId));
|
||||||
|
|
||||||
|
public Button RecallButton => new Button(this.Descendants.Find(RecallButtonId));
|
||||||
|
|
||||||
|
public Button PlusButton => new Button(this.Descendants.Find(PlusButtonId));
|
||||||
|
|
||||||
|
public Button MinusButton => new Button(this.Descendants.Find(MinusButtonId));
|
||||||
|
|
||||||
|
public Button SetButton => new Button(this.Descendants.Find(SetButtonId));
|
||||||
|
|
||||||
|
public Button MemoryButton => new Button(this.Descendants.Find(MemoryButtonId));
|
||||||
|
|
||||||
|
public bool IsMemoryButtonVisible => this.DoesDescendantExist(MemoryButtonId);
|
||||||
|
|
||||||
|
public TabItem MemoryPivot => new TabItem(this.Descendants.Find(MemoryPivotId));
|
||||||
|
|
||||||
|
public UIObject Body => this.Descendants.Find(BodyId);
|
||||||
|
|
||||||
|
public bool IsBodyOpen => this.DoesDescendantExist(BodyId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Components
|
||||||
|
{
|
||||||
|
public class NumberPadPom : UIObject
|
||||||
|
{
|
||||||
|
private const string OneButtonId = "num1Button";
|
||||||
|
private const string TwoButtonId = "num2Button";
|
||||||
|
private const string ThreeButtonId = "num3Button";
|
||||||
|
private const string FourButtonId = "num4Button";
|
||||||
|
private const string FiveButtonId = "num5Button";
|
||||||
|
private const string SixButtonId = "num6Button";
|
||||||
|
private const string SevenButtonId = "num7Button";
|
||||||
|
private const string EightButtonId = "num8Button";
|
||||||
|
private const string NineButtonId = "num9Button";
|
||||||
|
private const string ZeroButtonId = "num0Button";
|
||||||
|
private const string DecimalButtonId = "decimalSeparatorButton";
|
||||||
|
|
||||||
|
public NumberPadPom(UIObject uiObject) : base(uiObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button ZeroButton => new Button(this.Children.Find(ZeroButtonId));
|
||||||
|
|
||||||
|
public Button OneButton => new Button(this.Children.Find(OneButtonId));
|
||||||
|
|
||||||
|
public Button TwoButton => new Button(this.Children.Find(TwoButtonId));
|
||||||
|
|
||||||
|
public Button ThreeButton => new Button(this.Children.Find(ThreeButtonId));
|
||||||
|
|
||||||
|
public Button FourButton => new Button(this.Children.Find(FourButtonId));
|
||||||
|
|
||||||
|
public Button FiveButton => new Button(this.Children.Find(FiveButtonId));
|
||||||
|
|
||||||
|
public Button SixButton => new Button(this.Children.Find(SixButtonId));
|
||||||
|
|
||||||
|
public Button SevenButton => new Button(this.Children.Find(SevenButtonId));
|
||||||
|
|
||||||
|
public Button EightButton => new Button(this.Children.Find(EightButtonId));
|
||||||
|
|
||||||
|
public Button NineButton => new Button(this.Children.Find(NineButtonId));
|
||||||
|
|
||||||
|
public Button DecimalButton => new Button(this.Children.Find(DecimalButtonId));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Calculator.UIAutomationLibrary")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("D6913DAD-1C3B-4229-915F-8301A57970FC")]
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Etw.Managed;
|
||||||
|
using Calculator.UIAutomationLibrary.Components;
|
||||||
|
using WEX.TestExecution;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Tests
|
||||||
|
{
|
||||||
|
public static class BasicCalculationTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This test uses LFMs to add and then delete an alarm.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="calculatorAppLfm">The LFM for the alarms app window.</param>
|
||||||
|
public static void CalculateOnePlusTwo(this CalculatorAppLfm calculatorAppLfm)
|
||||||
|
{
|
||||||
|
var mainPage = calculatorAppLfm.MainPageLfm;
|
||||||
|
|
||||||
|
var standardCalculator = mainPage.NavigateToStandardCalculator();
|
||||||
|
|
||||||
|
standardCalculator.OnePlusTwoEnter();
|
||||||
|
|
||||||
|
Verify.AreEqual("\u202D3\u202C", standardCalculator.ObjectModel.Display.Name, "Ensure display value is 3");
|
||||||
|
|
||||||
|
standardCalculator.Clear();
|
||||||
|
|
||||||
|
Verify.AreEqual("\u202D0\u202C", standardCalculator.ObjectModel.Display.Name, "Ensure display value is 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Calculator.UIAutomationLibrary.Components;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WEX.TestExecution;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary.Tests
|
||||||
|
{
|
||||||
|
public static class ScientificCalculationTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This test uses LFMs to calculate the sqrt(4) - 2.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="calculatorAppLfm">The LFM for the calculator app window.</param>
|
||||||
|
public static void CalculateSqrt4Minus2(this CalculatorAppLfm calculatorAppLfm)
|
||||||
|
{
|
||||||
|
var mainPage = calculatorAppLfm.MainPageLfm;
|
||||||
|
|
||||||
|
var scientificCalculator = mainPage.NavigateToScientificCalculator();
|
||||||
|
|
||||||
|
scientificCalculator.Press4();
|
||||||
|
scientificCalculator.PressSqrt();
|
||||||
|
scientificCalculator.PressMinus();
|
||||||
|
scientificCalculator.Press3();
|
||||||
|
scientificCalculator.PressPlus();
|
||||||
|
scientificCalculator.Press1();
|
||||||
|
scientificCalculator.PressEquals();
|
||||||
|
|
||||||
|
Verify.AreEqual("\u202D0\u202C", scientificCalculator.ObjectModel.Display.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
100
internal/Calculator.UIAutomationLibrary/Utilities/Constants.cs
Normal file
100
internal/Calculator.UIAutomationLibrary/Utilities/Constants.cs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The path to the certificate file.
|
||||||
|
/// </summary>
|
||||||
|
public const string CertificateFileName = @"Calculator.cer";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path to the appxbundle file.
|
||||||
|
/// </summary>
|
||||||
|
public const string PackageFileName = @"Calculator.appxbundle";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path to the appxbundle file.
|
||||||
|
/// </summary>
|
||||||
|
public const string VCLibsPackageFileName = @"Microsoft.VCLibs.appx";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path to the appxbundle file.
|
||||||
|
/// </summary>
|
||||||
|
public const string WinUIPackageFileName = @"Microsoft.UI.Xaml.appx";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the CoreWindow.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppWindowName = "Calculator";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the process executable.
|
||||||
|
/// </summary>
|
||||||
|
public const string ProcessName = "Calculator.exe";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The package name.
|
||||||
|
/// </summary>
|
||||||
|
public const string PackageName = "Microsoft.WindowsCalculator";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The package family name for the app to test.
|
||||||
|
/// </summary>
|
||||||
|
public const string PackageFamilyName = PackageName + "_8wekyb3d8bbwe";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The package App User Model Id.
|
||||||
|
/// </summary>
|
||||||
|
public const string PackageAppUserModelId = PackageFamilyName + "!App";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AutomationId for the top level UI element.
|
||||||
|
/// </summary>
|
||||||
|
public const string TopLevelWindowAutomationId = "CalculatorWindow";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the first page is loaded.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppLaunchEndETWEventName = "AppLaunchEnd";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// App Provider GUID for ETW Events
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Guid CalculatorETWProviderGUID = new Guid("0905CA09-610E-401E-B650-2F212980B9E0");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when a calculator mode change is complete.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppModeChangeEndETWEventName = "ModeChangeEnd";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the History panel is opened by flyout or by changing pivot tabs.
|
||||||
|
/// </summary>
|
||||||
|
public const string HistoryBodyOpenedETWEventName = "HistoryBodyOpened";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the Memory panel is opened by flyout or by changing pivot tabs.
|
||||||
|
/// </summary>
|
||||||
|
public const string MemoryBodyOpenedETWEventName = "MemoryBodyOpened";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the About flyout control is loaded.
|
||||||
|
/// </summary>
|
||||||
|
public const string AboutFlyoutOpenedETWEventName = "AboutFlyoutOpened";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the Nav Bar control is opened.
|
||||||
|
/// </summary>
|
||||||
|
public const string NavBarOpenedETWEventName = "NavBarOpened";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Margin used to click in the gutter beneath the History and Memory lists
|
||||||
|
/// </summary>
|
||||||
|
public const int ClickMargin = 10;
|
||||||
|
}
|
||||||
|
}
|
101
internal/Calculator.UIAutomationLibrary/Utilities/EtwHelper.cs
Normal file
101
internal/Calculator.UIAutomationLibrary/Utilities/EtwHelper.cs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.OneCoreUap.Test.AppModel;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class EtwHelper
|
||||||
|
{
|
||||||
|
private static bool etwServiceWasInstalled = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Installs and starts the Etw.Service so that Tests may utilize Etw Waiters.
|
||||||
|
/// Wex.Services.exe is part of TAEF.
|
||||||
|
/// </summary>
|
||||||
|
public static void InstallAndStartETWService()
|
||||||
|
{
|
||||||
|
etwServiceWasInstalled = ServiceHelper.IsInstalled("Etw.Service");
|
||||||
|
if (!etwServiceWasInstalled)
|
||||||
|
{
|
||||||
|
string wexServices = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), "Wex.Services.exe");
|
||||||
|
if (!File.Exists(wexServices))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(wexServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Comment("Attempting to install Etw.Service...");
|
||||||
|
var startInfo = new ProcessStartInfo();
|
||||||
|
startInfo.FileName = wexServices;
|
||||||
|
startInfo.Arguments = "/install:Etw.Service";
|
||||||
|
|
||||||
|
var process = new Process();
|
||||||
|
process.StartInfo = startInfo;
|
||||||
|
if (process.Start())
|
||||||
|
{
|
||||||
|
process.WaitForExit();
|
||||||
|
Log.Comment("Completed installation of Etw.Service");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("ETW service was not able to be installed. Process didn't start.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Comment("Attempting to start Etw.Service...");
|
||||||
|
ServiceHelper.Start("Etw.Service");
|
||||||
|
Log.Comment("Etw.Service started");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the Etw.Service.
|
||||||
|
/// </summary>
|
||||||
|
public static void StopAndRemoveETWService()
|
||||||
|
{
|
||||||
|
if (ServiceHelper.IsInstalled("Etw.Service"))
|
||||||
|
{
|
||||||
|
Log.Comment("Attempting to stop Etw.Service...");
|
||||||
|
ServiceHelper.Stop("Etw.Service");
|
||||||
|
Log.Comment("Etw.Service stopped");
|
||||||
|
|
||||||
|
// if we installed the Etw.Service as part of this test we should also remove it.
|
||||||
|
// This prevents cases where TDP is upgraded but the service tregistration is referencing the old
|
||||||
|
// location that no longer exists.
|
||||||
|
if (!etwServiceWasInstalled)
|
||||||
|
{
|
||||||
|
|
||||||
|
string wexServices = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), "Wex.Services.exe");
|
||||||
|
if (!File.Exists(wexServices))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(wexServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Comment("Attempting to remove Etw.Service...");
|
||||||
|
var startInfo = new ProcessStartInfo();
|
||||||
|
startInfo.FileName = wexServices;
|
||||||
|
startInfo.Arguments = "/remove:Etw.Service";
|
||||||
|
|
||||||
|
var process = new Process();
|
||||||
|
process.StartInfo = startInfo;
|
||||||
|
if (process.Start())
|
||||||
|
{
|
||||||
|
process.WaitForExit();
|
||||||
|
Log.Comment("Completed removal of Etw.Service");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("ETW service could not be removed. Process didn't start.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public static class Impersonater
|
||||||
|
{
|
||||||
|
public static void RunAs(RunAsUser user, Action action)
|
||||||
|
{
|
||||||
|
IntPtr errorInfo;
|
||||||
|
SafeAccessTokenHandle restrictedToken;
|
||||||
|
GetRunAsUserToken getRunAsUserToken = ResolveGetRunAsUserTokenMethod();
|
||||||
|
Marshal.ThrowExceptionForHR(getRunAsUserToken(user, out restrictedToken, out errorInfo), errorInfo);
|
||||||
|
|
||||||
|
WindowsIdentity.RunImpersonated(restrictedToken, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RunAs<T>(RunAsUser user, Func<T> function)
|
||||||
|
{
|
||||||
|
IntPtr errorInfo;
|
||||||
|
SafeAccessTokenHandle restrictedToken;
|
||||||
|
GetRunAsUserToken getRunAsUserToken = ResolveGetRunAsUserTokenMethod();
|
||||||
|
Marshal.ThrowExceptionForHR(getRunAsUserToken(user, out restrictedToken, out errorInfo), errorInfo);
|
||||||
|
|
||||||
|
WindowsIdentity.RunImpersonated(restrictedToken, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From: https://microsoft.visualstudio.com/EngSys/_git/validation.taef?path=%2Fsrc%2FTAEF%2FCommon%2FPublished%2FRunAsFromSystem.h&version=GBdevelop
|
||||||
|
public enum RunAsUser
|
||||||
|
{
|
||||||
|
ElevatedUser,
|
||||||
|
User,
|
||||||
|
RestrictedUser,
|
||||||
|
LowIL,
|
||||||
|
InteractiveUser,
|
||||||
|
};
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
private delegate int GetRunAsUserToken(RunAsUser user, out SafeAccessTokenHandle token, out IntPtr errorInfo);
|
||||||
|
|
||||||
|
// GetRunAsUserToken is defined in a namespace so we have to do some tricks to use P/Invoke.
|
||||||
|
// We got the actual exported method name by running dumpbin /exports TE.Common.dll
|
||||||
|
private static GetRunAsUserToken ResolveGetRunAsUserTokenMethod()
|
||||||
|
{
|
||||||
|
IntPtr teCommonDll = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
teCommonDll = LoadLibrary(@"TE.Common.dll");
|
||||||
|
|
||||||
|
IntPtr x64GetRunAsUserToken = GetProcAddress(teCommonDll, "?GetRunAsUserToken@TestExecution@WEX@@YAJW4RunAsUser@12@PEAPEAXPEAPEAUIErrorInfo@@@Z");
|
||||||
|
if (x64GetRunAsUserToken != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return Marshal.GetDelegateForFunctionPointer<GetRunAsUserToken>(x64GetRunAsUserToken);
|
||||||
|
}
|
||||||
|
IntPtr x86GetRunAsUserToken = GetProcAddress(teCommonDll, "?GetRunAsUserToken@TestExecution@WEX@@YGJW4RunAsUser@12@PAPAXPAPAUIErrorInfo@@@Z");
|
||||||
|
if (x86GetRunAsUserToken != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return Marshal.GetDelegateForFunctionPointer<GetRunAsUserToken>(x86GetRunAsUserToken);
|
||||||
|
}
|
||||||
|
IntPtr armGetRunAsUserToken = GetProcAddress(teCommonDll, "?GetRunAsUserToken@TestExecution@WEX@@YAJW4RunAsUser@12@PAPAXPAPAUIErrorInfo@@@Z");
|
||||||
|
if (armGetRunAsUserToken != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return Marshal.GetDelegateForFunctionPointer<GetRunAsUserToken>(armGetRunAsUserToken);
|
||||||
|
}
|
||||||
|
IntPtr arm64GetRunAsUserToken = GetProcAddress(teCommonDll, "?GetRunAsUserToken@TestExecution@WEX@@YAJW4RunAsUser@12@PEAPEAXPEAPEAUIErrorInfo@@@Z");
|
||||||
|
if (arm64GetRunAsUserToken != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return Marshal.GetDelegateForFunctionPointer<GetRunAsUserToken>(arm64GetRunAsUserToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unable to find the GetRunAsUserToken function in DLL 'TE.Common.dll'");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (teCommonDll != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
FreeLibrary(teCommonDll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern bool FreeLibrary(IntPtr hModule);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.OneCoreUap.Test.AppModel;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Management.Deployment;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class InstallHelper
|
||||||
|
{
|
||||||
|
public static void InstallCertFile(string certFilePath)
|
||||||
|
{
|
||||||
|
// Ensure cert exists.
|
||||||
|
if (!File.Exists(certFilePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(certFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For some reason, attempting to use CertificateHelper.InstallFromSignedPackage() to install
|
||||||
|
// the certificate associated with the appx package fails with the error:
|
||||||
|
// "A certificate chain could not be built to a trusted root authority."
|
||||||
|
// The reason is that the cert needs to be installed in 'StoreName.TrustedPeople',
|
||||||
|
// but DeploymentHelper.AddPackage() attempts to install it in 'StoreName.Root'.
|
||||||
|
// Therefore, the cert has been installed manually beforehand.
|
||||||
|
Log.Comment($"Starting install of certificate at {certFilePath}");
|
||||||
|
|
||||||
|
X509Certificate2 certificate = new X509Certificate2(certFilePath);
|
||||||
|
X509Store trustedPeopleStore = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine);
|
||||||
|
trustedPeopleStore.Open(OpenFlags.MaxAllowed);
|
||||||
|
trustedPeopleStore.Add(certificate);
|
||||||
|
|
||||||
|
Log.Comment($"Completed install of certificate");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Upgrades the appx/appxbundle from the path if needed.
|
||||||
|
/// </summary>
|
||||||
|
public static void InstallPackage(string appxFilePath, params string[] dependencyAppxFilePaths)
|
||||||
|
{
|
||||||
|
// Ensure the files exist.
|
||||||
|
if (!File.Exists(appxFilePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(appxFilePath);
|
||||||
|
}
|
||||||
|
foreach (var path in dependencyAppxFilePaths.Where(p => !File.Exists(p)))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Comment($"Starting install of app package at {appxFilePath}");
|
||||||
|
|
||||||
|
PackageManager packageManager = new PackageManager();
|
||||||
|
var deploymentOperation = packageManager.AddPackageAsync(
|
||||||
|
new Uri(appxFilePath),
|
||||||
|
dependencyAppxFilePaths.Select(d => new Uri(d)),
|
||||||
|
DeploymentOptions.ForceApplicationShutdown | DeploymentOptions.ForceTargetApplicationShutdown | DeploymentOptions.ForceUpdateFromAnyVersion);
|
||||||
|
|
||||||
|
WaitForDeploymentOperation(deploymentOperation);
|
||||||
|
|
||||||
|
Log.Comment("Completed install of app package");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Waits for a deployment operation to complete
|
||||||
|
/// </summary>
|
||||||
|
private static void WaitForDeploymentOperation(IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> operation)
|
||||||
|
{
|
||||||
|
ManualResetEvent isCompletedEvent = new ManualResetEvent(false);
|
||||||
|
operation.Completed = (IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> asyncInfo, AsyncStatus asyncStatus) =>
|
||||||
|
{
|
||||||
|
isCompletedEvent.Set();
|
||||||
|
};
|
||||||
|
|
||||||
|
isCompletedEvent.WaitOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
internal static class NativeMethods
|
||||||
|
{
|
||||||
|
internal const int GW_OWNER = 4;
|
||||||
|
|
||||||
|
internal delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern int GetWindowTextLength(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern bool IsWindowVisible(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-ntuser-ie-window-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool StartService(IntPtr hService, int dwNumServiceArgs, string[] lpServiceArgVectors);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool ControlService(IntPtr hService, SERVICE_CONTROL dwControl, ref SERVICE_STATUS lpServiceStatus);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll")]
|
||||||
|
internal static extern IntPtr OpenSCManager(string machineName, string databaseName, uint dwAccess);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool CloseServiceHandle(IntPtr hSCObject);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
|
||||||
|
|
||||||
|
[DllImport("api-ms-win-service-management-l1-1-0.dll", SetLastError = true)]
|
||||||
|
internal static extern bool QueryServiceStatus(IntPtr hService, ref SERVICE_STATUS dwServiceStatus);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
internal struct SERVICE_STATUS
|
||||||
|
{
|
||||||
|
public int dwServiceType;
|
||||||
|
public int dwCurrentState;
|
||||||
|
public int dwControlsAccepted;
|
||||||
|
public int dwWin32ExitCode;
|
||||||
|
public int dwServiceSpecificExitCode;
|
||||||
|
public int dwCheckPoint;
|
||||||
|
public int dwWaitHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static uint STANDARD_RIGHTS_REQUIRED = 0xF0000;
|
||||||
|
|
||||||
|
internal static uint SC_MANAGER_CONNECT = 0x0001;
|
||||||
|
internal static uint SC_MANAGER_CREATE_SERVICE = 0x0002;
|
||||||
|
internal static uint SC_MANAGER_ENUMERATE_SERVICE = 0x0004;
|
||||||
|
internal static uint SC_MANAGER_LOCK = 0x0008;
|
||||||
|
internal static uint SC_MANAGER_QUERY_LOCK_STATUS = 0x0010;
|
||||||
|
internal static uint SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020;
|
||||||
|
internal static uint SC_MANAGER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
|
||||||
|
SC_MANAGER_CONNECT |
|
||||||
|
SC_MANAGER_CREATE_SERVICE |
|
||||||
|
SC_MANAGER_ENUMERATE_SERVICE |
|
||||||
|
SC_MANAGER_LOCK |
|
||||||
|
SC_MANAGER_QUERY_LOCK_STATUS |
|
||||||
|
SC_MANAGER_MODIFY_BOOT_CONFIG);
|
||||||
|
|
||||||
|
internal static uint SERVICE_QUERY_CONFIG = 0x0001;
|
||||||
|
internal static uint SERVICE_CHANGE_CONFIG = 0x0002;
|
||||||
|
internal static uint SERVICE_QUERY_STATUS = 0x0004;
|
||||||
|
internal static uint SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
|
||||||
|
internal static uint SERVICE_START = 0x0010;
|
||||||
|
internal static uint SERVICE_STOP = 0x0020;
|
||||||
|
internal static uint SERVICE_PAUSE_CONTINUE = 0x0040;
|
||||||
|
internal static uint SERVICE_INTERROGATE = 0x0080;
|
||||||
|
internal static uint SERVICE_USER_DEFINED_CONTROL = 0x0100;
|
||||||
|
internal static uint SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
|
||||||
|
SERVICE_QUERY_CONFIG |
|
||||||
|
SERVICE_CHANGE_CONFIG |
|
||||||
|
SERVICE_QUERY_STATUS |
|
||||||
|
SERVICE_ENUMERATE_DEPENDENTS |
|
||||||
|
SERVICE_START |
|
||||||
|
SERVICE_STOP |
|
||||||
|
SERVICE_PAUSE_CONTINUE |
|
||||||
|
SERVICE_INTERROGATE |
|
||||||
|
SERVICE_USER_DEFINED_CONTROL);
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum SERVICE_CONTROL : uint
|
||||||
|
{
|
||||||
|
STOP = 0x00000001,
|
||||||
|
PAUSE = 0x00000002,
|
||||||
|
CONTINUE = 0x00000003,
|
||||||
|
INTERROGATE = 0x00000004,
|
||||||
|
SHUTDOWN = 0x00000005,
|
||||||
|
PARAMCHANGE = 0x00000006,
|
||||||
|
NETBINDADD = 0x00000007,
|
||||||
|
NETBINDREMOVE = 0x00000008,
|
||||||
|
NETBINDENABLE = 0x00000009,
|
||||||
|
NETBINDDISABLE = 0x0000000A,
|
||||||
|
DEVICEEVENT = 0x0000000B,
|
||||||
|
HARDWAREPROFILECHANGE = 0x0000000C,
|
||||||
|
POWEREVENT = 0x0000000D,
|
||||||
|
SESSIONCHANGE = 0x0000000E
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum SERVICE_STATE : int
|
||||||
|
{
|
||||||
|
SERVICE_STOPPED = 0x00000001,
|
||||||
|
SERVICE_START_PENDING = 0x00000002,
|
||||||
|
SERVICE_STOP_PENDING = 0x00000003,
|
||||||
|
SERVICE_RUNNING = 0x00000004,
|
||||||
|
SERVICE_CONTINUE_PENDING = 0x00000005,
|
||||||
|
SERVICE_PAUSE_PENDING = 0x00000006,
|
||||||
|
SERVICE_PAUSED = 0x00000007
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class PerfConstants
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Path where the regions, wprprofiles and wpaprofiles will be deployed to by the spkg.
|
||||||
|
/// </summary>
|
||||||
|
public const string ConfigDirectory = @"Config\";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Our FunGates source, where we can view test results.
|
||||||
|
/// </summary>
|
||||||
|
public const string FunGatesSource =
|
||||||
|
#if DEBUG
|
||||||
|
"TestSite";
|
||||||
|
#else
|
||||||
|
"Utility Apps Performance Tests";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Windows Performance Recorder profile. These strings must have the config directory prefix.
|
||||||
|
/// For use with the WPRProfileFile test attribute.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppLifecycleWPRProfile = ConfigDirectory + "AppLifecycle.Profile.wprp";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The regions of interest file that contains the events we are interested in measuring.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppLifecycleRegions = ConfigDirectory + "AppLifecycle.regions.xml";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// These are uses with the DataSource test property to specify iteration info.
|
||||||
|
/// </summary>
|
||||||
|
public const string AppLifecycleInterationsSource = "Table:" + ConfigDirectory + "AppLifecycle.Iterations.xml#PerformanceConfigurations";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class ServiceHelper
|
||||||
|
{
|
||||||
|
public static void Start(string serviceName, int timeoutInMilliSeconds = 30000)
|
||||||
|
{
|
||||||
|
IntPtr hService = IntPtr.Zero;
|
||||||
|
IntPtr hSCManager = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hSCManager = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
||||||
|
if (IntPtr.Zero == hSCManager)
|
||||||
|
{
|
||||||
|
throw new Exception($"Start: Cannot Open OpenSCManager, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
hService = NativeMethods.OpenService(hSCManager, serviceName, NativeMethods.SERVICE_ALL_ACCESS);
|
||||||
|
if (IntPtr.Zero == hService)
|
||||||
|
{
|
||||||
|
throw new Exception($"Start: Cannot Open Service, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
||||||
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
||||||
|
{
|
||||||
|
throw new Exception($"Start: Unable to query status of Service, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_RUNNING &&
|
||||||
|
serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_START_PENDING)
|
||||||
|
{
|
||||||
|
if (!NativeMethods.StartService(hService, 0, null))
|
||||||
|
{
|
||||||
|
throw new Exception($"Start: Service cannot be started, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForStatus(hService, NativeMethods.SERVICE_STATE.SERVICE_RUNNING, TimeSpan.FromMilliseconds(timeoutInMilliSeconds));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (IntPtr.Zero != hService)
|
||||||
|
{
|
||||||
|
NativeMethods.CloseServiceHandle(hService);
|
||||||
|
}
|
||||||
|
if (IntPtr.Zero != hSCManager)
|
||||||
|
{
|
||||||
|
NativeMethods.CloseServiceHandle(hSCManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Stop(string serviceName, int timeoutInMilliSeconds = 30000)
|
||||||
|
{
|
||||||
|
IntPtr hSCManager = IntPtr.Zero;
|
||||||
|
IntPtr hService = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hSCManager = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
||||||
|
if (IntPtr.Zero == hSCManager)
|
||||||
|
{
|
||||||
|
throw new Exception($"Stop: Cannot Open OpenSCManager, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
hService = NativeMethods.OpenService(hSCManager, serviceName, NativeMethods.SERVICE_ALL_ACCESS);
|
||||||
|
if (IntPtr.Zero == hService)
|
||||||
|
{
|
||||||
|
throw new Exception($"Stop: Cannot Open Service, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
||||||
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
||||||
|
{
|
||||||
|
throw new Exception($"Stop: Unable to query status of Service, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_STOPPED &&
|
||||||
|
serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_STOP_PENDING)
|
||||||
|
{
|
||||||
|
if (!NativeMethods.ControlService(hService, NativeMethods.SERVICE_CONTROL.STOP, ref serviceStatus))
|
||||||
|
{
|
||||||
|
throw new Exception($"Stop: Service cannot be stopped, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForStatus(hService, NativeMethods.SERVICE_STATE.SERVICE_STOPPED, TimeSpan.FromMilliseconds(timeoutInMilliSeconds));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (IntPtr.Zero != hService)
|
||||||
|
{
|
||||||
|
NativeMethods.CloseServiceHandle(hService);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IntPtr.Zero != hSCManager)
|
||||||
|
{
|
||||||
|
NativeMethods.CloseServiceHandle(hSCManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsInstalled(string svcName)
|
||||||
|
{
|
||||||
|
IntPtr sc_handle = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
||||||
|
if (sc_handle == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new Exception($"IsInstalled: Cannot open service manager, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bResult = false;
|
||||||
|
IntPtr sv_handle = NativeMethods.OpenService(sc_handle, svcName, NativeMethods.SERVICE_QUERY_CONFIG);
|
||||||
|
if (sv_handle.ToInt64() != 0)
|
||||||
|
{
|
||||||
|
bResult = true;
|
||||||
|
NativeMethods.CloseServiceHandle(sv_handle);
|
||||||
|
}
|
||||||
|
NativeMethods.CloseServiceHandle(sc_handle);
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WaitForStatus(IntPtr hService, NativeMethods.SERVICE_STATE desiredStatus, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
Stopwatch swLoop = new Stopwatch();
|
||||||
|
swLoop.Start();
|
||||||
|
|
||||||
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
||||||
|
{
|
||||||
|
throw new Exception($"WaitForStatus: Unable to query status of service, {Marshal.GetLastWin32Error()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (serviceStatus.dwCurrentState != (int)desiredStatus && (swLoop.ElapsedMilliseconds <= timeout.TotalMilliseconds));
|
||||||
|
|
||||||
|
if (serviceStatus.dwCurrentState != (int)desiredStatus)
|
||||||
|
{
|
||||||
|
throw new Exception($"WaitForStatus: Service failed to reach desired state: {desiredStatus}, current state: {serviceStatus.dwCurrentState}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Automation;
|
||||||
|
using MS.Internal.Mita.Foundation;
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using MS.Internal.Mita.Foundation.Waiters;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public static class UIObjectExtensions
|
||||||
|
{
|
||||||
|
private const string NamePropertyName = "Name";
|
||||||
|
private static UICondition CoreWindowCondition = UICondition.CreateFromClassName("Windows.UI.Core.CoreWindow");
|
||||||
|
|
||||||
|
public static Window GetParentCoreWindow(this UIObject uiObject)
|
||||||
|
{
|
||||||
|
if (uiObject.Matches(CoreWindowCondition))
|
||||||
|
{
|
||||||
|
return new Window(uiObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Window(uiObject.Ancestors.Find(CoreWindowCondition));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Window GetTopLevelWindow(this Window window)
|
||||||
|
{
|
||||||
|
var node = window;
|
||||||
|
while (node != null && node.Parent != null && node.Parent.ControlType == ControlType.Window)
|
||||||
|
{
|
||||||
|
node = new Window(node.Parent);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void VerifyParentTreeStructure(this UIObject uiObject)
|
||||||
|
{
|
||||||
|
var node = uiObject;
|
||||||
|
while (node != null && node.Parent != null)
|
||||||
|
{
|
||||||
|
if (!node.Parent.Children.Contains(node))
|
||||||
|
{
|
||||||
|
Log.Comment($"- [VerifyingTree] {node} specifies {node.Parent} as parent but is not part of its children.");
|
||||||
|
}
|
||||||
|
if (!node.Parent.Descendants.Contains(node))
|
||||||
|
{
|
||||||
|
Log.Comment($"- [VerifyingTree] {node} specifies {node.Parent} as parent but is not part of its descendants.");
|
||||||
|
}
|
||||||
|
node = node.Parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool DoesDescendantExist(this UIObject uiObject, string automationId)
|
||||||
|
{
|
||||||
|
UIObject temp;
|
||||||
|
return uiObject.Descendants.TryFind(automationId, out temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PropertyChangedEventWaiter GetNameChangedWaiter(this TextBlock textBlock)
|
||||||
|
{
|
||||||
|
return new PropertyChangedEventWaiter(textBlock, UIProperty.Get(NamePropertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class Utilities
|
||||||
|
{
|
||||||
|
public static void KillExistingCalculatorProcesses()
|
||||||
|
{
|
||||||
|
Log.Comment("Killing any existing Calculator processes");
|
||||||
|
|
||||||
|
foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Constants.ProcessName)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
Log.Comment($"Killed {process.ProcessName}, Id: {process.Id}");
|
||||||
|
}
|
||||||
|
catch (Exception) when (process.HasExited)
|
||||||
|
{
|
||||||
|
Log.Comment($"{process.ProcessName}, Id: {process.Id} already exited.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using MS.Internal.Mita.Foundation.Controls;
|
||||||
|
using WEX.Logging.Interop;
|
||||||
|
|
||||||
|
namespace Calculator.UIAutomationLibrary
|
||||||
|
{
|
||||||
|
public class WindowHelper
|
||||||
|
{
|
||||||
|
public static void SetAsForeground(Window window)
|
||||||
|
{
|
||||||
|
Log.Comment($"Set window {window.NativeWindowHandle} as the foreground window.");
|
||||||
|
|
||||||
|
NativeMethods.SetForegroundWindow(window.NativeWindowHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
internal/Calculator.UIAutomationLibrary/project.json
Normal file
12
internal/Calculator.UIAutomationLibrary/project.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"AppModel.TestHelper": "2018.3.22",
|
||||||
|
"EtwProcessor.Managed": "10.34.181220007",
|
||||||
|
"MITALite": "1.0.180128001",
|
||||||
|
"Taef.Managed": "10.34.181220007",
|
||||||
|
"Test.Net.Redist": "2.0.1"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcore50": {}
|
||||||
|
}
|
||||||
|
}
|
145
internal/Calculator.UITests/Calculator.UITests.csproj
Normal file
145
internal/Calculator.UITests/Calculator.UITests.csproj
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<ProjectGuid>{0224A709-0C48-4C4F-BA17-843A49842C15}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Calculator.UITests</RootNamespace>
|
||||||
|
<AssemblyName>Calculator.UITests</AssemblyName>
|
||||||
|
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||||
|
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||||
|
<NuGetTargetMoniker>.NETCore,Version=v5.0</NuGetTargetMoniker>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17763.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<CopyNuGetImplementations>true</CopyNuGetImplementations>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\x86</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\x86</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\x64</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\x64</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\arm</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\arm</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM64' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\ARM64\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM64' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\ARM64\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Initialization.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Tests\AppLifecycleTests.cs" />
|
||||||
|
<Compile Include="Tests\CalculatorTests.cs" />
|
||||||
|
<Compile Include="Tests\LaunchTests.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Config\AppLifecycle.Profile.wprp">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Config\AppLifecycle.Regions.tt">
|
||||||
|
<Generator>TextTemplatingFileGenerator</Generator>
|
||||||
|
<LastGenOutput>AppLifecycle.Regions.xml</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Config\AppLifecycle.Regions.xml">
|
||||||
|
<DependentUpon>AppLifecycle.Regions.tt</DependentUpon>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Content>
|
||||||
|
<None Include="project.json" />
|
||||||
|
<None Include="testmd.definition" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Calculator.UIAutomationLibrary\Calculator.UIAutomationLibrary.csproj">
|
||||||
|
<Project>{a43517b5-8be3-4312-913f-004978c34444}</Project>
|
||||||
|
<Name>Calculator.UIAutomationLibrary</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Config\AppLifecycle.Iterations.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0' ">
|
||||||
|
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file defines a table of preformance configuration for use with
|
||||||
|
TAEF Table Based Data-driven Testing.
|
||||||
|
|
||||||
|
This table specifies we will run the test three times (each iteration has a
|
||||||
|
unique name to identify the scenario) with different parameters each time.
|
||||||
|
We use the same region file for WinPerf but we specify different WPR profiles
|
||||||
|
to capture ETW events from different providers, focusing on responsiveness for
|
||||||
|
launch runs and on memory for one diagnostic memory run.
|
||||||
|
|
||||||
|
The warm run is the one we are primarily interested in for startup performance.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Data>
|
||||||
|
<Table Id="PerformanceConfigurations">
|
||||||
|
<Row Name="Cold"
|
||||||
|
WinPerf.FriendlyAutomationName="AppLifecycle_Responsiveness_Cold"
|
||||||
|
WinPerf.Iterations="1"
|
||||||
|
WinPerf.WPRProfile="Config\AppLifecycle.Profile.wprp"
|
||||||
|
WinPerf.WPRProfileId="AppLifecycle.Responsiveness.Diagnostic.Verbose.File"
|
||||||
|
WinPerf.Regions="Config\AppLifecycle.Regions.xml">
|
||||||
|
</Row>
|
||||||
|
<Row Name="Warm"
|
||||||
|
WinPerf.FriendlyAutomationName="AppLifecycle_Responsiveness_Warm"
|
||||||
|
WinPerf.Iterations="10"
|
||||||
|
WinPerf.WPRProfile="Config\AppLifecycle.Profile.wprp"
|
||||||
|
WinPerf.WPRProfileId="AppLifecycle.Responsiveness.Diagnostic.Verbose.Memory"
|
||||||
|
WinPerf.Regions="Config\AppLifecycle.Regions.xml">
|
||||||
|
</Row>
|
||||||
|
<Row Name="Memory"
|
||||||
|
WinPerf.FriendlyAutomationName="AppLifecycle_Memory"
|
||||||
|
WinPerf.Iterations="1"
|
||||||
|
WinPerf.WPRProfile="Config\AppLifecycle.Profile.wprp"
|
||||||
|
WinPerf.WPRProfileId="AppLifecycle.Memory.Diagnostic.Verbose.File"
|
||||||
|
WinPerf.Regions="Config\AppLifecycle.Regions.xml">
|
||||||
|
</Row>
|
||||||
|
</Table>
|
||||||
|
</Data>
|
526
internal/Calculator.UITests/Config/AppLifecycle.Profile.wprp
Normal file
526
internal/Calculator.UITests/Config/AppLifecycle.Profile.wprp
Normal file
|
@ -0,0 +1,526 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
|
This WPRP (WPR profile) contains the App Life Cycle settings for Mobile and Client Performance Gates (MPG and CPG).
|
||||||
|
Since the appcycle automations are currently still separate, any changes here should be made in two places to keep these wprp's in sync.
|
||||||
|
CPG: base\PerfTest\MemRe\AppLifecycle\Common\AppLifeCycle.wprp
|
||||||
|
MPG: wm\src\tools\Product\DH\Test\PerfWorkloads\AppLifeCycle\AppLifeCycle.wprp
|
||||||
|
|
||||||
|
Prefixes in the WPRP:
|
||||||
|
SC_ - System Collector controlling kernel event tracing
|
||||||
|
EC_ - Event Collector controlling user mode event tracing
|
||||||
|
|
||||||
|
SP_ - System Provider
|
||||||
|
|
||||||
|
EP_ - Event Provider
|
||||||
|
|
||||||
|
There are two separate traces - Responsiveness and Memory.
|
||||||
|
Within that, we have Light tracing which is for official gating metrics/traces, and we have Verbose tracing, which is for Diagnostic metrics\traces.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<WindowsPerformanceRecorder Version="1.0" Comments="Test" Company="Microsoft Corporation" Copyright="Microsoft Corporation">
|
||||||
|
<Profiles>
|
||||||
|
<!-- BufferSizes are in KB in WPRP -->
|
||||||
|
|
||||||
|
<!-- System Collectors -->
|
||||||
|
<SystemCollector Id="SC_Responsiveness.LowCost.Light" Name="NT Kernel Resposiveness Logger LowCost Light">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="3" PercentageOfTotalMemory="true" MaximumBufferSpace="30" />
|
||||||
|
</SystemCollector>
|
||||||
|
|
||||||
|
<SystemCollector Id="SC_Responsiveness.LowCost" Name="NT Kernel Resposiveness Logger LowCost">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="35" />
|
||||||
|
</SystemCollector>
|
||||||
|
|
||||||
|
<SystemCollector Id="SC_Responsiveness.HighCost.Verbose" Name="NT Kernel Resposiveness Logger HighCost Verbose">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="7" PercentageOfTotalMemory="true" MaximumBufferSpace="140" />
|
||||||
|
</SystemCollector>
|
||||||
|
|
||||||
|
<SystemCollector Id="SC_Memory.LowCost.Light" Name="NT Kernel Memory Logger LowCost Light">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="35" />
|
||||||
|
</SystemCollector>
|
||||||
|
|
||||||
|
<SystemCollector Id="SC_Memory.HighCost.Verbose" Name="NT Kernel Memory Logger LowCost Light">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="75" />
|
||||||
|
</SystemCollector>
|
||||||
|
|
||||||
|
<!-- Event Collectors -->
|
||||||
|
<EventCollector Id="EC_Responsiveness.LowCost.Light" Name="User Session Logger LowCost Light">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="2" PercentageOfTotalMemory="true" MaximumBufferSpace="20"/>
|
||||||
|
</EventCollector>
|
||||||
|
|
||||||
|
<EventCollector Id="EC_Responsiveness.LowCost.Light.UTC" Name="User Session Logger LowCost Light UTC">
|
||||||
|
<BufferSize Value="1024"/>
|
||||||
|
<Buffers Value="5"/>
|
||||||
|
</EventCollector>
|
||||||
|
|
||||||
|
<EventCollector Id="EC_Responsiveness.LowCost" Name="User Session Logger LowCost">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="15" />
|
||||||
|
</EventCollector>
|
||||||
|
|
||||||
|
<EventCollector Id="EC_Responsiveness.HighCost.Verbose" Name="User Session Logger Higcost Verbose">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="3" PercentageOfTotalMemory="true" MaximumBufferSpace="60" />
|
||||||
|
</EventCollector>
|
||||||
|
|
||||||
|
<EventCollector Id="EC_Memory.LowCost.Light" Name="User Session Logger LowCost Light">
|
||||||
|
<BufferSize Value="1024" />
|
||||||
|
<Buffers Value="30" />
|
||||||
|
</EventCollector>
|
||||||
|
|
||||||
|
<!-- System Providers for collecting kernel events. -->
|
||||||
|
<SystemProvider Id="SP_Responsiveness.Light">
|
||||||
|
<Keywords Operation="Add">
|
||||||
|
<Keyword Value="CompactCSwitch"/>
|
||||||
|
<Keyword Value="CSwitch"/>
|
||||||
|
<Keyword Value="DiskIO"/>
|
||||||
|
<Keyword Value="ProcessThread"/>
|
||||||
|
<Keyword Value="Loader"/>
|
||||||
|
</Keywords>
|
||||||
|
</SystemProvider>
|
||||||
|
<SystemProvider Id="SP_Responsiveness" Base="SP_Responsiveness.Light">
|
||||||
|
<Keywords Operation="Add">
|
||||||
|
<Keyword Value="HardFaults"/>
|
||||||
|
<Keyword Value="MemoryInfo"/>
|
||||||
|
<Keyword Value="ReadyThread"/>
|
||||||
|
<Keyword Value="SampledProfile"/>
|
||||||
|
<Keyword Value="Session"/>
|
||||||
|
<Keyword Value="VAMap"/>
|
||||||
|
<Keyword Value="DPC"/>
|
||||||
|
<Keyword Value="Power"/>
|
||||||
|
</Keywords>
|
||||||
|
<Stacks Operation="Add">
|
||||||
|
<Stack Value="CSwitch"/>
|
||||||
|
<Stack Value="ReadyThread"/>
|
||||||
|
<Stack Value="SampledProfile"/>
|
||||||
|
</Stacks>
|
||||||
|
</SystemProvider>
|
||||||
|
<SystemProvider Id="SP_Memory.Light" Base="SP_Responsiveness.Light" >
|
||||||
|
<Keywords Operation="Add">
|
||||||
|
<Keyword Value="Memory"/>
|
||||||
|
<Keyword Value="MemoryInfo"/>
|
||||||
|
<Keyword Value="HardFaults"/>
|
||||||
|
<Keyword Value="ReferenceSet"/>
|
||||||
|
<Keyword Value="VirtualAllocation"/>
|
||||||
|
</Keywords>
|
||||||
|
</SystemProvider>
|
||||||
|
<SystemProvider Id="SP_Memory" Base="SP_Responsiveness" >
|
||||||
|
<Keywords Operation="Add">
|
||||||
|
<Keyword Value="FootPrint"/>
|
||||||
|
<Keyword Value="Memory"/>
|
||||||
|
<Keyword Value="MemoryInfoWS"/>
|
||||||
|
<Keyword Value="ReferenceSet"/>
|
||||||
|
<Keyword Value="VirtualAllocation"/>
|
||||||
|
</Keywords>
|
||||||
|
<Stacks Operation="Add">
|
||||||
|
<Stack Value="HeapCreate" />
|
||||||
|
<Stack Value="ImageLoad" />
|
||||||
|
<Stack Value="PageAccess" />
|
||||||
|
<Stack Value="PageAccessEx" />
|
||||||
|
<Stack Value="PagefileMappedSectionCreate" />
|
||||||
|
<Stack Value="PagefileMappedSectionDelete" />
|
||||||
|
<Stack Value="PageRangeAccess" />
|
||||||
|
<Stack Value="PageRangeRelease" />
|
||||||
|
<Stack Value="PageRelease" />
|
||||||
|
<Stack Value="PageRemovedfromWorkingSet" />
|
||||||
|
<Stack Value="VirtualAllocation" />
|
||||||
|
<Stack Value="VirtualFree" />
|
||||||
|
</Stacks>
|
||||||
|
</SystemProvider>
|
||||||
|
<!-- Start - AppLaunch.wprp -->
|
||||||
|
<EventProvider Id="EP_UTC" Name="UTC" NonPagedMemory="true" Level="4" />
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsPhone-AppPlatProvider" Name="3C42000F-CC27-48C3-A005-48F6E38B131F" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_XNA" Name="CD698436-A3E3-4607-BB60-0BAC4D765B59" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_TaskHost" Name="5CBDF2A5-7290-4ACC-B8A7-9BA285BEBC39" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsPhone-Silverlight" Name="AA087E0E-0B35-4e28-8F3A-440C3F51EEF1" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Device-Health-Etw" Name="F7A8FD9F-8FFD-482f-86C0-4C19240F334C" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsMobile-Compositor" Name="85FFFBA1-CF12-402c-B9B3-29A3217BB007" Level="5">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xfffffff" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsMobile-Splash" Name="872c8950-0def-4d5b-83f6-57dd027f88ce" Level="4">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xfffffff" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsMobile-UIXMobile" Name="0C0FFEE0-F4B1-4F4D-B591-FB3175B13413">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xE" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsMobile-StartMenu" Name="BECF83FD-D220-4b19-B7C1-C9127307F6B1" Level="5">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xfffffff" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-EventTracing" Name="b675ec37-bdb6-4648-bc92-f3fdc74d3ca2" Level="5">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x50" />
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave>
|
||||||
|
<Keyword Value="0x50" />
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsPhone-MobileUI" Name="F243DC34-205E-4d34-94CA-36E8C0859787" Level="5">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xfffffff" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Process" Name="2839ff94-8f12-4e1b-82e3-af7af77a450f" NonPagedMemory="true" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-TestExecution" Name="Microsoft-Windows-TestExecution" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.Windows.WinPerf" Name="BE6F04EA-3488-4543-8082-24843EAEC303" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Shell-Launcher" Name="*Microsoft-Windows-Shell-Launcher" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Immersive-Shell" Name="315A8872-923E-4EA2-9889-33CD4754BF64" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-XAML-Light" Name="531A35AB-63CE-4BCF-AA98-F88C7A89E455" Level="4" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-XAML-Verbose" Name="531A35AB-63CE-4BCF-AA98-F88C7A89E455" Level="5" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-ProcessLifetimeManager" Name="*Microsoft.Windows.ProcessLifetimeManager" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Desktop-ApplicationFrame" Name="678e492b-5de1-50c5-7219-ae4aa7d6a141" Level="5" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Microsoft-Phone-AppLifecycle" Name="f623a8ef-84da-4640-8917-fd5b0f847f28" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsPhone-CoreUIComponents" Name="a0b7550f-4e9a-4f03-ad41-b8042d06a2f7" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-AppModel-Exec" Name="EB65A492-86C0-406A-BACE-9912D595BD69" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.Windows.ActivationManager" Name="cf7f94b3-08dc-5257-422f-497d7dc86ab3">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-WindowsMobile-ExecManLogPublisher" Name="82c8ad90-5f3c-11be-bd9a-85bb5f50dfa4" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Shell-CortanaSearch" Name="E34441D9-5BCF-4958-B787-3BF824F362D7" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Dwm-Core" Name="9e9bba3c-2e38-40cb-99f4-9e8281425164" Level="4" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x2000C"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-ImageLoad" Name="2cb15d1d-5fc1-11d2-abe1-00a0c911f518" >
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x10"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-AppLifeCycle-UI" Name="ee97cdc4-b095-5c70-6e37-a541eb74c2b5" Level="5">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x400000000000"/>
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-AppLifeCycle" Name="ef00584a-2655-462c-bc24-e7de630e7fbf">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0000000000000"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave>
|
||||||
|
<Keyword Value="0x0000000000000"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Power" Name="331C3B3A-2005-44C2-AC5E-77220C37D6B4" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xA4"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave Timeout="0">
|
||||||
|
<Keyword Value="0xA4"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Processor-Power" Name="0f67e49f-fe51-4e9f-b490-6f2948cc6027" NonPagedMemory="true" EventKey="true" Level="4">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0xC2"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave Timeout="0">
|
||||||
|
<Keyword Value="0xC2"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Pep" Name="5412704E-B2E1-4624-8FFD-55777B8F7373" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave Timeout="0">
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Acpi" Name="C514638F-7723-485B-BCFC-96565D735D4A" Level="5" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-UserModePowerService" Name="CE8DEE0B-D539-4000-B0F8-77BED049C590" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</Keywords>
|
||||||
|
<CaptureStateOnSave Timeout="0">
|
||||||
|
<Keyword Value="0x0"/>
|
||||||
|
</CaptureStateOnSave>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.ClipC" Level="0" Name="ed0c10a5-5396-4a96-9ee3-6f4aa0d1120d" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x200000000000" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.ClipSp" Level="0" Name="b4b126de-32fe-4591-9ac5-b0778d79a0e7" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x200000000000" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.ClipSvc" Level="0" Name="b94d76c5-9d56-454a-8d1b-6ca30898160e" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x200000000000" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft.Windows.LicenseManager.Telemetry" Level="0" Name="af9f58ec-0c04-4be9-9eb5-55ff6dbe72d7" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x200000000000" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Win32k" Level="0" Name="8c416c79-d49b-4f01-a467-e56d3aa8234c" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x26A000" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<EventProvider Id="EP_Microsoft-Windows-Kernel-Prefetch" Level="0" Name="Microsoft-Windows-Kernel-Prefetch" NonPagedMemory="true" EventKey="true">
|
||||||
|
<Keywords>
|
||||||
|
<Keyword Value="0x0" />
|
||||||
|
</Keywords>
|
||||||
|
</EventProvider>
|
||||||
|
<!-- End - AppLaunch.wprp -->
|
||||||
|
<Profile Id="AppLifecycle.Responsiveness.Light.File" LoggingMode="File" Name="AppLifecycle.Responsiveness" DetailLevel="Light" Description="App lifecycle responsiveness light to file">
|
||||||
|
<Collectors>
|
||||||
|
<SystemCollectorId Value="SC_Responsiveness.LowCost.Light">
|
||||||
|
<SystemProviderId Value="SP_Responsiveness.Light" />
|
||||||
|
</SystemCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Responsiveness.LowCost.Light">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-TestExecution" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.Windows.WinPerf" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Immersive-Shell"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppLifeCycle" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Shell-Launcher" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-XAML-Light" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppLifeCycle-UI" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Process" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Shell-CortanaSearch"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppModel-Exec"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft.Windows.ActivationManager" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-EventTracing" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Desktop-ApplicationFrame" />
|
||||||
|
<EventProviderId Value="EP_XNA" />
|
||||||
|
<EventProviderId Value="EP_TaskHost" />
|
||||||
|
<EventProviderId Value="EP_Device-Health-Etw" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Microsoft-Phone-AppLifecycle"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-CoreUIComponents"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-AppPlatProvider" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-Silverlight" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-Splash" />
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Responsiveness.LowCost.Light.UTC">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_UTC"/>
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
</Collectors>
|
||||||
|
</Profile>
|
||||||
|
<Profile Id="AppLifecycle.Responsiveness.Diagnostic.Verbose.File" Base="AppLifecycle.Responsiveness.Light.File" LoggingMode="File" Name="AppLifecycle.Responsiveness.Diagnostic" DetailLevel="Verbose" Description="App lifecycle responsiveness verbose to file">
|
||||||
|
<Collectors Operation="Add">
|
||||||
|
<SystemCollectorId Value="SC_Responsiveness.LowCost">
|
||||||
|
<SystemProviderId Value="SP_Responsiveness" />
|
||||||
|
</SystemCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Responsiveness.LowCost">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-XAML-Verbose" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-ExecManLogPublisher"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-Compositor" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-UIXMobile" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-StartMenu" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-MobileUI" />
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
</Collectors>
|
||||||
|
</Profile>
|
||||||
|
<Profile Id="AppLifecycle.Responsiveness.Diagnostic.Verbose.Memory" Base="AppLifecycle.Responsiveness.Light.File" LoggingMode="Memory" Name="AppLifecycle.Responsiveness.Diagnostic" DetailLevel="Verbose" Description="App life cycle responsiveness verbose to memory">
|
||||||
|
<Collectors>
|
||||||
|
<SystemCollectorId Value="SC_Responsiveness.HighCost.Verbose">
|
||||||
|
<SystemProviderId Value="SP_Responsiveness"/>
|
||||||
|
</SystemCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Responsiveness.HighCost.Verbose">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-ProcessLifetimeManager" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Shell-CortanaSearch"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-ExecManLogPublisher"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-Compositor" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-UIXMobile" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-StartMenu" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-MobileUI" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Power" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Processor-Power" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Pep" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Acpi" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-UserModePowerService" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Dwm-Core" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-ImageLoad" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.ClipC" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.ClipSp" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.ClipSvc" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.Windows.LicenseManager.Telemetry" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Win32k" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Prefetch" />
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
</Collectors>
|
||||||
|
</Profile>
|
||||||
|
<Profile Id="AppLifecycle.Memory.Light.File" LoggingMode="File" Name="AppLifecycle.Memory" DetailLevel="Light" Description="App lifecycle memory light to file">
|
||||||
|
<Collectors>
|
||||||
|
<SystemCollectorId Value="SC_Memory.LowCost.Light">
|
||||||
|
<SystemProviderId Value="SP_Memory.Light" />
|
||||||
|
</SystemCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Memory.LowCost.Light">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-TestExecution" />
|
||||||
|
<EventProviderId Value="EP_Microsoft.Windows.WinPerf" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Immersive-Shell"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppModel-Exec"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft.Windows.ActivationManager" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppLifeCycle" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-AppLifeCycle-UI" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-EventTracing" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Desktop-ApplicationFrame" />
|
||||||
|
<EventProviderId Value="EP_XNA" />
|
||||||
|
<EventProviderId Value="EP_TaskHost" />
|
||||||
|
<EventProviderId Value="EP_Device-Health-Etw" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-ExecManLogPublisher"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Microsoft-Phone-AppLifecycle"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-CoreUIComponents"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-AppPlatProvider" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-Silverlight" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-XAML-Light" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-Splash" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Prefetch" />
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Responsiveness.LowCost.Light.UTC">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_UTC"/>
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
</Collectors>
|
||||||
|
</Profile>
|
||||||
|
<Profile Id="AppLifecycle.Memory.Diagnostic.Verbose.File" Base="AppLifecycle.Memory.Light.File" LoggingMode="File" Name="AppLifecycle.Memory.Diagnostic" DetailLevel="Verbose" Description="App lifecycle memory verbose to file">
|
||||||
|
<Collectors Operation="Add">
|
||||||
|
<SystemCollectorId Value="SC_Memory.HighCost.Verbose">
|
||||||
|
<SystemProviderId Value="SP_Memory" />
|
||||||
|
</SystemCollectorId>
|
||||||
|
<EventCollectorId Value="EC_Memory.LowCost.Light">
|
||||||
|
<EventProviders>
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Shell-Launcher" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-XAML-Verbose" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Power" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Processor-Power" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Pep" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Dwm-Core" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-ImageLoad" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Kernel-Process" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-Shell-CortanaSearch"/>
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-Compositor" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-UIXMobile" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsMobile-StartMenu" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-WindowsPhone-MobileUI" />
|
||||||
|
<EventProviderId Value="EP_Microsoft-Windows-ProcessLifetimeManager" />
|
||||||
|
</EventProviders>
|
||||||
|
</EventCollectorId>
|
||||||
|
</Collectors>
|
||||||
|
</Profile>
|
||||||
|
</Profiles>
|
||||||
|
<TraceMergeProperties>
|
||||||
|
<TraceMergeProperty Id="TraceMerge_Default" Name="TraceMerge_Default" Base="">
|
||||||
|
<DeletePreMergedTraceFiles Value="true"/>
|
||||||
|
<CustomEvents>
|
||||||
|
<CustomEvent Value="ImageId"/>
|
||||||
|
<CustomEvent Value="BuildInfo"/>
|
||||||
|
<CustomEvent Value="VolumeMapping"/>
|
||||||
|
<CustomEvent Value="EventMetadata"/>
|
||||||
|
<CustomEvent Value="PerfTrackMetadata"/>
|
||||||
|
<CustomEvent Value="WinSAT"/>
|
||||||
|
<CustomEvent Value="NetworkInterface"/>
|
||||||
|
</CustomEvents>
|
||||||
|
</TraceMergeProperty>
|
||||||
|
</TraceMergeProperties>
|
||||||
|
</WindowsPerformanceRecorder>
|
364
internal/Calculator.UITests/Config/AppLifecycle.Regions.tt
Normal file
364
internal/Calculator.UITests/Config/AppLifecycle.Regions.tt
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
<# // Copyright (c) Microsoft Corporation. All rights reserved. #>
|
||||||
|
<#@ template language="C#" hostspecific="True" #>
|
||||||
|
<#@ output extension=".xml" #>
|
||||||
|
<# // Set options specific to your app here
|
||||||
|
var options = new {
|
||||||
|
RegionPrefix = "Calculator",
|
||||||
|
ImageFileName = "Calculator.exe",
|
||||||
|
PackageFamilyName = "Microsoft.WindowsCalculator",
|
||||||
|
FirstView = "ms-resource:///Files/Views/MainPage.xbf"
|
||||||
|
};
|
||||||
|
#>
|
||||||
|
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Based on:
|
||||||
|
\base\PerfTest\MemRe\AppLifecycle\Common\Regions\Regions_Calculator.xml Regions_Calculator.xml
|
||||||
|
|
||||||
|
This is a regions of interest file that can be used by WPA to get a quick overview of the time
|
||||||
|
spent on a set of operations called "regions".
|
||||||
|
|
||||||
|
A region is defined as the combination of a Start and a Stop event.
|
||||||
|
|
||||||
|
This file contains regions that are of interest for the startup of a UWP app.
|
||||||
|
The first region "<#= options.RegionPrefix #>_AppLifecycle" is defined by the Start and Stop event of the test.
|
||||||
|
Subsequent regions are defined as children of this region to make sure we are only tracking
|
||||||
|
events that occurred during the test.
|
||||||
|
|
||||||
|
The events that are defined as Start and Stop events must come from an event provider that is enabled for the
|
||||||
|
trace that is being analyzed. For WinPerf, that means that the WPR Profile must have these providers enabled.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<?Copyright (c) Microsoft Corporation. All rights reserved.?>
|
||||||
|
<InstrumentationManifest>
|
||||||
|
<Instrumentation>
|
||||||
|
<Regions>
|
||||||
|
<RegionRoot Guid="{7e8672b5-efe5-4862-90f3-944f136d6c75}"
|
||||||
|
Name="<#= options.RegionPrefix #>_AppLifeCycle Region Root"
|
||||||
|
FriendlyName="Root">
|
||||||
|
<Region Guid="{cf6c4996-1dc8-4fc5-b275-7a7051376f77}"
|
||||||
|
Name="<#= options.RegionPrefix #>_AppLifeCycle"
|
||||||
|
FriendlyName="Application Life Cycle Test">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-TestExecution\RunTest_TestRunScope\win:Start -->
|
||||||
|
<Event Provider="{70d27130-f2f3-4365-b790-d31223254ef4}" Name="RunTest_TestRunScope" Opcode="1"/>
|
||||||
|
<!-- Match the name of the test we are running. -->
|
||||||
|
<PayloadIdentifier FieldName="Name" FieldValue="Calculator.PerfTests.AppLifecycleTests.*" FieldValueRelationship="RegEx"/>
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-TestExecution\RunTest_TestRunScope\win:Stop -->
|
||||||
|
<Event Provider="{70d27130-f2f3-4365-b790-d31223254ef4}" Name="RunTest_TestRunScope" Opcode="2"/>
|
||||||
|
<!-- Match the name of the test we are running. -->
|
||||||
|
<PayloadIdentifier FieldName="Name" FieldValue="Calculator.PerfTests.AppLifecycleTests.*" FieldValueRelationship="RegEx"/>
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PayloadBased NameField="Name"/>
|
||||||
|
</Naming>
|
||||||
|
<Region Guid="{b18b32ec-6796-43e1-802f-aec9aea5eb28}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_ProcessStart"
|
||||||
|
FriendlyName="Process Started">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{2839ff94-8f12-4e1b-82e3-af7af77a450f}" Name="ProcessStarted" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="ImageFileName" FieldValue=".*<#= options.ImageFileName #>" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{b1e4255d-131c-4ea8-899d-30b7345bf7d3}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_UIThreadStart"
|
||||||
|
FriendlyName="UI Thread Started">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Ideally use actual thread start event, for now it's just close, using InitializeCore -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="31" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{38084b96-d955-4603-a2c7-2720195ce160}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_InitializeCore"
|
||||||
|
FriendlyName="Create XAML Core">
|
||||||
|
<Start>
|
||||||
|
<!-- Initialize Core Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="31" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Initialize Core Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="32" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{cc909ec4-17c0-4cd9-9a83-293e06e0dc72}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_CreateDevice"
|
||||||
|
FriendlyName="Create Graphics Device">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Device Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="76" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Device Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="77" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{0ed49a01-2604-499e-8003-0878b3b3c61e}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_CreateResourceManager"
|
||||||
|
FriendlyName="Create Resource Manager">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Resource Manager Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="463" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Resource Manager Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="464" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{365920df-10e7-4b6e-8dcb-e769844ac11f}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_CreateWindow"
|
||||||
|
FriendlyName="Create Window">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Window Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="29" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Window Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="30" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{09995446-0266-4a34-aa39-d99467dfe85d}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_InitializeTheme"
|
||||||
|
FriendlyName="Initialize Theme Resources">
|
||||||
|
<Start>
|
||||||
|
<!-- Theme Changed Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="457" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Theme Changed Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="458" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{a2fdff0b-75c8-440d-bb55-b87a3c60d55f}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_NavToFirstFrame"
|
||||||
|
FriendlyName="XAML Navigate To First Frame Drawn">
|
||||||
|
<Start>
|
||||||
|
<!-- Parse XAML -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="1" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="URI" FieldValue="<#= options.FirstView #>" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Frame Drawn -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="65" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
<Match>
|
||||||
|
<Event PID="true"/>
|
||||||
|
</Match>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{ffc47f79-2d90-470a-bfde-0d075972f23b}"
|
||||||
|
Name="<#= options.RegionPrefix #>_ApplicationActivate"
|
||||||
|
FriendlyName="Application Activate">
|
||||||
|
<Start>
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="5901" Version="1" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="5902" Version="1" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{b0c74cf1-16fc-4a33-ba7e-2169727a08d7}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_SplashScreen"
|
||||||
|
FriendlyName="Splash Screen Dismissed">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- NavigationServerTask_SplashScreenDismissed -->
|
||||||
|
<Event Provider="{a0b7550f-4e9a-4f03-ad41-b8042d06a2f7}" Id="1572" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{a1648637-d5ec-46d2-9655-a26d00a35764}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_UIResponsive"
|
||||||
|
FriendlyName="UI Responsive">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{EF00584A-2655-462C-BC24-E7DE630E7FBF}" Name="ModernAppLaunch_UIResponsive" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{74d63c4e-7dd7-4ff6-9ee8-adb462c1c101}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Launch_VisibleComplete"
|
||||||
|
FriendlyName="Visible Complete">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{EF00584A-2655-462C-BC24-E7DE630E7FBF}" Name="ModernAppLaunch_VisibleComplete" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{ec31fb10-992b-438b-8c9e-42454f4b2e5a}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Suspend"
|
||||||
|
FriendlyName="Suspended">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_SuspendApplication\win:Start -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="2450" Version="1" />
|
||||||
|
<PayloadIdentifier FieldName="PsmKey" FieldValueRelationship="RegEx" FieldValue="<#= options.PackageFamilyName #>.*" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_SuspendApplication\win:Stop -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="2451" Version="1" />
|
||||||
|
<PayloadIdentifier FieldName="AppUserModelId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{83735b08-b17e-48cf-82f1-02cb08e45597}"
|
||||||
|
Name="<#= options.RegionPrefix #>_Resume"
|
||||||
|
FriendlyName="Resumed">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_ResumeApplication_EndToEnd\win:Start -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="11118" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="PsmKey" FieldValueRelationship="RegEx" FieldValue="<#= options.PackageFamilyName #>.*" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_ResumeApplication_EndToEnd\win:Stop -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="11119" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="AppUserModelId" FieldValue="<#= options.PackageFamilyName #>.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName><#= options.ImageFileName #></WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
</Region>
|
||||||
|
</RegionRoot>
|
||||||
|
</Regions>
|
||||||
|
</Instrumentation>
|
||||||
|
</InstrumentationManifest>
|
353
internal/Calculator.UITests/Config/AppLifecycle.Regions.xml
Normal file
353
internal/Calculator.UITests/Config/AppLifecycle.Regions.xml
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Based on:
|
||||||
|
\base\PerfTest\MemRe\AppLifecycle\Common\Regions\Regions_Calculator.xml Regions_Calculator.xml
|
||||||
|
|
||||||
|
This is a regions of interest file that can be used by WPA to get a quick overview of the time
|
||||||
|
spent on a set of operations called "regions".
|
||||||
|
|
||||||
|
A region is defined as the combination of a Start and a Stop event.
|
||||||
|
|
||||||
|
This file contains regions that are of interest for the startup of a UWP app.
|
||||||
|
The first region "Calculator_AppLifecycle" is defined by the Start and Stop event of the test.
|
||||||
|
Subsequent regions are defined as children of this region to make sure we are only tracking
|
||||||
|
events that occurred during the test.
|
||||||
|
|
||||||
|
The events that are defined as Start and Stop events must come from an event provider that is enabled for the
|
||||||
|
trace that is being analyzed. For WinPerf, that means that the WPR Profile must have these providers enabled.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<?Copyright (c) Microsoft Corporation. All rights reserved.?>
|
||||||
|
<InstrumentationManifest>
|
||||||
|
<Instrumentation>
|
||||||
|
<Regions>
|
||||||
|
<RegionRoot Guid="{7e8672b5-efe5-4862-90f3-944f136d6c75}"
|
||||||
|
Name="Calculator_AppLifeCycle Region Root"
|
||||||
|
FriendlyName="Root">
|
||||||
|
<Region Guid="{cf6c4996-1dc8-4fc5-b275-7a7051376f77}"
|
||||||
|
Name="Calculator_AppLifeCycle"
|
||||||
|
FriendlyName="Application Life Cycle Test">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-TestExecution\TE_TestRun\win:Start -->
|
||||||
|
<Event Provider="{065903c1-4883-4fb8-b163-d02bd5efc74c}" Id="7" Version="0" />
|
||||||
|
<!-- Match the name of the test we are running. -->
|
||||||
|
<PayloadIdentifier FieldName="Name" FieldValue="Calculator.PerfTests.AppLifecycleTests.*" FieldValueRelationship="RegEx"/>
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-TestExecution\TE_TestRun\win:Stop -->
|
||||||
|
<Event Provider="{065903c1-4883-4fb8-b163-d02bd5efc74c}" Id="8" Version="0" />
|
||||||
|
<!-- Match the name of the test we are running. -->
|
||||||
|
<PayloadIdentifier FieldName="Name" FieldValue="Calculator.PerfTests.AppLifecycleTests.*" FieldValueRelationship="RegEx"/>
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PayloadBased NameField="Name"/>
|
||||||
|
</Naming>
|
||||||
|
<Region Guid="{b18b32ec-6796-43e1-802f-aec9aea5eb28}"
|
||||||
|
Name="Calculator_Launch_ProcessStart"
|
||||||
|
FriendlyName="Process Started">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{2839ff94-8f12-4e1b-82e3-af7af77a450f}" Name="ProcessStarted" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="ImageFileName" FieldValue=".*Calculator.exe" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{b1e4255d-131c-4ea8-899d-30b7345bf7d3}"
|
||||||
|
Name="Calculator_Launch_UIThreadStart"
|
||||||
|
FriendlyName="UI Thread Started">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Ideally use actual thread start event, for now it's just close, using InitializeCore -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="31" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{38084b96-d955-4603-a2c7-2720195ce160}"
|
||||||
|
Name="Calculator_Launch_InitializeCore"
|
||||||
|
FriendlyName="Create XAML Core">
|
||||||
|
<Start>
|
||||||
|
<!-- Initialize Core Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="31" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Initialize Core Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="32" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{cc909ec4-17c0-4cd9-9a83-293e06e0dc72}"
|
||||||
|
Name="Calculator_Launch_CreateDevice"
|
||||||
|
FriendlyName="Create Graphics Device">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Device Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="76" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Device Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="77" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{0ed49a01-2604-499e-8003-0878b3b3c61e}"
|
||||||
|
Name="Calculator_Launch_CreateResourceManager"
|
||||||
|
FriendlyName="Create Resource Manager">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Resource Manager Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="463" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Resource Manager Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="464" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{365920df-10e7-4b6e-8dcb-e769844ac11f}"
|
||||||
|
Name="Calculator_Launch_CreateWindow"
|
||||||
|
FriendlyName="Create Window">
|
||||||
|
<Start>
|
||||||
|
<!-- Create Window Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="29" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Create Window Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="30" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{09995446-0266-4a34-aa39-d99467dfe85d}"
|
||||||
|
Name="Calculator_Launch_InitializeTheme"
|
||||||
|
FriendlyName="Initialize Theme Resources">
|
||||||
|
<Start>
|
||||||
|
<!-- Theme Changed Start -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="457" Version="0" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Theme Changed Stop -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="458" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{a2fdff0b-75c8-440d-bb55-b87a3c60d55f}"
|
||||||
|
Name="Calculator_Launch_NavToFirstFrame"
|
||||||
|
FriendlyName="XAML Navigate To First Frame Drawn">
|
||||||
|
<Start>
|
||||||
|
<!-- Parse XAML -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="1" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="URI" FieldValue="ms-resource:///Files/Views/MainPage.xbf" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Frame Drawn -->
|
||||||
|
<Event Provider="{531A35AB-63CE-4BCF-AA98-F88C7A89E455}" Id="65" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
<Match>
|
||||||
|
<Event PID="true"/>
|
||||||
|
</Match>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{ffc47f79-2d90-470a-bfde-0d075972f23b}"
|
||||||
|
Name="Calculator_ApplicationActivate"
|
||||||
|
FriendlyName="Application Activate">
|
||||||
|
<Start>
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="5901" Version="1" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="5902" Version="1" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{b0c74cf1-16fc-4a33-ba7e-2169727a08d7}"
|
||||||
|
Name="Calculator_Launch_SplashScreen"
|
||||||
|
FriendlyName="Splash Screen Dismissed">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- NavigationServerTask_SplashScreenDismissed -->
|
||||||
|
<Event Provider="{a0b7550f-4e9a-4f03-ad41-b8042d06a2f7}" Id="1572" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{a1648637-d5ec-46d2-9655-a26d00a35764}"
|
||||||
|
Name="Calculator_Launch_UIResponsive"
|
||||||
|
FriendlyName="UI Responsive">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{EF00584A-2655-462C-BC24-E7DE630E7FBF}" Name="ModernAppLaunch_UIResponsive" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{74d63c4e-7dd7-4ff6-9ee8-adb462c1c101}"
|
||||||
|
Name="Calculator_Launch_VisibleComplete"
|
||||||
|
FriendlyName="Visible Complete">
|
||||||
|
<Start>
|
||||||
|
<!-- Use AAMShim_ActivationStart instead of AppLaunch_UserClick as we don't lanch from Start -->
|
||||||
|
<Event Provider="{cf7f94b3-08dc-5257-422f-497d7dc86ab3}" Name="AAMShim_ActivationStart" />
|
||||||
|
<PayloadIdentifier FieldName="AppId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<Event Provider="{EF00584A-2655-462C-BC24-E7DE630E7FBF}" Name="ModernAppLaunch_VisibleComplete" Version="0" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{ec31fb10-992b-438b-8c9e-42454f4b2e5a}"
|
||||||
|
Name="Calculator_Suspend"
|
||||||
|
FriendlyName="Suspended">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_SuspendApplication\win:Start -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="2450" Version="1" />
|
||||||
|
<PayloadIdentifier FieldName="PsmKey" FieldValueRelationship="RegEx" FieldValue="Microsoft.WindowsCalculator.*" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_SuspendApplication\win:Stop -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="2451" Version="1" />
|
||||||
|
<PayloadIdentifier FieldName="AppUserModelId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
<Region Guid="{83735b08-b17e-48cf-82f1-02cb08e45597}"
|
||||||
|
Name="Calculator_Resume"
|
||||||
|
FriendlyName="Resumed">
|
||||||
|
<Start>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_ResumeApplication_EndToEnd\win:Start -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="11118" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="PsmKey" FieldValueRelationship="RegEx" FieldValue="Microsoft.WindowsCalculator.*" />
|
||||||
|
</Start>
|
||||||
|
<Stop>
|
||||||
|
<!-- Microsoft-Windows-Immersive-Shell\PerfTrack_PLM_ResumeApplication_EndToEnd\win:Stop -->
|
||||||
|
<Event Provider="{315a8872-923e-4ea2-9889-33cd4754bf64}" Id="11119" Version="0" />
|
||||||
|
<PayloadIdentifier FieldName="AppUserModelId" FieldValue="Microsoft.WindowsCalculator.*" FieldValueRelationship="RegEx" />
|
||||||
|
</Stop>
|
||||||
|
<Naming>
|
||||||
|
<PrependParentName />
|
||||||
|
</Naming>
|
||||||
|
<Metadata>
|
||||||
|
<WinperfWPAPreset.1>CPU</WinperfWPAPreset.1>
|
||||||
|
<WinperfWPAPreset.1.ProcessName>Calculator.exe</WinperfWPAPreset.1.ProcessName>
|
||||||
|
<WinperfWPAPreset.2>Commit</WinperfWPAPreset.2>
|
||||||
|
<WinperfWPAPreset.2.ProcessName>Calculator.exe</WinperfWPAPreset.2.ProcessName>
|
||||||
|
</Metadata>
|
||||||
|
</Region>
|
||||||
|
</Region>
|
||||||
|
</RegionRoot>
|
||||||
|
</Regions>
|
||||||
|
</Instrumentation>
|
||||||
|
</InstrumentationManifest>
|
54
internal/Calculator.UITests/Initialization.cs
Normal file
54
internal/Calculator.UITests/Initialization.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Calculator.UIAutomationLibrary;
|
||||||
|
using Microsoft.OneCoreUap.Test.AppModel;
|
||||||
|
using WEX.TestExecution;
|
||||||
|
using WEX.TestExecution.Markup;
|
||||||
|
|
||||||
|
namespace Calculator.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Initialization
|
||||||
|
{
|
||||||
|
[DllImport("AppModel.TestHelper.dll")]
|
||||||
|
private static extern Int32 WinRTHelper_Register();
|
||||||
|
|
||||||
|
[AssemblyInitialize]
|
||||||
|
[TestProperty("CoreClrProfile", "TestNetv2.0")]
|
||||||
|
[TestProperty("RunFixtureAs:Assembly", "System")]
|
||||||
|
public static void AssemblySetup(TestContext context)
|
||||||
|
{
|
||||||
|
Verify.AreEqual(0, WinRTHelper_Register());
|
||||||
|
TestHelper.Initialize();
|
||||||
|
|
||||||
|
// Install and Start the Etw.Service service to enable the use of EtwWaiter.
|
||||||
|
EtwHelper.InstallAndStartETWService();
|
||||||
|
|
||||||
|
bool installApp = false;
|
||||||
|
if (context.Properties.Contains("InstallApp") && (bool.TryParse(context.Properties["InstallApp"].ToString(), out installApp)) && installApp)
|
||||||
|
{
|
||||||
|
string certToDeploy = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), Constants.CertificateFileName);
|
||||||
|
InstallHelper.InstallCertFile(certToDeploy);
|
||||||
|
|
||||||
|
string vcLibsToDeploy = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), Constants.VCLibsPackageFileName);
|
||||||
|
string winUIToDeploy = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), Constants.WinUIPackageFileName);
|
||||||
|
string appxToDeploy = Path.Combine(TAEFHelper.GetTestDeploymentDirectory(), Constants.PackageFileName);
|
||||||
|
Impersonater.RunAs(Impersonater.RunAsUser.RestrictedUser, () => InstallHelper.InstallPackage(appxToDeploy, vcLibsToDeploy, winUIToDeploy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AssemblyCleanup]
|
||||||
|
[TestProperty("RunFixtureAs:Assembly", "System")]
|
||||||
|
public static void AssemblyCleanup()
|
||||||
|
{
|
||||||
|
// Stop and remove the Etw.Service service.
|
||||||
|
EtwHelper.StopAndRemoveETWService();
|
||||||
|
|
||||||
|
TestHelper.Uninitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue