Hello GitHub
This commit is contained in:
Родитель
456fe5e355
Коммит
c13b8a099e
|
@ -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
|
|
@ -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
|
|
@ -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.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
@ -24,14 +24,11 @@ bld/
|
|||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
@ -45,29 +42,20 @@ TestResult.xml
|
|||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
|
@ -105,9 +93,6 @@ ipch/
|
|||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
|
@ -128,10 +113,6 @@ _TeamCity*
|
|||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
@ -167,7 +148,7 @@ publish/
|
|||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.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
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
@ -180,11 +161,11 @@ PublishScripts/
|
|||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
**/packages/*
|
||||
# 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
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
@ -202,7 +183,6 @@ AppPackages/
|
|||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
|
@ -221,10 +201,6 @@ ClientBin/
|
|||
*.publishsettings
|
||||
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
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
@ -239,8 +215,6 @@ _UpgradeReport_Files/
|
|||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
|
@ -251,7 +225,6 @@ ServiceFabricBackup/
|
|||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
@ -263,6 +236,9 @@ FakesAssemblies/
|
|||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
|
@ -302,9 +278,6 @@ __pycache__/
|
|||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
|
@ -314,17 +287,15 @@ __pycache__/
|
|||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
# Calculator specific
|
||||
Generated Files/
|
||||
# Don't ignore anything under SpkgDefs or TrexDefs
|
||||
!/SpkgDefs/**
|
||||
!/TrexDefs/**
|
||||
!/build/config/TRexDefs/**
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
# Localized strings
|
||||
# LCT files are loc system artifacts that we don't want in our repo.
|
||||
*.lct
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
WorkspaceInfo.xml
|
||||
|
|
|
@ -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.
|
|
@ -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`.
|
34
LICENSE
34
LICENSE
|
@ -1,21 +1,21 @@
|
|||
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
|
||||
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:
|
||||
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 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
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
<!-- TODO: Replace with something else or remove if builds are not public -->
|
||||
[![Build Status](https://microsoft.visualstudio.com/Apps/_apis/build/status/Utility%20Apps/Calculator-Daily)](https://microsoft.visualstudio.com/Apps/_build?definitionId=3539)
|
||||
|
||||
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.
|
||||
![Calculator Screenshot](\docs\Images\CalculatorScreenshot.png)
|
||||
|
||||
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.
|
||||
## Features
|
||||
- Standard Calculator functionality which offers basic operations and evaluates commands immediately as they are entered.
|
||||
- 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
|
||||
|
||||
![Visual Studio Installation Screenshot](\docs\Images\VSInstallationScreenshot.png)
|
||||
- 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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"$schema": "http://universaltest/schema/testlist-2.json",
|
||||
"TestMDs": [
|
||||
{
|
||||
"FilePath": "Calculator.UITests\\Prebuilt\\Test\\arm\\fre\\Calculator.UITests.testmd",
|
||||
"ExecutionProfile": "Performance"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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)"] }'
|
|
@ -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
|
||||
}
|
|
@ -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)
|
|
@ -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
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 68 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 69 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 3.1 MiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.2 MiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 3.2 MiB |
|
@ -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'
|
|
@ -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).
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": {}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче