This commit is contained in:
Howard Wolosky 2019-01-28 16:24:37 -08:00
Родитель 456fe5e355
Коммит c13b8a099e
822 изменённых файлов: 276650 добавлений и 75 удалений

11
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,11 @@
## IDE-independent coding style via EditorConfig: http://editorconfig.org/
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

63
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
*.sln merge=binary
*.csproj merge=binary
*.vbproj merge=binary
*.vcxproj merge=binary
*.vcproj merge=binary
*.dbproj merge=binary
*.fsproj merge=binary
*.lsproj merge=binary
*.wixproj merge=binary
*.modelproj merge=binary
*.sqlproj merge=binary
*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
*.jpg binary
*.png binary
*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

67
.gitignore поставляемый
Просмотреть файл

@ -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

6
CODE_OF_CONDUCT.md Normal file
Просмотреть файл

@ -0,0 +1,6 @@
# Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or
comments.

96
CONTRIBUTING.md Normal file
Просмотреть файл

@ -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
Просмотреть файл

@ -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.

39
NOTICE.txt Normal file
Просмотреть файл

@ -0,0 +1,39 @@
THIRD PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
This software incorporates material from third parties. Microsoft makes certain
open source code available at http://3rdpartysource.microsoft.com, or you may
send a check or money order for US $5.00, including the product name, the open
source component name, and version number, to:
Source Code Compliance Team
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052
USA
Notwithstanding any other terms, you may reverse engineer this software to the
extent required to debug changes to any libraries licensed under the GNU Lesser
General Public License.
---
Hebrew OpenType Layout logic
The MIT License (MIT)
Copyright (c) 2003, 2007 Ralph Hancock & John Hudson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Просмотреть файл

@ -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

Двоичные данные
docs/Images/CalculatorScreenshot.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 68 KiB

Двоичные данные
docs/Images/VSInstallationScreenshot.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 69 KiB

Двоичные данные
docs/Images/VisualStates/Converter1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 MiB

Двоичные данные
docs/Images/VisualStates/Scientific1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.2 MiB

Двоичные данные
docs/Images/VisualStates/Standard1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 MiB

353
docs/ManualTests.md Normal file
Просмотреть файл

@ -0,0 +1,353 @@
# Calculator Manual Tests
These manual tests are run before every release of the Calculator app.
## Smoke Tests
### Calculators
### Math in Standard Calculator
**Test 1**
Steps:
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
Expected: “6” shows up in the display
2. Input “4”, “-“, “2”, “=” using the in-app buttons
*Expected: “2” shows up in the display*
**Test 2**
Steps:
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
2. Navigate to the History pane, and verify that “3 + 3 = 6” shows up in the pane
3. Input “MS” using the in-app buttons
4. Navigate to the Memory pane
*Expected: “6” shows up in the pane*
### Math in Scientific Calculator
**Test 1**
Steps:
1. From the Scientific Calculator page, input “3”, “^”, “3”, “Enter” on the keyboard
*Expected: “27” shows up in the display*
**Test 2**
Steps:
1. Input “5”, “n!“, “=” using the in-app buttons
*Expected: “120” shows up in the display*
### Math in Programmer Calculator
**Test 1**
Steps:
1. From the Programmer Calculator page, input “1”, “&”, “0”, “Enter” on the keyboard
*Expected: “0” shows up in the display*
**Test 2**
Steps:
1. Input “15” using the in-app buttons and select “HEX”
*Expected: “F” shows up in the display and the letters A-F show up as in-app buttons*
### Converters
**Converter Usage**
Steps:
1. From the Length Converter page, select “kilometers” as the unit type in the input field and input “5” using the keyboard
2. Select “miles” as the unit type in the output field
*Expected: The output starts with is “3.106856”*
## Basic Verification Tests
**Launch App Test**
Steps:
1. Press the Windows key.
2. Navigate to "all apps".
3. Look for "Calculator".
4. Click to launch the "Calculator" app.
*Expected: The calculator app launches gracefully.*
**All Calculators Test: Verify All Numbers & Input Methods**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Standard" Calculator.
3. Mouse Input
*Expected: All numbers work via mouse click.*
4. Keyboard Input:
*Expected: All numbers work via number pad.*
5. Navigate to "Scientific" Calculator and Repeat Steps 3-5
*Expected: Steps 3-5 pass in Scientific mode*
6. Navigate to "Programmer" Calculator and Repeat Steps 3-5
*Expected: Steps 3-5 pass in Programmer mode*
**All Calculators Test: Verify Basic Arithmetic Functions**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Standard" Calculator.
3. Using the Number Pad and Mouse perform the following arithmetic functions and verify the result.
a. (+) Addition
b. (-) Subtraction
c. (x) Multiplication
d. (÷) Division
e. (1/x) Reciprocal
f. (√) Square Root
g. (x²) Squared
h. (x³) Cubed
i. (%) Percent
j. (±) Positive / Negative
k. (=) Equals
l. Delete Button (flag with x in it)
m. [CE] Clear
n. [C] Global Clear
o. (.) Decimal
4. Navigate to "Scientific" Calculator and Repeat Steps 3-19.
5. Navigate to "Programmer" Calculator and Repeat Steps 3-18 (No Decimal in Programming Calc).
**Scientific Calculator Test: Verify advanced arithmetic functions**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Scientific" Calculator.
3. Using the Number Pad and Mouse perform the following arithmetic functions and verify the result.
a. (xʸ) Xth Power of Y
b. (y√x) Y Root of X
c. (10ˣ) 10 Power of X
d. (ex) E Power of X
e. (π) Pi
f. (n!) Factorial
g. (Ln) Natural Logarithm
h. (Log) Logarithm
i. (Exp) Exponential
j. (dms) Degrees, Minutes, Seconds
k. (deg) Degrees
l. (Mod) Modulo
m. “( )" Parenthesis
**All Calulators Test: Verify memory functions**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Standard" Calculator.
3. Perform a calculation and press the MS button.
4. If small scale, Select the (M) with the drop down arrow
*Expected: Calculation from previous step is present.*
5. Click the (M+) Add to Memory.
*Expected: Previous calculation is added to itself.*
6. Click the (M-) Subtract from Memory.
*Expected: Previous calculation is subtracted from the base calculation.*
7. Click the (MR) Memory Recall.
*Expected: Previous calculation is made primary (This is not available in the Programmer mode).*
8. Check the MC button.
*Expected: The stored information is cleared.*
9. Navigate to "Scientific" Calculator and Repeat Steps 3-8.
*Expected: All in "Scientific" mode.*
10. Navigate to "Programmer" Calculator and Repeat Steps 3-8.
*Expected: All in "Programmer" mode.*
**Scientific Calculator Test: Verify trigonometric functions**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Scientific" Calculator.
3. Using the Number Pad and Mouse perform the following trigonometric functions and verify the result.
3. Sine (sin)
4. Cosine (cos)
5. Tangent (tan)
6. Inverse Sine (sin-1)
7. Inverse Cosine (cos-1)
8. Inverse Tangent (tan-1) Inverse Tangent:
9. Press (HYP) for Hyperbolic trig functions:
*Expected: Trig function buttons show hyperbolic trig functions.*
10. Hyperbolic Sine (sinh)
11. Hyperbolic Tangent (tanh)
12. Hyperbolic Cosine (cosh)
13. Inverse Hyperbolic Sine (sinh-1)
14. Inverse Hyperbolic Tangent (tanh-1)
15. Inverse Hyperbolic Cosine (cosh-1)
**Programmer Calculator Test: Verify logical functions**
Steps:
1. Launch the "Calculator" app
2. Navigate to "Programmer" Calculator.
3. Using the Number Pad and Mouse perform the following trigonometric functions and verify the result.
4. Rotate Left (RoL) Logical Operator:
01011001 rol 3 = 11001010.
5. Rotate Right (RoR) Logical Operator:
01011001 RoR 3 = 00101011.
6. (Lsh) Logical Operator:
(10 multiplied by 2 three times)
10 Lsh 3 = gives 80.
10.345 Lsh 3 = also gives 80.
7. (Rsh) Logical Operator:
(16 divided by 2 twice)
16 Rsh 2 = gives 4.
16.999 Rsh 2 = also gives 4.
7. (Or) Logical Operator
101 OR 110 = gives 111.
9. Exclusive Or (Xor) Logical Operator:
101 XOR 110 = gives 11.
9. (Not) Logical Operator
NOT 1001100111001001 =
0110011000110110.
10. (And) Logical Operator
101 AND 110 = gives 100.
11. (Mod) Logical Operator
Remainder of integer division (Modulo x)
12. "( )" Parenthesis
**All Calculators and Converters Test: Verify scaling functions and languages**
Steps:
1. Launch the "Calculator" app.
2. For All Modes: While scaling in both directions to capacity
*Expected: Elements like Memory and History are shifted or integrated appropriately.*
3. In Any Mode: While at the Smallest scale, Select the Menu Button
*Expected: The menu items are scrollable with nothing overlapping.*
4. While in the Menu: Check the About Page
*Expected: Everything in the about page fits into its window*
5. For Scientific Mode: At a Larger Scale
*Expected: All buttons are present and the up arrow is grayed out.*
6. For Scientific Mode: At a Smaller Scale
*Expected: All buttons are present and the up arrow is able to be toggled.*
7. For Programmer Mode: At a Any Scale
*Expected: All buttons are present and the up arrow is able to be toggled.*
8. For Converter Mode: While Scaling
*Expected: The number pad and input areas move around each other gracefully.*
9. Changing Language: Open Settings app > Time & language > Region & language > Add a language > Select a Right to Left (RTL) language such as Hebrew > Install the associated files> Set it to the system default.
10. Set the system number format preference: Open a Run dialog (WIN + R) > type intl.cpl > Enter > In the format dropdown list > Select Hebrew > Apply.
11. Initiating the change: Package has completed installing > Sign out > Sign in. (This change to the app may also require a reinstallation of the build)
12. Repeat Steps 2-6 again in a (RTL) language.
*Expected: No elements fall out of intended boundaries.*
**All Calculators Test: Verify toggling functions**
Steps:
1. Launch the "Calculator" app.
2. For Standard & Scientific Modes: While in the Smallest scale, verify that the History Icon brings up the history panel gracefully and is displayed appropriately.
For Scientific Mode: At a Smaller Scale
Verify the following:
3. Grad / Deg / Rad
Perform a trig function
*Expected: The answer to the function is in the selected grad/deg/rad. Repeat for each of the modes.*
4. (Hyp) Hyperbolic
*Expected: Sin toggles to Sinh, Cos toggles to Cosh, Tan toggles to Tanh.*
5. (F-E key) Floating Point Notation & Scientific Notation.
*Expected: Display toggles between floating point and Scientific notation.*
For Programmer Mode
Verify the following:
6. "Bit Toggling Keypad":
*Expected: In app keypad changes to represent Bits (1s and 0s).*
7. "QWORD / DWORD / WORD / BYTE":
*Expected: Toggles as expected.*
8. "Hex" Hexadecimal:
*Expected: A B C D E F become active and user can use them. A maximum of 16 characters can be entered.*
9. "Dec" Decimal:
*Expected: A B C D E F are inactive. A maximum of 19 characters can be entered.*
10. "Oct" Octal:
*Expected: A B C D E F 8 9 are inactive. A maximum of 22 characters can be entered.*
11. "Bin" Binary:
*Expected: A B C D E F 2 3 4 5 6 7 8 9 are inactive. A maximum of 64 characters can be entered.*
**Date Calculation Test: Verify dates can be calculated.**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Date Calculation" Calculator.
3. With "Difference between dates" Selected
Change the various date input fields
*Expected: From and To reflect dates input respectively.*
5. With "Add or Subtract days" Selected
Change the various date input fields
*Expected: Verify changes made to both add and subtract reflect input respectively.*
**Currency Converter Test: Verify conversion & updating current currency rates.**
Steps:
1. Launch the "Calculator" app.
2. Navigate to "Currency Converter" Calculator.
3. Select 2 Currency types from the dropdowns & enter a "1" into a conversion slot.
*Expected: The currency is slotted properly and converted rate matches the ratio provided under the selected currency types.*
4. Click "Updated"
*Expected: Display matches PC's date and time.*
5. After at least a minute: Select "Update rates" & Check "Updated" again:
*Expected: The "Update Rates" button changes the date and time to match the computer's current date and time.*
**All Calculators Test: Hotkeys: Verify Hot Key function.**
Steps:
1. Launch the "Calculator" app.
For All Applicable Modes:
Verify the following:
2. Press **Alt +1** to Enter "Standard" mode
*Expected: Move to "Standard" screen.*
3. Press **Alt +2** to Enter "Scientific" mode
*Expected: Move to "Scientific" screen.*
4. Press **Alt +3** to Enter "Programmer" mode
*Expected: Move to "Programming" screen.*
5. Press **Alt +4** to Enter "Date Calculation" mode
*Expected: Move to "Date Calculation" screen.*
6. Press **Ctrl +M** to Store in Memory
7. Press **Ctrl +P** to Add to Active Memory
8. Press **Ctrl +Q** to Subtract form Active Memory
9. Press **Ctrl +R** to Recall from Memory
10. Press **Ctrl +L** to Clear from Memory
11. Press **Delete** to Clear Current Input 'CE'
12. Press **Esc** to Full Clear Input 'C'
13. Press **F9** to Toggle '±'
14. Press **R** to Select '1/x'
15. Press **@** to Select '√'
16. Press **Ctrl + H** to Toggle History Panel
*Expected: Function when in small scale window.*
17. Press **Up arrow** to Move up History Panel
*Expected: Function when in small scale window.*
18. Press **Down arrow** to Move Down History Panel
*Expected: Function when in small scale window.*
19. Press **Ctrl + Shift + D** to Clear History Panel
*Expected: Function when in small scale window.*
20. Press **Spacebar** to Repeat Last Input:
Verify the following in Scientific Mode
21. Press **F3** to Select 'DEG'
22. Press **F4** to Select 'RAD'
23. Press **F5** to Select 'GRAD'
24. Press **Ctrl +G** to Select '10ˣ'
25. Press **Ctrl +Y** to Select 'y√x'
26. Press **Shift +O** to Select 'sin-1'
27. Press **Shift + S** to Select 'cos-1'
28. Press **Shift +T** to Select 'tan-1'
29. Press **Ctrl +O** to Select 'Cosh'
30. Press **Ctrl +S** to Select 'Sinh'
31. Press **Ctrl +T** to Select 'Tanh'
32. Press **D** to Select 'Mod'
33. Press **L** to Select 'log'
34. Press **M** to Select 'dms'
35. Press **N** to Select 'ln'
36. Press **Ctrl +N** to Select 'ex'
37. Press **O** to Select 'Cos'
38. Press **P** to Select 'π'
39. Press **Q** to Select 'x²'
40. Press **S** to Select 'Sin'
41. Press **T** to Select 'Tan'
42. Press **V** to Toggle 'F-E'
43. Press **X** to Select 'Exp'
44. Press **Y** or **^** to Select 'xʸ'
45. Press **#** to Select 'x³'
46. Press **!** to Select 'n!'
Verify the following in Programmer Mode
47. Press **F2** to Select 'DWORD'
48. Press **F3** to Select 'WORD'
49. Press **F4** to Select 'BYTE'
50. Press **F5** to Select 'HEX'
51. Press **F6** to Select 'DEC'
52. Press **F7** to Select 'OCT'
53. Press **F8** to Select 'BIN'
54. Press **F12** to Select 'QWORD'
55. Press **A-F** to Input in HEX
56. Press **J** to Select 'RoL'
57. Press **K** to Select 'RoR'
58. Press **<** to Select 'Lsh'
59. Press **>** to Select 'Rsh'
60. Press **%** to Select 'Mod'
61. Press ** | ** to Select 'Or'
62. Press **~** to Select 'Not'
63. Press **&** to Select 'And'

149
docs/NewFeatureProcess.md Normal file
Просмотреть файл

@ -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? Whos 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 customers needs? How will the solution/feature improve the metrics?
Whos the target audience?
* **Risks**: This section may not be necessary if covered by the problem statement. What is the
risk if we dont 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&mdash;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)' &lt; '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)' &lt; '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)' &lt; '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();
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше