├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_RU.md ├── scripts ├── ci-release.ps1 ├── ci.ps1 ├── prepare-release.ps1 └── setup.ps1 ├── src ├── .nuget │ ├── NuGet.Config │ └── NuGet.targets ├── NugetPublish.bat ├── Settings.StyleCop ├── TestApplications.Tests │ ├── WindowsFormsTestApplication.Tests │ │ ├── App.config │ │ ├── CheckFocusedElement.cs │ │ ├── Map │ │ │ ├── ElementExtension.cs │ │ │ ├── FirstTab.cs │ │ │ ├── MainWindow.cs │ │ │ ├── SecondTab.cs │ │ │ └── WindowsFormsTestApplicationApp.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── SetUpFixture.cs │ │ ├── TestCases │ │ │ ├── CheckFirstTab.cs │ │ │ └── CheckSecondTab.cs │ │ ├── TestClassHelper.cs │ │ ├── WindowsFormsTestApplication.Tests.csproj │ │ └── packages.config │ └── WpfTestApplication.Tests │ │ ├── App.config │ │ ├── CheckElementIsStaleProperty.cs │ │ ├── CheckFindByXPath.cs │ │ ├── CheckFocusedElement.cs │ │ ├── CheckMouse.cs │ │ ├── Map │ │ ├── ElementExtension.cs │ │ ├── FirstRibbonTab.cs │ │ ├── FirstTab.cs │ │ ├── MainWindow.cs │ │ ├── SecondRibbonTab.cs │ │ ├── SecondTab.cs │ │ ├── ThirdTab.cs │ │ └── WpfTestApplicationApp.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── SetUpFixture.cs │ │ ├── TestCases │ │ ├── CheckFirstTab.cs │ │ ├── CheckRibbon.cs │ │ ├── CheckSecondTab.cs │ │ └── CheckThirdTab.cs │ │ ├── TestClassHelper.cs │ │ ├── WpfTestApplication.Tests.csproj │ │ └── packages.config ├── TestApplications │ ├── WindowsFormsTestApplication │ │ ├── App.config │ │ ├── Form1.Designer.cs │ │ ├── Form1.cs │ │ ├── Form1.resx │ │ ├── Program.cs │ │ ├── Properties │ │ │ ├── AssemblyInfo.cs │ │ │ ├── Resources.Designer.cs │ │ │ ├── Resources.resx │ │ │ ├── Settings.Designer.cs │ │ │ └── Settings.settings │ │ └── WindowsFormsTestApplication.csproj │ └── WpfTestApplication │ │ ├── App.config │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── MainWindow.xaml │ │ ├── MainWindow.xaml.cs │ │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ │ ├── RibbonTabExt.cs │ │ └── WpfTestApplication.csproj ├── Winium.Cruciatus │ ├── Application.cs │ ├── Core │ │ ├── By.cs │ │ ├── ByProperty.cs │ │ ├── ByXPath.cs │ │ ├── ClickStrategies.cs │ │ ├── CruciatusElementProperties.cs │ │ ├── DisplayOrientation.cs │ │ ├── ExpandStrategy.cs │ │ ├── GetTextStrategy.cs │ │ ├── IKeyboard.cs │ │ ├── IScreenshoter.cs │ │ ├── KeyboardSimulatorExt.cs │ │ ├── MouseButtons.cs │ │ ├── MouseSimulatorExt.cs │ │ ├── RotationManager.cs │ │ ├── Screenshot.cs │ │ ├── Screenshoter.cs │ │ └── SendKeysExt.cs │ ├── CruciatusCommand.cs │ ├── CruciatusFactory.cs │ ├── CruciatusRuleSet.ruleset │ ├── Elements │ │ ├── CheckBox.cs │ │ ├── ComboBox.cs │ │ ├── CruciatusElement.cs │ │ ├── DataGrid.cs │ │ ├── ListBox.cs │ │ ├── Menu.cs │ │ ├── OpenFileDialog.cs │ │ ├── SaveFileDialog.cs │ │ └── TabItem.cs │ ├── Exceptions │ │ ├── CruciatusException.cs │ │ └── NoSuchElementException.cs │ ├── Extensions │ │ ├── AutomationElementExtension.cs │ │ ├── CruciatusElementExtension.cs │ │ └── IScreenshoterExtension.cs │ ├── FullReleaseNotes.txt │ ├── Helpers │ │ ├── AutomationElementHelper.cs │ │ ├── AutomationPropertyHelper.cs │ │ ├── ScreenCoordinatesHelper.cs │ │ └── XPath │ │ │ ├── DesktopTreeXPathNavigator.cs │ │ │ ├── ElementItem.cs │ │ │ ├── PropertyItem.cs │ │ │ ├── RootItem.cs │ │ │ └── XPathItem.cs │ ├── MessageBox.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Settings │ │ ├── CruciatusSettings.cs │ │ ├── KeyboardSimulatorType.cs │ │ ├── MessageBoxSettings │ │ │ ├── MessageBoxButtonUid.cs │ │ │ ├── OkCancelType.cs │ │ │ ├── OkType.cs │ │ │ ├── YesNoCancelType.cs │ │ │ └── YesNoType.cs │ │ ├── OpenFileDialogUid.cs │ │ └── SaveFileDialogUid.cs │ ├── Winium.Cruciatus.csproj │ ├── Winium.Cruciatus.nuspec │ └── packages.config ├── Winium.sln └── Winium.sln.DotSettings └── tools └── UISpy └── UISpy.exe /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | !build/ 15 | /*/build 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 20 | !packages/*/build/ 21 | 22 | # MSTest test Results 23 | [Tt]est[Rr]esult*/ 24 | [Bb]uild[Ll]og.* 25 | 26 | *_i.c 27 | *_p.c 28 | *.ilk 29 | *.meta 30 | *.obj 31 | *.pch 32 | *.pdb 33 | *.pgc 34 | *.pgd 35 | *.rsp 36 | *.sbr 37 | *.tlb 38 | *.tli 39 | *.tlh 40 | *.tmp 41 | *.tmp_proj 42 | *.log 43 | *.vspscc 44 | *.vssscc 45 | .builds 46 | *.pidb 47 | *.svclog 48 | *.scc 49 | 50 | # Visual C++ cache files 51 | ipch/ 52 | *.aps 53 | *.ncb 54 | *.opensdf 55 | *.sdf 56 | *.cachefile 57 | 58 | # Visual Studio profiler 59 | *.psess 60 | *.vsp 61 | *.vspx 62 | 63 | # TFS 2012 Local Workspace 64 | $tf/ 65 | 66 | # Guidance Automation Toolkit 67 | *.gpState 68 | 69 | # ReSharper is a .NET coding add-in 70 | _ReSharper*/ 71 | *.[Rr]e[Ss]harper 72 | *.DotSettings.user 73 | 74 | # TeamCity is a build add-in 75 | _TeamCity* 76 | 77 | # DotCover is a Code Coverage Tool 78 | *.dotCover 79 | 80 | # NCrunch 81 | *.ncrunch* 82 | _NCrunch_* 83 | .*crunch*.local.xml 84 | 85 | # Installshield output folder 86 | [Ee]xpress/ 87 | 88 | # DocProject is a documentation generator add-in 89 | DocProject/buildhelp/ 90 | DocProject/Help/*.HxT 91 | DocProject/Help/*.HxC 92 | DocProject/Help/*.hhc 93 | DocProject/Help/*.hhk 94 | DocProject/Help/*.hhp 95 | DocProject/Help/Html2 96 | DocProject/Help/html 97 | 98 | # Click-Once directory 99 | publish/ 100 | 101 | # Publish Web Output 102 | *.Publish.xml 103 | 104 | # NuGet Packages Directory 105 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 106 | packages/ 107 | 108 | # Windows Azure Build Output 109 | csx 110 | *.build.csdef 111 | 112 | # Windows Store app package directory 113 | AppPackages/ 114 | 115 | # Others 116 | sql/ 117 | *.Cache 118 | ClientBin/ 119 | [Ss]tyle[Cc]op.* 120 | ~$* 121 | *~ 122 | *.dbmdl 123 | *.dbproj.schemaview 124 | *.[Pp]ublish.xml 125 | *.pfx 126 | *.publishsettings 127 | 128 | # RIA/Silverlight projects 129 | Generated_Code/ 130 | 131 | # Backup & report files from converting an old project file to a newer 132 | # Visual Studio version. Backup files are not needed, because we have git ;-) 133 | _UpgradeReport_Files/ 134 | Backup*/ 135 | UpgradeLog*.XML 136 | UpgradeLog*.htm 137 | 138 | # SQL Server files 139 | App_Data/*.mdf 140 | App_Data/*.ldf 141 | 142 | # Business Intelligence projects 143 | *.rdl.data 144 | *.bim.layout 145 | *.bim_*.settings 146 | 147 | # Microsoft Fakes 148 | FakesAssemblies/ 149 | 150 | # ========================= 151 | # Windows detritus 152 | # ========================= 153 | 154 | # Windows image file caches 155 | Thumbs.db 156 | ehthumbs.db 157 | 158 | # Folder config file 159 | Desktop.ini 160 | 161 | # Recycle Bin used on file shares 162 | $RECYCLE.BIN/ 163 | 164 | # Mac crap 165 | .DS_Store 166 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | 4 | 5 | ## v2.10.0 6 | 7 | - Add `RotationManager` for get and set display orientation (thanks to @jonstoneman) 8 | 9 | 10 | ## v2.9.1 11 | 12 | - Fix XPath attribute value if this ControlType 13 | 14 | 15 | ## v2.9.0 16 | 17 | - Add 'SetFocus' method to 'CruciatusElement' 18 | 19 | 20 | ## v2.8.0 21 | 22 | - Add `XPath` strategy for locating elements 23 | 24 | 25 | ## v2.7.0 26 | 27 | - Set default search timeout to 10 seconds 28 | - Simplify DataGrid element instantiation 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | English description | Описание на русском 3 |

4 | 5 | # Winium for Desktop 6 | [![Build Status](https://img.shields.io/jenkins/s/http/opensource-ci.2gis.ru/Winium.Cruciatus.svg?style=flat-square)](http://opensource-ci.2gis.ru/job/Winium.Cruciatus/) 7 | [![Inner Server NuGet downloads](https://img.shields.io/nuget/dt/Winium.Cruciatus.svg?style=flat-square)](https://www.nuget.org/packages/Winium.Cruciatus/) 8 | [![Inner Server NuGet version](https://img.shields.io/nuget/v/Winium.Cruciatus.svg?style=flat-square)](https://www.nuget.org/packages/Winium.Cruciatus/) 9 | 10 |

11 | Winium.Cruciatus is C# Framework for automated testing of Windows application based on WinFroms and WPF platforms 12 |

13 | 14 | Winium.Cruciatus is an open source C# Framework for automated testing of Windows application based on WinFroms and WPF platforms. 15 | 16 | Winium.Cruciatus is a wrapper over Microsoft UI Automation library in the [System.Windows.Automation](https://msdn.microsoft.com/en-us/library/system.windows.automation(v=vs.110).aspx) namespace. 17 | 18 | ## Why Winium.Cruciatus? 19 | 20 | - Enough Visual Studio Professional offering 21 | - You can use any testing framework to write tests (example [NUnit](https://www.nuget.org/packages/NUnit/)) 22 | 23 | ## Quick Start 24 | 25 | 1. Add reference to `Winium.Cruciatus` in UI test project ([install NuGet package](https://www.nuget.org/packages/Winium.Cruciatus/)) 26 | 27 | 2. Create a map application 28 | 29 | 3. Use created map in tests 30 | 31 | 4. Run your tests and watch the magic happening 32 | 33 | ## Example 34 | - [Example test applications](src/TestApplications) 35 | - [Example test projects](src/TestApplications.Tests) 36 | 37 | ## Very Quick Start 38 | 39 | 1. Add reference to `Winium.Cruciatus` in UI test project ([install NuGet package](https://www.nuget.org/packages/Winium.Cruciatus/)) 40 | 41 | 2. Create C# Console Application project and use this code: 42 | 43 | ```c# 44 | namespace ConsoleApplication 45 | { 46 | using System.Windows.Automation; 47 | using Winium.Cruciatus.Core; 48 | using Winium.Cruciatus.Extensions; 49 | 50 | public class Program 51 | { 52 | private static void Main(string[] args) 53 | { 54 | var calc = new Winium.Cruciatus.Application("C:/windows/system32/calc.exe"); 55 | calc.Start(); 56 | 57 | var winFinder = By.Name("Calculator").AndType(ControlType.Window); 58 | var win = Winium.Cruciatus.CruciatusFactory.Root.FindElement(winFinder); 59 | var menu = win.FindElementByUid("MenuBar").ToMenu(); 60 | 61 | menu.SelectItem("View$Scientific"); 62 | menu.SelectItem("View$History"); 63 | 64 | win.FindElementByUid("132").Click(); // 2 65 | win.FindElementByUid("93").Click(); // + 66 | win.FindElementByUid("134").Click(); // 4 67 | win.FindElementByUid("97").Click(); // ^ 68 | win.FindElementByUid("138").Click(); // 8 69 | win.FindElementByUid("121").Click(); // = 70 | 71 | calc.Close(); 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | 3. Run ConsoleApplication and watch the magic happening 78 | 79 | ## Contributing 80 | 81 | Contributions are welcome! 82 | 83 | 1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. 84 | 2. Fork the repository to start making your changes to the master branch (or branch off of it). 85 | 3. We recommend to write a test which shows that the bug was fixed or that the feature works as expected. 86 | 4. Send a pull request and bug the maintainer until it gets merged and published. :smiley: 87 | 88 | ## Contact 89 | 90 | Have some questions? Found a bug? Create [new issue](https://github.com/2gis/Winium.Cruciatus/issues/new) or contact us at g.golovin@2gis.ru 91 | 92 | ## License 93 | 94 | Winium is released under the MPL 2.0 license. See [LICENSE](LICENSE) for details. 95 | -------------------------------------------------------------------------------- /README_RU.md: -------------------------------------------------------------------------------- 1 | # Winium для Desktop 2 | [![Build Status](https://img.shields.io/jenkins/s/http/opensource-ci.2gis.ru/Winium.Cruciatus.svg?style=flat-square)](http://opensource-ci.2gis.ru/job/Winium.Cruciatus/) 3 | [![Inner Server NuGet downloads](https://img.shields.io/nuget/dt/Winium.Cruciatus.svg?style=flat-square)](https://www.nuget.org/packages/Winium.Cruciatus/) 4 | [![Inner Server NuGet version](https://img.shields.io/nuget/v/Winium.Cruciatus.svg?style=flat-square)](https://www.nuget.org/packages/Winium.Cruciatus/) 5 | 6 |

7 | Winium.Cruciatus это C# фреймворк для автоматизации тестирования Windows приложений построенных на WinFroms или WPF платформах 8 |

9 | 10 | Winium.Cruciatus это open-source C# фреймворк для автоматизации тестирования Windows приложений построенных на WinFroms или WPF платформах. 11 | 12 | Winium.Cruciatus это обёртка над библиотекой Microsoft UI Automation из пространства имён [System.Windows.Automation](https://msdn.microsoft.com/en-us/library/system.windows.automation(v=vs.110).aspx). 13 | 14 | ## Почему Winium.Cruciatus? 15 | 16 | - Для работы достаточно редакции Visual Studio Professional 17 | - Вы можете использовать любой тестовый фреймворк для написания тестов (например [NUnit](https://www.nuget.org/packages/NUnit/)) 18 | 19 | ## Быстрый старт 20 | 21 | 1. Добавить ссылку на `Winium.Cruciatus` в тестовом проекте ([через NuGet пакет](https://www.nuget.org/packages/Winium.Cruciatus/)) 22 | 23 | 2. Описать карту приложения 24 | 25 | 3. Используя карту написать тесты 26 | 27 | 4. Запустить тесты и балдеть от происходящей магии 28 | 29 | ## Примеры 30 | - [Примеры тестовый приложений](src/TestApplications) 31 | - [Примеры тестовых проектов](src/TestApplications.Tests) 32 | 33 | ## Очень быстрый старт 34 | 35 | 1. Создать C# Console Application проект 36 | 37 | 2. Добавить ссылку на `Winium.Cruciatus` ([через NuGet пакет](https://www.nuget.org/packages/Winium.Cruciatus/)) 38 | 39 | 3. Использовать следующий код: 40 | 41 | ```c# 42 | namespace ConsoleApplication 43 | { 44 | using System.Windows.Automation; 45 | using Winium.Cruciatus.Core; 46 | using Winium.Cruciatus.Extensions; 47 | 48 | public class Program 49 | { 50 | private static void Main(string[] args) 51 | { 52 | var calc = new Winium.Cruciatus.Application("C:/windows/system32/calc.exe"); 53 | calc.Start(); 54 | 55 | var winFinder = By.Name("Калькулятор").AndType(ControlType.Window); 56 | var win = Winium.Cruciatus.CruciatusFactory.Root.FindElement(winFinder); 57 | var menu = win.FindElementByUid("MenuBar").ToMenu(); 58 | 59 | menu.SelectItem("Вид$Инженерный"); 60 | menu.SelectItem("Вид$Журнал"); 61 | 62 | win.FindElementByUid("132").Click(); // 2 63 | win.FindElementByUid("93").Click(); // + 64 | win.FindElementByUid("134").Click(); // 4 65 | win.FindElementByUid("97").Click(); // ^ 66 | win.FindElementByUid("138").Click(); // 8 67 | win.FindElementByUid("121").Click(); // = 68 | 69 | calc.Close(); 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | 3. Запустить ConsoleApplication и балдеть от происходящей магии 76 | 77 | ## Вклад в развитие 78 | 79 | Мы открыты для сотрудничества! 80 | 81 | 1. Проверьте нет ли уже открытого issue или заведите новый issue для обсуждения новой фичи или бага. 82 | 2. Форкните репозиторий и начните делать свои изменения в ветке мастер или новой ветке 83 | 3. Мы советуем написать тест, который покажет, что баг был починен или что новая фича работает как ожидается. 84 | 4. Создайте pull-request и тыкайте в мэнтейнера до тех пор, пока он не примет и не сольет ваши изменения. :smiley: 85 | 86 | ## Контакты 87 | 88 | Есть вопросы? Нашли ошибку? Создавайте [новое issue](https://github.com/2gis/Winium.Cruciatus/issues/new) или пишите g.golovin@2gis.ru 89 | 90 | ## Лицензия 91 | 92 | Winium выпущен под MPL 2.0 лицензией. [Подробности](LICENSE). 93 | -------------------------------------------------------------------------------- /scripts/ci-release.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('git', 'versioning', 'changelog', 'msbuild', 'nunit', 'nuget', 'github')) 6 | 7 | $version = $env:release_version 8 | $description = $env:release_description 9 | 10 | # Git checkout master 11 | Invoke-Git ('checkout', 'master') -Verbose 12 | 13 | # Update AssembyInfo 14 | Update-AssemblyInfo $assemblyInfoPath $version -Verbose 15 | 16 | # Update CHANGELOG.md 17 | Update-Changelog $changelogPath $version $description -Verbose 18 | 19 | # Update Nuspec file 20 | Update-Nuspec $nuspecPath $version $description -Verbose 21 | 22 | # Build 23 | Invoke-MSBuild $solution $msbuildProperties -Verbose 24 | 25 | # Test 26 | (New-Object -ComObject "Shell.Application").minimizeall() 27 | Invoke-NUnit $testFiles -Verbose 28 | 29 | # Create nuget-package 30 | New-Item -ItemType directory -Path $releaseDir | Out-Null 31 | Invoke-NuGetPack $project $configuration $releaseDir -Verbose 32 | 33 | # Git add changes 34 | Invoke-Git ('add', $assemblyInfoPath) -Verbose 35 | Invoke-Git ('add', $changelogPath) -Verbose 36 | Invoke-Git ('add', $nuspecPath) -Verbose 37 | 38 | # Git commit and push 39 | Invoke-GitCommit "Version $version" -Verbose 40 | Invoke-Git ('push', 'origin', 'master') -Verbose 41 | 42 | # Git tag and push 43 | $buildUrl = $env:BUILD_URL 44 | Invoke-GitTag "Version '$version'. Build url '$buildUrl'." "v$version" -Verbose 45 | Invoke-Git ('push', 'origin', 'master', "v$version") -Verbose 46 | 47 | # Push nuget-package 48 | $package = Join-Path $releaseDir '*.nupkg' 49 | Invoke-NuGetPush $package -Verbose 50 | 51 | # Create github release 52 | Invoke-CreateGitHubRelease '2gis' $githubProjectName $version $description $releaseDir -Verbose 53 | -------------------------------------------------------------------------------- /scripts/ci.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('msbuild', 'nunit')) 6 | 7 | # Build 8 | Invoke-MSBuild $solution $msbuildProperties -Verbose 9 | 10 | # Test 11 | (New-Object -ComObject "Shell.Application").minimizeall() 12 | Invoke-NUnit $testFiles -Verbose 13 | -------------------------------------------------------------------------------- /scripts/prepare-release.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('msbuild', 'nunit', 'nuget')) 6 | 7 | if (Test-Path $releaseDir) 8 | { 9 | Remove-Item $releaseDir -Force -Recurse 10 | } 11 | 12 | New-Item -ItemType directory -Path $releaseDir | Out-Null 13 | 14 | Write-Output "Update CHANGELOG.md" 15 | Write-Output "Update version in Assemblies" 16 | Write-Output "Update release notes in Nuspec file" 17 | 18 | Pause 19 | 20 | # Build 21 | Invoke-MSBuild $solution $msbuildProperties -Verbose 22 | 23 | # Test 24 | Invoke-NUnit $testFiles -Verbose 25 | 26 | # Create nuget-package 27 | Invoke-NuGetPack $project $configuration $releaseDir -Verbose 28 | 29 | Write-Output "Publish NuGet package using nuget.exe push $releaseDir\*.nupkg" 30 | Write-Output "Add and push tag using git tag -a -m 'Version *.*.*' v*.*.*" 31 | Write-Output "Upload and attach $releaseDir\* files to release" 32 | -------------------------------------------------------------------------------- /scripts/setup.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string[]]$modules 3 | ) 4 | 5 | Set-StrictMode -Version Latest 6 | $ErrorActionPreference = 'Stop' 7 | #------------------------------ 8 | 9 | $configuration = 'Release' 10 | $solution = Join-Path $PSScriptRoot '..\src\Winium.sln' 11 | $testFiles = ,"..\src\TestApplications.Tests\WindowsFormsTestApplication.Tests\bin\$configuration\WindowsFormsTestApplication.Tests.dll" 12 | $testFiles += "..\src\TestApplications.Tests\WpfTestApplication.Tests\bin\$configuration\WpfTestApplication.Tests.dll" 13 | $releaseDir = Join-Path $PSScriptRoot '../Release' 14 | $project = Join-Path $PSScriptRoot '..\src\Winium.Cruciatus\Winium.Cruciatus.csproj' 15 | $assemblyInfoPath = Join-Path $PSScriptRoot '..\src\Winium.Cruciatus\Properties\AssemblyInfo.cs' 16 | $changelogPath = Join-Path $PSScriptRoot '..\CHANGELOG.md' 17 | $nuspecPath = Join-Path $PSScriptRoot '..\src\Winium.Cruciatus\Winium.Cruciatus.nuspec' 18 | $githubProjectName = 'Winium.Cruciatus' 19 | 20 | $msbuildProperties = @{ 21 | 'Configuration' = $configuration 22 | 'Defineconstants' = 'REMOTE' 23 | } 24 | 25 | $env:UITestApps=(Join-Path $PSScriptRoot 'UITestApps') 26 | 27 | $modulesUrl = 'https://raw.githubusercontent.com/skyline-gleb/dev-help/v0.2.1/psm' 28 | 29 | if (!(Get-Module -ListAvailable -Name PsGet)) 30 | { 31 | (new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex 32 | } 33 | 34 | foreach ($module in $modules) 35 | { 36 | Install-Module -ModuleUrl "$modulesUrl/$module.psm1" -Update 37 | } 38 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/NugetPublish.bat: -------------------------------------------------------------------------------- 1 | REM delete existing nuget packages 2 | del *.nupkg 3 | set NUGET=.\.nuget\nuget.exe 4 | %NUGET% pack .\Winium.Cruciatus\Winium.Cruciatus.csproj -IncludeReferencedProjects -Prop Configuration=Release 5 | %NUGET% push *.nupkg -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/CheckFocusedElement.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WindowsFormsTestApplication.Tests.Map; 8 | 9 | using Winium.Cruciatus; 10 | 11 | #endregion 12 | 13 | [TestFixture] 14 | public class CheckFocusedElement 15 | { 16 | #region Fields 17 | 18 | private WindowsFormsTestApplicationApp application; 19 | 20 | #endregion 21 | 22 | #region Public Methods and Operators 23 | 24 | [TestFixtureSetUp] 25 | public void FixtureSetUp() 26 | { 27 | TestClassHelper.Initialize(out this.application); 28 | } 29 | 30 | [TestFixtureTearDown] 31 | public void FixtureTearDown() 32 | { 33 | TestClassHelper.Cleanup(this.application); 34 | } 35 | 36 | [Test] 37 | public void GetFocusedElement() 38 | { 39 | var textBox = this.application.Window.TabItem1.TextBox1; 40 | 41 | textBox.Click(); 42 | var textBoxToo = CruciatusFactory.FocusedElement; 43 | 44 | Assert.AreEqual(textBox, textBoxToo); 45 | } 46 | 47 | #endregion 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Map/ElementExtension.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Elements; 9 | using Winium.Cruciatus.Extensions; 10 | 11 | #endregion 12 | 13 | public static class ElementExtension 14 | { 15 | #region Public Methods and Operators 16 | 17 | public static CheckBox GetCheckBoxByName(this CruciatusElement element, string name) 18 | { 19 | return element.FindElement(By.Name(name).AndType(ControlType.CheckBox)).ToCheckBox(); 20 | } 21 | 22 | public static CheckBox ScrollToCheckBoxByName(this ListBox element, string name) 23 | { 24 | return element.ScrollTo(By.Name(name).AndType(ControlType.ListItem)).ToCheckBox(); 25 | } 26 | 27 | #endregion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Map/FirstTab.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class FirstTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public FirstTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CheckBox CheckBox1 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("CheckBox1").ToCheckBox(); 29 | } 30 | } 31 | 32 | public CruciatusElement SetTextButton 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("SetTextButton"); 37 | } 38 | } 39 | 40 | public CruciatusElement TextBox1 41 | { 42 | get 43 | { 44 | return this.FindElementByUid("TextBox1"); 45 | } 46 | } 47 | 48 | public ComboBox TextComboBox 49 | { 50 | get 51 | { 52 | return this.FindElementByUid("TextComboBox").ToComboBox(); 53 | } 54 | } 55 | 56 | public ListBox TextListBox 57 | { 58 | get 59 | { 60 | return this.FindElementByUid("TextListBox").ToListBox(); 61 | } 62 | } 63 | 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Map/MainWindow.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | 8 | #endregion 9 | 10 | public class MainWindow : CruciatusElement 11 | { 12 | #region Constructors and Destructors 13 | 14 | public MainWindow(CruciatusElement parent, By getStrategy) 15 | : base(parent, getStrategy) 16 | { 17 | } 18 | 19 | #endregion 20 | 21 | #region Public Properties 22 | 23 | public FirstTab TabItem1 24 | { 25 | get 26 | { 27 | return new FirstTab(this, By.Name("TabItem1")); 28 | } 29 | } 30 | 31 | public SecondTab TabItem2 32 | { 33 | get 34 | { 35 | return new SecondTab(this, By.Name("TabItem2")); 36 | } 37 | } 38 | 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Map/SecondTab.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class SecondTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public SecondTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CruciatusElement ChangeEnabledButton 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("ChangeEnabledButton"); 29 | } 30 | } 31 | 32 | public CheckBox CheckBox2 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("CheckBox2").ToCheckBox(); 37 | } 38 | } 39 | 40 | public ListBox CheckListBox 41 | { 42 | get 43 | { 44 | return this.FindElementByUid("CheckListBox").ToListBox(); 45 | } 46 | } 47 | 48 | public CruciatusElement TextBox2 49 | { 50 | get 51 | { 52 | return this.FindElementByUid("TextBox2"); 53 | } 54 | } 55 | 56 | #endregion 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Map/WindowsFormsTestApplicationApp.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus; 6 | using Winium.Cruciatus.Core; 7 | 8 | #endregion 9 | 10 | public class WindowsFormsTestApplicationApp : Application 11 | { 12 | #region Constructors and Destructors 13 | 14 | public WindowsFormsTestApplicationApp(string fullPath) 15 | : base(fullPath) 16 | { 17 | } 18 | 19 | #endregion 20 | 21 | #region Public Properties 22 | 23 | public MainWindow Window 24 | { 25 | get 26 | { 27 | return new MainWindow(CruciatusFactory.Root, By.Uid("Form1")); 28 | } 29 | } 30 | 31 | #endregion 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region using 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | #endregion 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("WindowsFormsTestApplication.Tests")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("WindowsFormsTestApplication.Tests")] 16 | [assembly: AssemblyCopyright("Copyright © 2015")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("eb68f0b3-644f-458e-b812-106d15bee591")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/SetUpFixture.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | #endregion 8 | 9 | [SetUpFixture] 10 | public class SetUpFixture 11 | { 12 | #region Public Methods and Operators 13 | 14 | [SetUp] 15 | public void SetUp() 16 | { 17 | #if REMOTE 18 | Winium.Cruciatus.CruciatusFactory.Settings.AutomaticScreenshotCapture = true; 19 | #endif 20 | } 21 | 22 | #endregion 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/TestCases/CheckFirstTab.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WindowsFormsTestApplication.Tests.Map; 8 | 9 | using Winium.Cruciatus.Core; 10 | 11 | #endregion 12 | 13 | [TestFixture] 14 | public class CheckFirstTab 15 | { 16 | #region Fields 17 | 18 | private WindowsFormsTestApplicationApp application; 19 | 20 | private FirstTab firstTab; 21 | 22 | #endregion 23 | 24 | #region Public Methods and Operators 25 | 26 | [Test] 27 | public void CheckingChangeEnabledTextListBox() 28 | { 29 | this.firstTab.CheckBox1.Uncheck(); 30 | Assert.IsFalse(this.firstTab.CheckBox1.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 31 | Assert.IsFalse(this.firstTab.TextListBox.Properties.IsEnabled, "TextListBox включен после uncheсk-а."); 32 | 33 | this.firstTab.CheckBox1.Check(); 34 | Assert.IsTrue(this.firstTab.CheckBox1.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 35 | Assert.IsTrue(this.firstTab.TextListBox.Properties.IsEnabled, "TextListBox выключен после cheсk-а."); 36 | } 37 | 38 | [Test] 39 | public void CheckingCheckBox1() 40 | { 41 | this.firstTab.CheckBox1.Uncheck(); 42 | Assert.IsFalse(this.firstTab.CheckBox1.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 43 | 44 | this.firstTab.CheckBox1.Check(); 45 | Assert.IsTrue(this.firstTab.CheckBox1.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 46 | } 47 | 48 | [Test] 49 | public void CheckingSetTextButton() 50 | { 51 | this.firstTab.SetTextButton.Click(); 52 | } 53 | 54 | [Test] 55 | public void CheckingSetTextToTextBox1() 56 | { 57 | this.firstTab.TextBox1.SetText(null); 58 | this.firstTab.SetTextButton.Click(); 59 | 60 | var currentText = this.firstTab.TextBox1.Text(); 61 | Assert.AreEqual("CARAMBA", currentText, "После клика текст не стал = CARAMBA."); 62 | } 63 | 64 | [Test] 65 | public void CheckingTabItem1() 66 | { 67 | this.application.Window.TabItem1.Select(); 68 | } 69 | 70 | [Test] 71 | public void CheckingTextBox1() 72 | { 73 | const string StartText = "new test text"; 74 | this.firstTab.TextBox1.SetText(null); 75 | this.firstTab.TextBox1.SetText(StartText); 76 | 77 | var currentText = this.firstTab.TextBox1.Text(); 78 | Assert.AreEqual(StartText, currentText, "Текст после ввода не стал new test text."); 79 | } 80 | 81 | [Test] 82 | public void CheckingTextComboBox() 83 | { 84 | this.firstTab.TextComboBox.Expand(); 85 | 86 | var element = this.firstTab.TextComboBox.FindElement(By.Name("Quarter")); 87 | element.Click(); 88 | } 89 | 90 | [Test] 91 | public void CheckingTextListBox() 92 | { 93 | var month = this.firstTab.TextListBox.ScrollTo(By.Name("December")); 94 | month.Click(); 95 | 96 | month = this.firstTab.TextListBox.ScrollTo(By.Name("October")); 97 | month.Click(); 98 | } 99 | 100 | [TestFixtureSetUp] 101 | public void FixtureSetUp() 102 | { 103 | TestClassHelper.Initialize(out this.application); 104 | 105 | this.firstTab = this.application.Window.TabItem1; 106 | } 107 | 108 | [TestFixtureTearDown] 109 | public void FixtureTearDown() 110 | { 111 | TestClassHelper.Cleanup(this.application); 112 | } 113 | 114 | #endregion 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/TestCases/CheckSecondTab.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WindowsFormsTestApplication.Tests.Map; 8 | 9 | #endregion 10 | 11 | [TestFixture] 12 | public class CheckSecondTab 13 | { 14 | #region Fields 15 | 16 | private WindowsFormsTestApplicationApp application; 17 | 18 | private SecondTab secondTab; 19 | 20 | #endregion 21 | 22 | #region Public Methods and Operators 23 | 24 | [Test] 25 | public void CheckingChangeAfterCheckBox2() 26 | { 27 | var monthMarch = this.secondTab.CheckListBox.ScrollToCheckBoxByName("March"); 28 | Assert.AreEqual(false, monthMarch.IsToggleOn, "Чекбокс March в check состоянии."); 29 | 30 | var monthDecember = this.secondTab.CheckListBox.ScrollToCheckBoxByName("December"); 31 | Assert.AreEqual(false, monthDecember.IsToggleOn, "Чекбокс December в check состоянии."); 32 | 33 | this.secondTab.CheckBox2.Check(); 34 | Assert.AreEqual(true, this.secondTab.CheckBox2.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 35 | 36 | this.secondTab.CheckListBox.ScrollToCheckBoxByName("March"); 37 | Assert.AreEqual(true, monthMarch.IsToggleOn, "Чекбокс March остался в uncheck состоянии."); 38 | 39 | this.secondTab.CheckListBox.ScrollToCheckBoxByName("December"); 40 | Assert.AreEqual(true, monthDecember.IsToggleOn, "Чекбокс December остался в uncheck состоянии."); 41 | } 42 | 43 | [Test] 44 | public void CheckingChangeEnabledButton() 45 | { 46 | if (!this.secondTab.TextBox2.Properties.IsEnabled) 47 | { 48 | this.secondTab.ChangeEnabledButton.Click(); 49 | } 50 | 51 | this.secondTab.ChangeEnabledButton.Click(); 52 | Assert.AreEqual(false, this.secondTab.TextBox2.Properties.IsEnabled); 53 | 54 | this.secondTab.ChangeEnabledButton.Click(); 55 | Assert.AreEqual(true, this.secondTab.TextBox2.Properties.IsEnabled); 56 | } 57 | 58 | [Test] 59 | public void CheckingCheckBox2() 60 | { 61 | this.secondTab.CheckBox2.Uncheck(); 62 | Assert.AreEqual(false, this.secondTab.CheckBox2.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 63 | 64 | this.secondTab.CheckBox2.Check(); 65 | Assert.AreEqual(true, this.secondTab.CheckBox2.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 66 | } 67 | 68 | [Test] 69 | public void CheckingCheckListBox() 70 | { 71 | var month = this.secondTab.CheckListBox.ScrollToCheckBoxByName("December"); 72 | 73 | month.Check(); 74 | Assert.AreEqual(true, month.IsToggleOn, "Чекбокс December в uncheck состоянии после check."); 75 | } 76 | 77 | [Test] 78 | public void CheckingTabItem2() 79 | { 80 | this.secondTab.Select(); 81 | Assert.AreEqual(true, this.secondTab.IsSelection, "Вкладка 2 оказалась не выбрана"); 82 | } 83 | 84 | [Test] 85 | public void CheckingTextBox2() 86 | { 87 | this.secondTab.TextBox2.SetText("start test text"); 88 | var startText = this.secondTab.TextBox2.Text(); 89 | 90 | this.secondTab.TextBox2.SetText("new test text"); 91 | var currentText = this.secondTab.TextBox2.Text(); 92 | 93 | Assert.AreNotEqual(startText, currentText, "Текст не изменился."); 94 | } 95 | 96 | [TestFixtureSetUp] 97 | public void FixtureSetUp() 98 | { 99 | TestClassHelper.Initialize(out this.application); 100 | 101 | this.secondTab = this.application.Window.TabItem2; 102 | this.secondTab.Select(); 103 | } 104 | 105 | [TestFixtureTearDown] 106 | public void FixtureTearDown() 107 | { 108 | TestClassHelper.Cleanup(this.application); 109 | } 110 | 111 | #endregion 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/TestClassHelper.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Configuration; 7 | 8 | using NUnit.Framework; 9 | 10 | using WindowsFormsTestApplication.Tests.Map; 11 | 12 | #endregion 13 | 14 | public static class TestClassHelper 15 | { 16 | #region Public Methods and Operators 17 | 18 | public static void Cleanup(WindowsFormsTestApplicationApp application) 19 | { 20 | var isClosed = application.Close() || application.Kill(); 21 | Assert.IsTrue(isClosed, "Не удалось завершить приложение WindowsFormsTestApplication."); 22 | } 23 | 24 | public static void Initialize(out WindowsFormsTestApplicationApp application) 25 | { 26 | var appsFolderEnvVar = ConfigurationManager.AppSettings.Get("AppsFolderEnvVar"); 27 | var appsFolder = Environment.GetEnvironmentVariable(appsFolderEnvVar); 28 | var appPath = appsFolder + ConfigurationManager.AppSettings.Get("PathToExe"); 29 | application = new WindowsFormsTestApplicationApp(appPath); 30 | application.Start(); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/WindowsFormsTestApplication.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A} 8 | Library 9 | Properties 10 | WindowsFormsTestApplication.Tests 11 | WindowsFormsTestApplication.Tests 12 | v4.5 13 | 512 14 | ..\..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | {45982320-d316-4afb-b350-15eae32f4d4c} 64 | Winium.Cruciatus 65 | 66 | 67 | 68 | 69 | 70 | 71 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 72 | 73 | 74 | 75 | 82 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WindowsFormsTestApplication.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/CheckElementIsStaleProperty.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WpfTestApplication.Tests.Map; 8 | 9 | #endregion 10 | 11 | [TestFixture] 12 | public class CheckElementIsStaleProperty 13 | { 14 | #region Fields 15 | 16 | private WpfTestApplicationApp application; 17 | 18 | #endregion 19 | 20 | #region Public Methods and Operators 21 | 22 | [Test] 23 | public void ElementNotStaleTest() 24 | { 25 | Assert.IsFalse(this.application.MainWindow.IsStale); 26 | } 27 | 28 | [Test] 29 | public void FoundElementStaleTest() 30 | { 31 | var mainWindow = this.FindMainWindow(); 32 | 33 | this.CloseAppWithRetry(); 34 | Assert.IsTrue(mainWindow.IsStale); 35 | } 36 | 37 | [Test] 38 | public void NotFoundElementStaleTest() 39 | { 40 | this.CloseAppWithRetry(); 41 | Assert.IsTrue(this.application.MainWindow.IsStale); 42 | } 43 | 44 | [Test] 45 | public void NotFoundElementStaleWhenParentStaleTest() 46 | { 47 | var mainWindow = this.FindMainWindow(); 48 | 49 | this.CloseAppWithRetry(); 50 | Assert.IsTrue(mainWindow.TabItem1.IsStale); 51 | } 52 | 53 | [SetUp] 54 | public void SetUp() 55 | { 56 | TestClassHelper.Initialize(out this.application); 57 | } 58 | 59 | [TearDown] 60 | public void TearDown() 61 | { 62 | TestClassHelper.Cleanup(this.application); 63 | } 64 | 65 | #endregion 66 | 67 | #region Methods 68 | 69 | private void CloseAppWithRetry() 70 | { 71 | Assert.That(() => this.application.Close(), Is.True.After(2000)); 72 | } 73 | 74 | private MainWindow FindMainWindow() 75 | { 76 | var mainWindow = this.application.MainWindow; 77 | 78 | // Needed for real find main window element 79 | var winName = mainWindow.Properties.Name; 80 | 81 | return mainWindow; 82 | } 83 | 84 | #endregion 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/CheckFindByXPath.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using System.Linq; 6 | 7 | using NUnit.Framework; 8 | 9 | using Winium.Cruciatus; 10 | using Winium.Cruciatus.Core; 11 | 12 | using WpfTestApplication.Tests.Map; 13 | 14 | #endregion 15 | 16 | [TestFixture] 17 | public class CheckFindByXPath 18 | { 19 | #region Fields 20 | 21 | private WpfTestApplicationApp application; 22 | 23 | #endregion 24 | 25 | #region Public Methods and Operators 26 | 27 | [Test] 28 | public void FindElementsByPartName() 29 | { 30 | const string XPath = "*[starts-with(@Name, 'M')]"; 31 | var results = this.application.MainWindow.TabItem1.TextListBox.FindElements(By.XPath(XPath)).ToList(); 32 | Assert.That(results, Has.Count.EqualTo(2)); 33 | } 34 | 35 | [Test] 36 | public void FindMainWindowFromRoot() 37 | { 38 | const string XPath = "*[@AutomationId='WpfTestApplicationMainWindow']"; 39 | var mainWindow = CruciatusFactory.Root.FindElement(By.XPath(XPath)); 40 | Assert.AreEqual(mainWindow, this.application.MainWindow); 41 | } 42 | 43 | [Test] 44 | public void FindMainWindowUseRootXPathFunction() 45 | { 46 | const string XPath = "/*[@AutomationId='WpfTestApplicationMainWindow']"; 47 | var mainWindow = this.application.MainWindow.TabItem1.SetTextButton.FindElement(By.XPath(XPath)); 48 | Assert.AreEqual(mainWindow, this.application.MainWindow); 49 | } 50 | 51 | [TestFixtureSetUp] 52 | public void FixtureSetUp() 53 | { 54 | TestClassHelper.Initialize(out this.application); 55 | } 56 | 57 | [TestFixtureTearDown] 58 | public void FixtureTearDown() 59 | { 60 | TestClassHelper.Cleanup(this.application); 61 | } 62 | 63 | #endregion 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/CheckFocusedElement.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using Winium.Cruciatus; 8 | 9 | using WpfTestApplication.Tests.Map; 10 | 11 | #endregion 12 | 13 | [TestFixture] 14 | public class CheckFocusedElement 15 | { 16 | #region Fields 17 | 18 | private WpfTestApplicationApp application; 19 | 20 | #endregion 21 | 22 | #region Public Methods and Operators 23 | 24 | [TestFixtureSetUp] 25 | public void FixtureSetUp() 26 | { 27 | TestClassHelper.Initialize(out this.application); 28 | } 29 | 30 | [TestFixtureTearDown] 31 | public void FixtureTearDown() 32 | { 33 | TestClassHelper.Cleanup(this.application); 34 | } 35 | 36 | [Test] 37 | public void GetFocusedElement() 38 | { 39 | var textBox = this.application.MainWindow.TabItem1.TextBox1; 40 | 41 | textBox.Click(); 42 | var textBoxToo = CruciatusFactory.FocusedElement; 43 | 44 | Assert.AreEqual(textBox, textBoxToo); 45 | } 46 | 47 | #endregion 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/CheckMouse.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using Winium.Cruciatus; 8 | 9 | #endregion 10 | 11 | [TestFixture] 12 | public class CheckMouse 13 | { 14 | [TestCase(50, 50)] 15 | [TestCase(-50, -50)] 16 | public void MouseMoveTo(int x, int y) 17 | { 18 | var oldPoint = CruciatusFactory.Mouse.CurrentCursorPos; 19 | oldPoint.Offset(x, y); 20 | 21 | CruciatusFactory.Mouse.MoveCursorPos(x, y); 22 | var newPoint = CruciatusFactory.Mouse.CurrentCursorPos; 23 | 24 | Assert.That(oldPoint.X, Is.EqualTo(newPoint.X).Within(1)); 25 | Assert.That(oldPoint.Y, Is.EqualTo(newPoint.Y).Within(1)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/ElementExtension.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Elements; 9 | using Winium.Cruciatus.Extensions; 10 | 11 | #endregion 12 | 13 | public static class ElementExtension 14 | { 15 | #region Public Methods and Operators 16 | 17 | public static CheckBox GetCheckBoxByName(this CruciatusElement element, string name) 18 | { 19 | return element.FindElement(By.Name(name).AndType(ControlType.CheckBox)).ToCheckBox(); 20 | } 21 | 22 | public static CheckBox ScrollToCheckBoxByName(this ListBox element, string name) 23 | { 24 | return element.ScrollTo(By.Name(name).AndType(ControlType.CheckBox)).ToCheckBox(); 25 | } 26 | 27 | #endregion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/FirstRibbonTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class FirstRibbonTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public FirstRibbonTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CruciatusElement RibbonButton 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("RibbonButton"); 29 | } 30 | } 31 | 32 | public ComboBox RibbonCheckComboBox 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("RibbonCheckComboBox").ToComboBox(); 37 | } 38 | } 39 | 40 | public ComboBox RibbonTextComboBox 41 | { 42 | get 43 | { 44 | return this.FindElementByUid("RibbonTextComboBox").ToComboBox(); 45 | } 46 | } 47 | 48 | #endregion 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/FirstTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class FirstTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public FirstTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CheckBox CheckBox1 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("CheckBox1").ToCheckBox(); 29 | } 30 | } 31 | 32 | public CruciatusElement SetTextButton 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("SetTextButton"); 37 | } 38 | } 39 | 40 | public CruciatusElement TextBox1 41 | { 42 | get 43 | { 44 | return this.FindElementByUid("TextBox1"); 45 | } 46 | } 47 | 48 | public ComboBox TextComboBox 49 | { 50 | get 51 | { 52 | return this.FindElementByUid("TextComboBox").ToComboBox(); 53 | } 54 | } 55 | 56 | public ListBox TextListBox 57 | { 58 | get 59 | { 60 | return this.FindElementByUid("TextListBox").ToListBox(); 61 | } 62 | } 63 | 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/MainWindow.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class MainWindow : CruciatusElement 12 | { 13 | #region Constructors and Destructors 14 | 15 | public MainWindow(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public OpenFileDialog OpenFileDialog 25 | { 26 | get 27 | { 28 | return new OpenFileDialog(this, By.Name("Открытие").OrName("Open")); 29 | } 30 | } 31 | 32 | public Menu RibbonMenu 33 | { 34 | get 35 | { 36 | return new Menu(this, By.Uid("RibbonMenu")); 37 | } 38 | } 39 | 40 | public FirstRibbonTab RibbonTabItem1 41 | { 42 | get 43 | { 44 | return new FirstRibbonTab(this, By.Uid("RibbonTabItem1")); 45 | } 46 | } 47 | 48 | public SecondRibbonTab RibbonTabItem2 49 | { 50 | get 51 | { 52 | return new SecondRibbonTab(this, By.Uid("RibbonTabItem2")); 53 | } 54 | } 55 | 56 | public SaveFileDialog SaveFileDialog 57 | { 58 | get 59 | { 60 | return new SaveFileDialog(this, By.Name("Сохранение").OrName("Save As")); 61 | } 62 | } 63 | 64 | public Menu SetTextButtonContextMenu 65 | { 66 | get 67 | { 68 | return new Menu(this, By.Uid("SetTextButtonContextMenu")); 69 | } 70 | } 71 | 72 | public Menu SimpleMenu 73 | { 74 | get 75 | { 76 | return this.FindElementByUid("SimpleMenu").ToMenu(); 77 | } 78 | } 79 | 80 | public FirstTab TabItem1 81 | { 82 | get 83 | { 84 | return new FirstTab(this, By.Uid("TabItem1")); 85 | } 86 | } 87 | 88 | public SecondTab TabItem2 89 | { 90 | get 91 | { 92 | return new SecondTab(this, By.Uid("TabItem2")); 93 | } 94 | } 95 | 96 | public ThirdTab TabItem3 97 | { 98 | get 99 | { 100 | return new ThirdTab(this, By.Uid("TabItem3")); 101 | } 102 | } 103 | 104 | #endregion 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/SecondRibbonTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class SecondRibbonTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public SecondRibbonTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CheckBox RibbonCheckBox 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("RibbonCheckBox").ToCheckBox(); 29 | } 30 | } 31 | 32 | public CheckBox RibbonToggleButton 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("RibbonToggleButton").ToCheckBox(); 37 | } 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/SecondTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | using Winium.Cruciatus.Extensions; 8 | 9 | #endregion 10 | 11 | public class SecondTab : TabItem 12 | { 13 | #region Constructors and Destructors 14 | 15 | public SecondTab(CruciatusElement parent, By getStrategy) 16 | : base(parent, getStrategy) 17 | { 18 | } 19 | 20 | #endregion 21 | 22 | #region Public Properties 23 | 24 | public CruciatusElement ChangeEnabledButton 25 | { 26 | get 27 | { 28 | return this.FindElementByUid("ChangeEnabledButton"); 29 | } 30 | } 31 | 32 | public CheckBox CheckBox2 33 | { 34 | get 35 | { 36 | return this.FindElementByUid("CheckBox2").ToCheckBox(); 37 | } 38 | } 39 | 40 | public ComboBox CheckComboBox 41 | { 42 | get 43 | { 44 | return this.FindElementByUid("CheckComboBox").ToComboBox(); 45 | } 46 | } 47 | 48 | public ListBox CheckListBox 49 | { 50 | get 51 | { 52 | return this.FindElementByUid("CheckListBox").ToListBox(); 53 | } 54 | } 55 | 56 | public CruciatusElement TextBox2 57 | { 58 | get 59 | { 60 | return this.FindElementByUid("TextBox2"); 61 | } 62 | } 63 | 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/ThirdTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using Winium.Cruciatus.Core; 6 | using Winium.Cruciatus.Elements; 7 | 8 | #endregion 9 | 10 | public class ThirdTab : TabItem 11 | { 12 | #region Constructors and Destructors 13 | 14 | public ThirdTab(CruciatusElement parent, By getStrategy) 15 | : base(parent, getStrategy) 16 | { 17 | } 18 | 19 | #endregion 20 | 21 | #region Public Properties 22 | 23 | public CruciatusElement OpenFileDialogButton 24 | { 25 | get 26 | { 27 | return this.FindElementByUid("OpenFileDialogButton"); 28 | } 29 | } 30 | 31 | public CruciatusElement SaveFileDialogButton 32 | { 33 | get 34 | { 35 | return this.FindElementByUid("SaveFileDialogButton"); 36 | } 37 | } 38 | 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Map/WpfTestApplicationApp.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.Map 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus; 8 | using Winium.Cruciatus.Core; 9 | 10 | #endregion 11 | 12 | public class WpfTestApplicationApp : Application 13 | { 14 | #region Constructors and Destructors 15 | 16 | public WpfTestApplicationApp(string fullPath) 17 | : base(fullPath) 18 | { 19 | } 20 | 21 | #endregion 22 | 23 | #region Public Properties 24 | 25 | public MainWindow MainWindow 26 | { 27 | get 28 | { 29 | return new MainWindow(CruciatusFactory.Root, By.Uid(TreeScope.Children, "WpfTestApplicationMainWindow")); 30 | } 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region using 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | #endregion 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("WpfTestApplication.Tests")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("WpfTestApplication.Tests")] 16 | [assembly: AssemblyCopyright("Copyright © 2015")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("2370421a-e461-41d8-a5b6-1aba1a24b727")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/SetUpFixture.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | #endregion 8 | 9 | [SetUpFixture] 10 | public class SetUpFixture 11 | { 12 | #region Public Methods and Operators 13 | 14 | [SetUp] 15 | public void SetUp() 16 | { 17 | #if REMOTE 18 | Winium.Cruciatus.CruciatusFactory.Settings.AutomaticScreenshotCapture = true; 19 | #endif 20 | } 21 | 22 | #endregion 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/TestCases/CheckFirstTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using Winium.Cruciatus; 8 | using Winium.Cruciatus.Core; 9 | using Winium.Cruciatus.Elements; 10 | 11 | using WpfTestApplication.Tests.Map; 12 | 13 | #endregion 14 | 15 | [TestFixture] 16 | public class CheckFirstTab 17 | { 18 | #region Static Fields 19 | 20 | private static WpfTestApplicationApp application; 21 | 22 | private static FirstTab firstTab; 23 | 24 | private static Menu setTextButtonContextMenu; 25 | 26 | #endregion 27 | 28 | #region Public Methods and Operators 29 | 30 | [Test] 31 | public void CheckingChangeEnabledTextListBox() 32 | { 33 | Assert.IsTrue(firstTab.TextListBox.Properties.IsEnabled, "TextListBox в начале оказался не включен."); 34 | 35 | firstTab.CheckBox1.Uncheck(); 36 | Assert.IsFalse(firstTab.CheckBox1.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 37 | 38 | Assert.IsFalse(firstTab.TextListBox.Properties.IsEnabled, "TextListBox не стал включенным."); 39 | } 40 | 41 | [Test] 42 | public void CheckingCheckBox1() 43 | { 44 | firstTab.CheckBox1.Uncheck(); 45 | Assert.IsFalse(firstTab.CheckBox1.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 46 | 47 | firstTab.CheckBox1.Check(); 48 | Assert.IsTrue(firstTab.CheckBox1.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 49 | } 50 | 51 | [Test] 52 | public void CheckingSetTextButton() 53 | { 54 | firstTab.SetTextButton.Click(); 55 | 56 | var currentText = firstTab.TextBox1.Text(); 57 | Assert.AreEqual(currentText, "CARAMBA", "Верный текст не установлен в текстовое поле."); 58 | } 59 | 60 | [Test] 61 | public void CheckingSetTextButtonContextMenu1() 62 | { 63 | firstTab.SetTextButton.Click(MouseButton.Right); 64 | setTextButtonContextMenu.SelectItem("Menu item 1"); 65 | 66 | firstTab.SetTextButton.Click(MouseButton.Right); 67 | Assert.IsFalse( 68 | setTextButtonContextMenu.GetItem("Menu item 3").Properties.IsEnabled, 69 | "Пункт Menu item 3 оказался активен."); 70 | CruciatusFactory.Keyboard.SendEscape(); 71 | } 72 | 73 | [Test] 74 | public void CheckingTabItem2() 75 | { 76 | firstTab.Select(); 77 | } 78 | 79 | [Test] 80 | public void CheckingTextBox1() 81 | { 82 | const string Text = "new test text"; 83 | 84 | firstTab.TextBox1.SetText(Text); 85 | var currentText = firstTab.TextBox1.Text(); 86 | 87 | Assert.AreEqual(Text, currentText, "Текст не изменился."); 88 | } 89 | 90 | [Test] 91 | public void CheckingTextComboBox() 92 | { 93 | firstTab.TextComboBox.Expand(); 94 | 95 | var element = firstTab.TextComboBox.FindElement(By.Name("Quarter")); 96 | Assert.IsNotNull(element); 97 | 98 | element.Click(); 99 | } 100 | 101 | [Test] 102 | public void CheckingTextListBox() 103 | { 104 | if (!firstTab.TextListBox.Properties.IsEnabled) 105 | { 106 | firstTab.CheckBox1.Check(); 107 | } 108 | 109 | firstTab.TextListBox.ScrollTo(By.Name("December")).Click(); 110 | 111 | firstTab.TextListBox.ScrollTo(By.Name("October")).Click(); 112 | } 113 | 114 | [TestFixtureSetUp] 115 | public void FixtureSetUp() 116 | { 117 | TestClassHelper.Initialize(out application); 118 | 119 | firstTab = application.MainWindow.TabItem1; 120 | setTextButtonContextMenu = application.MainWindow.SetTextButtonContextMenu; 121 | 122 | firstTab.Select(); 123 | } 124 | 125 | [TestFixtureTearDown] 126 | public void FixtureTearDown() 127 | { 128 | TestClassHelper.Cleanup(application); 129 | } 130 | 131 | #endregion 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/TestCases/CheckRibbon.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Elements; 9 | 10 | using WpfTestApplication.Tests.Map; 11 | 12 | #endregion 13 | 14 | [TestFixture] 15 | public class CheckRibbon 16 | { 17 | #region Fields 18 | 19 | private WpfTestApplicationApp application; 20 | 21 | private FirstRibbonTab firstRibbonTab; 22 | 23 | private Menu ribbonMenu; 24 | 25 | private SecondRibbonTab secondRibbonTab; 26 | 27 | private Menu simpleMenu; 28 | 29 | #endregion 30 | 31 | #region Public Methods and Operators 32 | 33 | [Test] 34 | public void CheckingRibbonButton() 35 | { 36 | this.firstRibbonTab.Select(); 37 | 38 | this.firstRibbonTab.RibbonButton.Click(); 39 | } 40 | 41 | [Test] 42 | public void CheckingRibbonCheckBox() 43 | { 44 | this.secondRibbonTab.Select(); 45 | 46 | this.secondRibbonTab.RibbonCheckBox.Uncheck(); 47 | Assert.IsFalse(this.secondRibbonTab.RibbonCheckBox.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 48 | 49 | this.secondRibbonTab.RibbonCheckBox.Check(); 50 | Assert.IsTrue(this.secondRibbonTab.RibbonCheckBox.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 51 | } 52 | 53 | [Test] 54 | public void CheckingRibbonCheckComboBox() 55 | { 56 | this.firstRibbonTab.Select(); 57 | 58 | this.firstRibbonTab.RibbonCheckComboBox.Expand(); 59 | Assert.IsTrue(this.firstRibbonTab.RibbonCheckComboBox.IsExpanded); 60 | 61 | var element = this.firstRibbonTab.RibbonCheckComboBox.GetCheckBoxByName("Quarter"); 62 | element.Check(); 63 | Assert.IsTrue(element.IsToggleOn, "Чекбокс Quarter в uncheck состоянии после check."); 64 | 65 | element = this.firstRibbonTab.RibbonCheckComboBox.GetCheckBoxByName("Week"); 66 | element.Check(); 67 | Assert.IsTrue(element.IsToggleOn, "Чекбокс Week в uncheck состоянии после check."); 68 | 69 | this.firstRibbonTab.RibbonCheckComboBox.Collapse(); 70 | } 71 | 72 | [Test] 73 | public void CheckingRibbonTabItem1() 74 | { 75 | this.firstRibbonTab.Select(); 76 | Assert.IsTrue(this.firstRibbonTab.IsSelection); 77 | } 78 | 79 | [Test] 80 | public void CheckingRibbonTabItem2() 81 | { 82 | this.secondRibbonTab.Select(); 83 | Assert.IsTrue(this.secondRibbonTab.IsSelection); 84 | } 85 | 86 | [Test] 87 | public void CheckingRibbonTextComboBox() 88 | { 89 | this.firstRibbonTab.Select(); 90 | 91 | this.firstRibbonTab.RibbonTextComboBox.Expand(); 92 | Assert.IsTrue(this.firstRibbonTab.RibbonTextComboBox.IsExpanded); 93 | 94 | this.firstRibbonTab.RibbonTextComboBox.FindElement(By.Name("Quarter")).Click(); 95 | } 96 | 97 | [Test] 98 | public void CheckingRibbonToggleButton() 99 | { 100 | this.secondRibbonTab.Select(); 101 | 102 | this.secondRibbonTab.RibbonToggleButton.Uncheck(); 103 | Assert.IsFalse( 104 | this.secondRibbonTab.RibbonToggleButton.IsToggleOn, 105 | "Чекбокс в check состоянии после uncheck."); 106 | 107 | this.secondRibbonTab.RibbonToggleButton.Check(); 108 | Assert.IsTrue( 109 | this.secondRibbonTab.RibbonToggleButton.IsToggleOn, 110 | "Чекбокс в uncheck состоянии после check."); 111 | } 112 | 113 | [Test] 114 | public void CheckingTabItem1() 115 | { 116 | this.application.MainWindow.TabItem1.Select(); 117 | Assert.IsTrue(this.application.MainWindow.TabItem1.IsSelection); 118 | } 119 | 120 | [TestFixtureSetUp] 121 | public void FixtureSetUp() 122 | { 123 | TestClassHelper.Initialize(out this.application); 124 | 125 | this.simpleMenu = this.application.MainWindow.SimpleMenu; 126 | this.ribbonMenu = this.application.MainWindow.RibbonMenu; 127 | this.firstRibbonTab = this.application.MainWindow.RibbonTabItem1; 128 | this.secondRibbonTab = this.application.MainWindow.RibbonTabItem2; 129 | } 130 | 131 | [TestFixtureTearDown] 132 | public void FixtureTearDown() 133 | { 134 | TestClassHelper.Cleanup(this.application); 135 | } 136 | 137 | [Test] 138 | public void RibbonMenuTestMethod1() 139 | { 140 | this.ribbonMenu.Click(); 141 | this.ribbonMenu.SelectItem("Print$Open"); 142 | } 143 | 144 | [Test] 145 | public void RibbonMenuTestMethod2() 146 | { 147 | this.ribbonMenu.Click(); 148 | this.ribbonMenu.SelectItem("Print$New$Save"); 149 | } 150 | 151 | [Test] 152 | public void SimpleMenuTestMethod1() 153 | { 154 | const string HeadersPath = "Level1$MultiLevel2$Level3"; 155 | this.simpleMenu.SelectItem(HeadersPath); 156 | } 157 | 158 | [Test] 159 | public void SimpleMenuTestMethod2() 160 | { 161 | const string HeadersPath = "Level1$MultiLevel2$MultiLevel3$MultiLevel4$Level5"; 162 | this.simpleMenu.SelectItem(HeadersPath); 163 | this.simpleMenu.SelectItem(HeadersPath); 164 | } 165 | 166 | #endregion 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/TestCases/CheckSecondTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WpfTestApplication.Tests.Map; 8 | 9 | #endregion 10 | 11 | [TestFixture] 12 | public class CheckSecondTab 13 | { 14 | #region Fields 15 | 16 | private WpfTestApplicationApp application; 17 | 18 | private SecondTab secondTab; 19 | 20 | #endregion 21 | 22 | #region Public Methods and Operators 23 | 24 | [Test] 25 | public void CheckingChangeAfterCheckBox2() 26 | { 27 | this.secondTab.CheckBox2.Check(); 28 | this.secondTab.CheckBox2.Uncheck(); 29 | Assert.AreEqual(false, this.secondTab.CheckBox2.IsToggleOn, "Чекбокс в check состоянии после uncheck."); 30 | 31 | var monthMarch = this.secondTab.CheckListBox.GetCheckBoxByName("March"); 32 | var monthDecember = this.secondTab.CheckListBox.ScrollToCheckBoxByName("December"); 33 | 34 | this.secondTab.CheckBox2.Check(); 35 | Assert.AreEqual(true, this.secondTab.CheckBox2.IsToggleOn, "Чекбокс в uncheck состоянии после check."); 36 | Assert.AreEqual(true, monthMarch.IsToggleOn, "У чекбокса March не изменилась чекнутость."); 37 | Assert.AreEqual(true, monthDecember.IsToggleOn, "У чекбокса December не изменилась чекнутость."); 38 | } 39 | 40 | [Test] 41 | public void CheckingChangeEnabledButton() 42 | { 43 | this.secondTab.ChangeEnabledButton.Click(); 44 | } 45 | 46 | [Test] 47 | public void CheckingChangeEnabledTextBox2() 48 | { 49 | var isEnabled = this.secondTab.TextBox2.Properties.IsEnabled; 50 | 51 | this.secondTab.ChangeEnabledButton.Click(); 52 | 53 | Assert.AreNotEqual( 54 | isEnabled, 55 | this.secondTab.TextBox2.Properties.IsEnabled, 56 | "Включенность TextBox2 не изменилась."); 57 | } 58 | 59 | [Test] 60 | public void CheckingCheckBox2() 61 | { 62 | this.secondTab.CheckBox2.Uncheck(); 63 | Assert.That( 64 | this.secondTab.CheckBox2.IsToggleOn, 65 | Is.False.After(100, 2000), 66 | "Чекбокс в check состоянии после uncheck."); 67 | 68 | this.secondTab.CheckBox2.Check(); 69 | Assert.That( 70 | this.secondTab.CheckBox2.IsToggleOn, 71 | Is.True.After(100, 2000), 72 | "Чекбокс в uncheck состоянии после check."); 73 | } 74 | 75 | [Test] 76 | public void CheckingCheckComboBox() 77 | { 78 | this.secondTab.CheckComboBox.Expand(); 79 | Assert.AreEqual(true, this.secondTab.CheckComboBox.IsExpanded); 80 | 81 | var element = this.secondTab.CheckComboBox.GetCheckBoxByName("Quarter"); 82 | 83 | element.Check(); 84 | Assert.That( 85 | element.IsToggleOn, 86 | Is.True.After(100, 2000), 87 | "Чекбокс Quarter в uncheck состоянии после check."); 88 | 89 | element = this.secondTab.CheckComboBox.GetCheckBoxByName("Week"); 90 | 91 | element.Check(); 92 | Assert.AreEqual(true, element.IsToggleOn, "Чекбокс Week в uncheck состоянии после check."); 93 | 94 | this.secondTab.CheckComboBox.Collapse(); 95 | Assert.AreEqual(false, this.secondTab.CheckComboBox.IsExpanded); 96 | } 97 | 98 | [Test] 99 | public void CheckingCheckListBox() 100 | { 101 | var month = this.secondTab.CheckListBox.ScrollToCheckBoxByName("December"); 102 | month.Check(); 103 | Assert.AreEqual(true, month.IsToggleOn, "Чекбокс December в uncheck состоянии после check."); 104 | 105 | month = this.secondTab.CheckListBox.ScrollToCheckBoxByName("October"); 106 | month.Check(); 107 | Assert.AreEqual(true, month.IsToggleOn, "Чекбокс 10ый в uncheck состоянии после check."); 108 | } 109 | 110 | [Test] 111 | public void CheckingTabItem2() 112 | { 113 | this.secondTab.Select(); 114 | Assert.IsTrue(this.secondTab.IsSelection); 115 | } 116 | 117 | [Test] 118 | public void CheckingTextBox2() 119 | { 120 | if (!this.secondTab.TextBox2.Properties.IsEnabled) 121 | { 122 | this.secondTab.ChangeEnabledButton.Click(); 123 | } 124 | 125 | var startText = this.secondTab.TextBox2.Text(); 126 | 127 | this.secondTab.TextBox2.SetText("new test text"); 128 | 129 | var currentText = this.secondTab.TextBox2.Text(); 130 | 131 | Assert.AreNotEqual(startText, currentText, "Текст не изменился."); 132 | } 133 | 134 | [TestFixtureSetUp] 135 | public void FixtureSetUp() 136 | { 137 | TestClassHelper.Initialize(out this.application); 138 | 139 | this.secondTab = this.application.MainWindow.TabItem2; 140 | 141 | this.secondTab.Select(); 142 | Assert.IsTrue(this.secondTab.IsSelection); 143 | } 144 | 145 | [TestFixtureTearDown] 146 | public void FixtureTearDown() 147 | { 148 | TestClassHelper.Cleanup(this.application); 149 | } 150 | 151 | #endregion 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/TestCases/CheckThirdTab.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests.TestCases 2 | { 3 | #region using 4 | 5 | using NUnit.Framework; 6 | 7 | using WpfTestApplication.Tests.Map; 8 | 9 | #endregion 10 | 11 | [TestFixture] 12 | public class CheckThirdTab 13 | { 14 | #region Fields 15 | 16 | private WpfTestApplicationApp application; 17 | 18 | private ThirdTab thirdTab; 19 | 20 | #endregion 21 | 22 | #region Public Methods and Operators 23 | 24 | [Test] 25 | public void CheckingOpenFileDialog() 26 | { 27 | this.thirdTab.OpenFileDialogButton.Click(); 28 | 29 | var openFileDialog = this.application.MainWindow.OpenFileDialog; 30 | var fileName = openFileDialog.FileNameComboBox.Text(); 31 | Assert.AreEqual("Program.cs", fileName); 32 | 33 | openFileDialog.CancelButton.Click(); 34 | } 35 | 36 | [Test] 37 | public void CheckingSaveFileDialog() 38 | { 39 | this.thirdTab.SaveFileDialogButton.Click(); 40 | 41 | var saveFileDialog = this.application.MainWindow.SaveFileDialog; 42 | var fileName = saveFileDialog.FileNameComboBox.Text(); 43 | Assert.AreEqual("Program.cs", fileName); 44 | 45 | var fileType = saveFileDialog.FileTypeComboBox.SelectedItem().Properties.Name; 46 | Assert.AreEqual("Visual C# Files (*.cs)", fileType); 47 | 48 | saveFileDialog.CancelButton.Click(); 49 | } 50 | 51 | [Test] 52 | public void CheckingTabItem3() 53 | { 54 | this.thirdTab.Select(); 55 | Assert.AreEqual(true, this.thirdTab.IsSelection, "Третья вкладка оказалось не выбранной"); 56 | } 57 | 58 | [TestFixtureSetUp] 59 | public void FixtureSetUp() 60 | { 61 | TestClassHelper.Initialize(out this.application); 62 | 63 | this.thirdTab = this.application.MainWindow.TabItem3; 64 | } 65 | 66 | [TestFixtureTearDown] 67 | public void FixtureTearDown() 68 | { 69 | TestClassHelper.Cleanup(this.application); 70 | } 71 | 72 | [SetUp] 73 | public void TestSetUp() 74 | { 75 | this.thirdTab.Select(); 76 | } 77 | 78 | #endregion 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/TestClassHelper.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication.Tests 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Configuration; 7 | 8 | using NUnit.Framework; 9 | 10 | using WpfTestApplication.Tests.Map; 11 | 12 | #endregion 13 | 14 | public static class TestClassHelper 15 | { 16 | #region Public Methods and Operators 17 | 18 | public static void Cleanup(WpfTestApplicationApp application) 19 | { 20 | var isClosed = application.Close() || application.Kill(); 21 | Assert.IsTrue(isClosed, "Не удалось завершить приложение WpfTestApplication."); 22 | } 23 | 24 | public static void Initialize(out WpfTestApplicationApp application) 25 | { 26 | var appsFolderEnvVar = ConfigurationManager.AppSettings.Get("AppsFolderEnvVar"); 27 | var appsFolder = Environment.GetEnvironmentVariable(appsFolderEnvVar); 28 | var appPath = appsFolder + ConfigurationManager.AppSettings.Get("PathToExe"); 29 | application = new WpfTestApplicationApp(appPath); 30 | application.Start(); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/WpfTestApplication.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9D5915DE-F329-47BA-B382-E70976B1A4B2} 8 | Library 9 | Properties 10 | WpfTestApplication.Tests 11 | WpfTestApplication.Tests 12 | v4.5 13 | 512 14 | ..\..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | {45982320-d316-4afb-b350-15eae32f4d4c} 74 | Winium.Cruciatus 75 | 76 | 77 | 78 | 79 | 80 | 81 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 82 | 83 | 84 | 85 | 92 | -------------------------------------------------------------------------------- /src/TestApplications.Tests/WpfTestApplication.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Form1.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Windows.Forms; 8 | 9 | #endregion 10 | 11 | /// 12 | /// The form 1. 13 | /// 14 | public partial class Form1 : Form 15 | { 16 | #region Fields 17 | 18 | private readonly List monthsList = new List 19 | { 20 | "January", 21 | "February", 22 | "March", 23 | "April", 24 | "May", 25 | "June", 26 | "July", 27 | "August", 28 | "September", 29 | "October", 30 | "November", 31 | "December" 32 | }; 33 | 34 | private readonly List timeSizeList = new List 35 | { 36 | "Day", 37 | "Week", 38 | "Decade", 39 | "Month", 40 | "Quarter", 41 | "Year" 42 | }; 43 | 44 | #endregion 45 | 46 | #region Constructors and Destructors 47 | 48 | public Form1() 49 | { 50 | this.InitializeComponent(); 51 | 52 | this.CheckBox1.Checked = true; 53 | 54 | // Fill TextComboBox 55 | this.TextComboBox.DataSource = this.timeSizeList; 56 | this.TextComboBox.SelectedIndex = -1; 57 | 58 | // Fill TextListBox 59 | this.TextListBox.DataSource = this.monthsList; 60 | this.TextListBox.SelectedIndex = -1; 61 | 62 | // Fill CheckListBox 63 | this.CheckListBox.DataSource = this.monthsList; 64 | 65 | // Fill DataGrid 66 | this.DataGrid.Rows.Add("1", "one"); 67 | this.DataGrid.Rows.Add("2", "two"); 68 | this.DataGrid.Rows.Add("3", "three"); 69 | this.DataGrid.Rows.Add("4", "four"); 70 | this.DataGrid.Rows.Add("5", "five"); 71 | } 72 | 73 | #endregion 74 | 75 | #region Methods 76 | 77 | private void ChangeEnabledButtonClick(object sender, EventArgs e) 78 | { 79 | this.TextBox2.Enabled = !this.TextBox2.Enabled; 80 | } 81 | 82 | private void CheckBox1CheckedChanged(object sender, EventArgs e) 83 | { 84 | this.TextListBox.Enabled = this.CheckBox1.Checked; 85 | } 86 | 87 | private void CheckBox2CheckedChanged(object sender, EventArgs e) 88 | { 89 | var check = this.CheckBox2.Checked; 90 | for (int i = 0; i < this.CheckListBox.Items.Count; ++i) 91 | { 92 | this.CheckListBox.SetItemChecked(i, check); 93 | } 94 | } 95 | 96 | private void SetTextButtonClick(object sender, EventArgs e) 97 | { 98 | this.TextBox1.Text = @"CARAMBA"; 99 | } 100 | 101 | #endregion 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Program.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsTestApplication 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Windows.Forms; 7 | 8 | #endregion 9 | 10 | internal static class Program 11 | { 12 | #region Methods 13 | 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] 18 | private static void Main() 19 | { 20 | Application.EnableVisualStyles(); 21 | Application.SetCompatibleTextRenderingDefault(false); 22 | Application.Run(new Form1()); 23 | } 24 | 25 | #endregion 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region using 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | #endregion 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("WindowsFormsTestApplication")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("2ГИС")] 15 | [assembly: AssemblyProduct("WindowsFormsTestApplication")] 16 | [assembly: AssemblyCopyright("Copyright © 2ГИС 2013")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("257d0d1c-29b0-4ddb-a6b5-7245ede64969")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowsFormsTestApplication.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsTestApplication.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowsFormsTestApplication.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/TestApplications/WindowsFormsTestApplication/WindowsFormsTestApplication.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5A44C751-4393-4BE1-9912-4C4C84B382B4} 8 | WinExe 9 | Properties 10 | WindowsFormsTestApplication 11 | WindowsFormsTestApplication 12 | v4.5 13 | 512 14 | UITestApps 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Form 44 | 45 | 46 | Form1.cs 47 | 48 | 49 | 50 | 51 | Form1.cs 52 | 53 | 54 | ResXFileCodeGenerator 55 | Resources.Designer.cs 56 | Designer 57 | 58 | 59 | True 60 | Resources.resx 61 | 62 | 63 | SettingsSingleFileGenerator 64 | Settings.Designer.cs 65 | 66 | 67 | True 68 | Settings.settings 69 | True 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | powershell.exe $dpath = $env:$(DeployPathEnvVarName); if ($dpath -ne $null) { New-Item -ItemType Directory -Path $dpath\$(ProjectName) -Force; Copy-Item $(TargetDir)\* $dpath\$(ProjectName) -Recurse -Force; Write-Host "Copy build files successful." } else { Write-Host "Copy build files stop. Environment variable '$(DeployPathEnvVarName)' not found." } 79 | 80 | 81 | 88 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/App.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication 2 | { 3 | /// 4 | /// Interaction logic for App.xaml 5 | /// 6 | public partial class App 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region using 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | #endregion 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("WpfTestApplication")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("WpfTestApplication")] 17 | [assembly: AssemblyCopyright("Copyright © 2013")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WpfTestApplication.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WpfTestApplication.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WpfTestApplication.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/RibbonTabExt.cs: -------------------------------------------------------------------------------- 1 | namespace WpfTestApplication 2 | { 3 | #region using 4 | 5 | using System.Linq; 6 | using System.Windows; 7 | using System.Windows.Automation.Peers; 8 | using System.Windows.Controls.Ribbon; 9 | 10 | #endregion 11 | 12 | public class RibbonTabExt : RibbonTab 13 | { 14 | #region Methods 15 | 16 | protected override AutomationPeer OnCreateAutomationPeer() 17 | { 18 | return new RibbonTabAutomationPeerExt(this); 19 | } 20 | 21 | #endregion 22 | 23 | // Класс наследуется от стандартного Peer для RibbonTab 24 | private class RibbonTabAutomationPeerExt : RibbonTabAutomationPeer 25 | { 26 | #region Constructors and Destructors 27 | 28 | public RibbonTabAutomationPeerExt(RibbonTab owner) 29 | : base(owner) 30 | { 31 | } 32 | 33 | #endregion 34 | 35 | // Меняем только возврат точки клика 36 | #region Methods 37 | 38 | protected override Point GetClickablePointCore() 39 | { 40 | // Получаем детей элемента 41 | var childs = this.GetChildrenCore(); 42 | 43 | if (childs != null) 44 | { 45 | // В детях ищем заголовок 46 | var header = 47 | childs.FirstOrDefault(peer => peer.GetAutomationControlType() == AutomationControlType.Header); 48 | 49 | // Если заголовок нашелся (а теоретически он должен быть всегда), возвращаем его точку клика 50 | if (header != null) 51 | { 52 | return header.GetClickablePoint(); 53 | } 54 | } 55 | 56 | // Если с заголовком что-то пошло не так, то...по дефолту 57 | return base.GetClickablePointCore(); 58 | } 59 | 60 | #endregion 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/TestApplications/WpfTestApplication/WpfTestApplication.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F} 8 | WinExe 9 | Properties 10 | WpfTestApplication 11 | WpfTestApplication 12 | v4.5 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | UITestApps 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 4.0 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | MSBuild:Compile 55 | Designer 56 | 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | App.xaml 64 | Code 65 | 66 | 67 | MainWindow.xaml 68 | Code 69 | 70 | 71 | 72 | 73 | Code 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | ResXFileCodeGenerator 87 | Resources.Designer.cs 88 | 89 | 90 | 91 | SettingsSingleFileGenerator 92 | Settings.Designer.cs 93 | 94 | 95 | 96 | 97 | 98 | 99 | powershell.exe $dpath = $env:$(DeployPathEnvVarName); if ($dpath -ne $null) { New-Item -ItemType Directory -Path $dpath\$(ProjectName) -Force; Copy-Item $(TargetDir)\* $dpath\$(ProjectName) -Recurse -Force; Write-Host "Copy build files successful." } else { Write-Host "Copy build files stop. Environment variable $(DeployPathEnvVarName) not found." } 100 | 101 | 102 | 109 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Application.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Diagnostics; 7 | using System.IO; 8 | 9 | using Winium.Cruciatus.Exceptions; 10 | 11 | #endregion 12 | 13 | /// 14 | /// Класс для запуска и завершения приложения. 15 | /// 16 | public class Application 17 | { 18 | #region Fields 19 | 20 | private readonly string executableFilePath; 21 | 22 | private Process process; 23 | 24 | #endregion 25 | 26 | #region Constructors and Destructors 27 | 28 | /// 29 | /// Создает объект класса. 30 | /// 31 | /// 32 | /// Полный путь до исполняемого файла. 33 | /// 34 | public Application(string executableFilePath) 35 | { 36 | if (executableFilePath == null) 37 | { 38 | throw new ArgumentNullException("executableFilePath"); 39 | } 40 | 41 | if (Path.IsPathRooted(executableFilePath)) 42 | { 43 | this.executableFilePath = executableFilePath; 44 | } 45 | else 46 | { 47 | var absolutePath = Path.Combine(Environment.CurrentDirectory, executableFilePath); 48 | this.executableFilePath = Path.GetFullPath((new Uri(absolutePath)).LocalPath); 49 | } 50 | } 51 | 52 | #endregion 53 | 54 | #region Public Methods and Operators 55 | 56 | /// 57 | /// Посылает сообщение о закрытии главному окну приложения. 58 | /// 59 | /// 60 | /// true если приложение завершилось и false в противном случае. 61 | /// 62 | public bool Close() 63 | { 64 | this.process.CloseMainWindow(); 65 | return this.process.WaitForExit(CruciatusFactory.Settings.WaitForExitTimeout); 66 | } 67 | 68 | /// 69 | /// Убивает приложение. 70 | /// 71 | /// 72 | /// true если приложение завершилось и false в противном случае. 73 | /// 74 | public bool Kill() 75 | { 76 | this.process.Kill(); 77 | return this.process.WaitForExit(CruciatusFactory.Settings.WaitForExitTimeout); 78 | } 79 | 80 | /// 81 | /// Запускает исполняемый файл. 82 | /// 83 | public void Start() 84 | { 85 | this.Start(string.Empty); 86 | } 87 | 88 | /// 89 | /// Запускает исполняемый файл с аргументами. 90 | /// 91 | /// 92 | /// Строка аргументов запуска приложения. 93 | /// 94 | public void Start(string arguments) 95 | { 96 | if (!File.Exists(this.executableFilePath)) 97 | { 98 | throw new CruciatusException(string.Format(@"Path ""{0}"" doesn't exists", this.executableFilePath)); 99 | } 100 | 101 | var directory = Path.GetDirectoryName(this.executableFilePath); 102 | 103 | // ReSharper disable once AssignNullToNotNullAttribute 104 | // directory не может быть null, в связи с проверкой выше наличия файла executableFilePath 105 | var info = new ProcessStartInfo 106 | { 107 | FileName = this.executableFilePath, 108 | WorkingDirectory = directory, 109 | Arguments = arguments 110 | }; 111 | 112 | this.process = Process.Start(info); 113 | } 114 | 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/By.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Collections.Generic; 6 | using System.Windows.Automation; 7 | 8 | #endregion 9 | 10 | /// 11 | /// Конструктор стратегии поиска элементов. 12 | /// 13 | public abstract class By 14 | { 15 | #region Public Methods and Operators 16 | 17 | /// 18 | /// Поиск по AutomationProperty. 19 | /// Требуется подключить ссылку на UIAutomationClient. 20 | /// 21 | /// 22 | /// Целевое свойство. 23 | /// 24 | /// 25 | /// Значение целевого свойства. 26 | /// 27 | public static ByProperty AutomationProperty(AutomationProperty property, object value) 28 | { 29 | return AutomationProperty(TreeScope.Subtree, property, value); 30 | } 31 | 32 | /// 33 | /// Поиск по AutomationProperty с заданием глубины. 34 | /// Требуется подключить ссылку на UIAutomationClient. 35 | /// 36 | /// 37 | /// Глубина поиска. 38 | /// 39 | /// 40 | /// Целевое свойство. 41 | /// 42 | /// 43 | /// Значение целевого свойства. 44 | /// 45 | public static ByProperty AutomationProperty(TreeScope scope, AutomationProperty property, object value) 46 | { 47 | return new ByProperty(scope, property, value); 48 | } 49 | 50 | /// 51 | /// Поиск по Name. 52 | /// 53 | /// 54 | /// Имя элемента. 55 | /// 56 | public static ByProperty Name(string value) 57 | { 58 | return AutomationProperty(AutomationElement.NameProperty, value); 59 | } 60 | 61 | /// 62 | /// Поиск по Name с заданием глубины. 63 | /// 64 | /// 65 | /// Глубина поиска. 66 | /// 67 | /// 68 | /// Имя элемента. 69 | /// 70 | public static ByProperty Name(TreeScope scope, string value) 71 | { 72 | return AutomationProperty(scope, AutomationElement.NameProperty, value); 73 | } 74 | 75 | /// 76 | /// Поиск по AutomationId. 77 | /// 78 | /// 79 | /// Уникальный идентификатор элемента. 80 | /// 81 | public static ByProperty Uid(string value) 82 | { 83 | return AutomationProperty(AutomationElement.AutomationIdProperty, value); 84 | } 85 | 86 | /// 87 | /// Поиск по AutomationId. 88 | /// 89 | /// 90 | /// Глубина поиска. 91 | /// 92 | /// 93 | /// Уникальный идентификатор элемента. 94 | /// 95 | public static ByProperty Uid(TreeScope scope, string value) 96 | { 97 | return AutomationProperty(scope, AutomationElement.AutomationIdProperty, value); 98 | } 99 | 100 | /// 101 | /// Поиск по XPath. 102 | /// 103 | /// 104 | /// Путь до файла в формате XPath. 105 | /// 106 | public static ByXPath XPath(string value) 107 | { 108 | return new ByXPath(value); 109 | } 110 | 111 | /// 112 | /// Возвращает строковое представление стратегии поиска. 113 | /// 114 | public abstract override string ToString(); 115 | 116 | #endregion 117 | 118 | #region Methods 119 | 120 | internal abstract IEnumerable FindAll(AutomationElement parent, int timeout); 121 | 122 | internal abstract AutomationElement FindFirst(AutomationElement parent, int timeout); 123 | 124 | #endregion 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/ByXPath.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Windows.Automation; 8 | 9 | using Winium.Cruciatus.Helpers; 10 | 11 | #endregion 12 | 13 | /// 14 | /// Класс-конструктор стратегии поиска элементов по XPath. 15 | /// 16 | public class ByXPath : By 17 | { 18 | #region Fields 19 | 20 | private readonly string xpath; 21 | 22 | #endregion 23 | 24 | #region Constructors and Destructors 25 | 26 | internal ByXPath(string xpath) 27 | { 28 | this.xpath = xpath; 29 | } 30 | 31 | #endregion 32 | 33 | #region Public Methods and Operators 34 | 35 | /// 36 | /// Возвращает строковое представление стратегии поиска. 37 | /// 38 | public override string ToString() 39 | { 40 | return this.xpath; 41 | } 42 | 43 | #endregion 44 | 45 | #region Methods 46 | 47 | internal override IEnumerable FindAll(AutomationElement parent, int timeout) 48 | { 49 | return AutomationElementHelper.FindAll(parent, this.xpath, timeout); 50 | } 51 | 52 | internal override AutomationElement FindFirst(AutomationElement parent, int timeout) 53 | { 54 | return AutomationElementHelper.FindAll(parent, this.xpath, timeout).FirstOrDefault(); 55 | } 56 | 57 | #endregion 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/ClickStrategies.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Перечисление поддерживаемых стратегий клика. Имеет атрибут Flags. 11 | /// 12 | [Flags] 13 | public enum ClickStrategies 14 | { 15 | /// 16 | /// Отсутствие определенной стратегии. 17 | /// 18 | None = 0, 19 | 20 | /// 21 | /// Стратегия использования свойства элемента ClickablePoint. 22 | /// 23 | ClickablePoint = 1, 24 | 25 | /// 26 | /// Стратегия использования свойства элемента BoundingRectangle. 27 | /// 28 | BoundingRectangleCenter = 2, 29 | 30 | /// 31 | /// Стратегия использования интерфейса InvokePattern. 32 | /// 33 | InvokePattern = 4 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/CruciatusElementProperties.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Windows; 6 | using System.Windows.Automation; 7 | 8 | #endregion 9 | 10 | /// 11 | /// Класс свойств CruciatusElement. 12 | /// 13 | public class CruciatusElementProperties 14 | { 15 | #region Fields 16 | 17 | private readonly AutomationElement element; 18 | 19 | #endregion 20 | 21 | #region Constructors and Destructors 22 | 23 | internal CruciatusElementProperties(AutomationElement element) 24 | { 25 | this.element = element; 26 | } 27 | 28 | #endregion 29 | 30 | #region Public Properties 31 | 32 | /// 33 | /// Свойство BoundingRectangle. 34 | /// 35 | public Rect BoundingRectangle 36 | { 37 | get 38 | { 39 | return this.element.Current.BoundingRectangle; 40 | } 41 | } 42 | 43 | /// 44 | /// Свойство ClickablePoint. Внимание, значение может отсутствовать. 45 | /// 46 | public Point? ClickablePoint 47 | { 48 | get 49 | { 50 | Point point; 51 | var exists = this.element.TryGetClickablePoint(out point); 52 | return exists ? point : new Point?(); 53 | } 54 | } 55 | 56 | /// 57 | /// Свойство IsEnabled. 58 | /// 59 | public bool IsEnabled 60 | { 61 | get 62 | { 63 | return this.element.Current.IsEnabled; 64 | } 65 | } 66 | 67 | /// 68 | /// Свойство IsOffscreen. 69 | /// 70 | public bool IsOffscreen 71 | { 72 | get 73 | { 74 | return this.element.Current.IsOffscreen; 75 | } 76 | } 77 | 78 | /// 79 | /// Свойство Name. 80 | /// 81 | public string Name 82 | { 83 | get 84 | { 85 | return this.element.Current.Name; 86 | } 87 | } 88 | 89 | /// 90 | /// Строковое представление RuntimeId элемента. 91 | /// 92 | public string RuntimeId 93 | { 94 | get 95 | { 96 | return string.Join(" ", this.element.GetRuntimeId()); 97 | } 98 | } 99 | 100 | #endregion 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/DisplayOrientation.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | /// 4 | /// Represents the orientation of the screen 5 | /// 6 | public enum DisplayOrientation 7 | { 8 | LANDSCAPE = 0, 9 | LANDSCAPE_FLIPPED = 2, 10 | PORTRAIT = 1, 11 | PORTRAIT_FLIPPED = 3 12 | } 13 | } -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/ExpandStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | /// 4 | /// Перечисление поддерживаемых стратегий раскрытия выпадающего элемента. 5 | /// 6 | public enum ExpandStrategy 7 | { 8 | /// 9 | /// Стратегия раскрытия через клик по элементу. 10 | /// 11 | Click = 0, 12 | 13 | /// 14 | /// Стратегия использования интерфейса ExpandCollapsePattern. 15 | /// 16 | ExpandCollapsePattern = 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/GetTextStrategy.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2gis/Winium.Cruciatus/09ff49c971a6bdb4c18ddfecdd88508439519187/src/Winium.Cruciatus/Core/GetTextStrategy.cs -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/IKeyboard.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using WindowsInput.Native; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Интерфейс симулятора клавиатуры. 11 | /// 12 | public interface IKeyboard 13 | { 14 | #region Public Methods and Operators 15 | 16 | /// 17 | /// Эмулирует действие 'нажать и держать' над кнопкой. 18 | /// 19 | /// 20 | /// Ключ целевой кнопки. 21 | /// 22 | IKeyboard KeyDown(VirtualKeyCode keyCode); 23 | 24 | /// 25 | /// Эмулирует действие 'отпустить' над кнопкой. 26 | /// 27 | /// 28 | /// Ключ целевой кнопки. 29 | /// 30 | IKeyboard KeyUp(VirtualKeyCode keyCode); 31 | 32 | /// 33 | /// Эмулирует нажатие кнопки Backspace. 34 | /// 35 | IKeyboard SendBackspace(); 36 | 37 | /// 38 | /// Эмулирует нажатие сочетания кнопок Ctrl + A. 39 | /// 40 | IKeyboard SendCtrlA(); 41 | 42 | /// 43 | /// Эмулирует нажатие сочетания кнопок Ctrl + C. 44 | /// 45 | IKeyboard SendCtrlC(); 46 | 47 | /// 48 | /// Эмулирует нажатие сочетания кнопок Ctrl + V. 49 | /// 50 | IKeyboard SendCtrlV(); 51 | 52 | /// 53 | /// Эмулирует нажатие кнопки Enter. 54 | /// 55 | IKeyboard SendEnter(); 56 | 57 | /// 58 | /// Эмулирует нажатие кнопки Escape. 59 | /// 60 | IKeyboard SendEscape(); 61 | 62 | /// 63 | /// Эмулирует ввод текста. 64 | /// 65 | /// 66 | /// Текст. 67 | /// 68 | IKeyboard SendText(string text); 69 | 70 | #endregion 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/IScreenshoter.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Интерфейс снимателя скриншотов. 11 | /// 12 | public interface IScreenshoter 13 | { 14 | #region Public Methods and Operators 15 | 16 | /// 17 | /// Возвращает скриншот рабочего стола. 18 | /// 19 | [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Reviewed.")] 20 | Screenshot GetScreenshot(); 21 | 22 | #endregion 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/MouseButtons.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Перечисление поддерживаемых кнопок мыши. 11 | /// 12 | [SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags", Justification = "Reviewed.")] 13 | public enum MouseButton 14 | { 15 | /// 16 | /// Левая кнопка мыши. 17 | /// 18 | Left = 0, 19 | 20 | /// 21 | /// Правая кнопка мыши. 22 | /// 23 | Right = 2 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/Screenshot.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.IO; 7 | 8 | #endregion 9 | 10 | /// 11 | /// Класс описывающий скриншот. 12 | /// 13 | public class Screenshot 14 | { 15 | #region Fields 16 | 17 | private readonly string base64String = string.Empty; 18 | 19 | private readonly byte[] byteArray; 20 | 21 | #endregion 22 | 23 | #region Constructors and Destructors 24 | 25 | internal Screenshot(byte[] array) 26 | { 27 | if (array == null || array.Length == 0) 28 | { 29 | throw new ArgumentException("Cannot be null or empty", "array"); 30 | } 31 | 32 | this.byteArray = array; 33 | this.base64String = Convert.ToBase64String(this.byteArray); 34 | } 35 | 36 | #endregion 37 | 38 | #region Public Methods and Operators 39 | 40 | /// 41 | /// Возвращает скриншот в виде base64 строки. 42 | /// 43 | public string AsBase64String() 44 | { 45 | return this.base64String; 46 | } 47 | 48 | /// 49 | /// Возвращает скриншот в виде массива байт. 50 | /// 51 | public byte[] AsByteArray() 52 | { 53 | return this.byteArray; 54 | } 55 | 56 | /// 57 | /// Сохраняет скриншот в заданный файл. 58 | /// 59 | /// 60 | /// Путь до файла. 61 | /// 62 | public void SaveAsFile(string filePath) 63 | { 64 | if (string.IsNullOrEmpty(filePath)) 65 | { 66 | throw new ArgumentException("Cannot be null or empty", "filePath"); 67 | } 68 | 69 | var dir = Path.GetDirectoryName(filePath); 70 | if (!string.IsNullOrEmpty(dir)) 71 | { 72 | Directory.CreateDirectory(dir); 73 | } 74 | 75 | using (var stream = File.OpenWrite(filePath)) 76 | { 77 | stream.Write(this.byteArray, 0, this.byteArray.Length); 78 | } 79 | } 80 | 81 | /// 82 | /// Возвращает скриншот в виде base64 строки. 83 | /// 84 | public override string ToString() 85 | { 86 | return this.base64String; 87 | } 88 | 89 | #endregion 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/Screenshoter.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System.Drawing; 6 | using System.Drawing.Imaging; 7 | using System.IO; 8 | using System.Windows; 9 | 10 | using Point = System.Drawing.Point; 11 | 12 | #endregion 13 | 14 | /// 15 | /// Класс для создания скриншотов рабочего стола. 16 | /// 17 | public class Screenshoter : IScreenshoter 18 | { 19 | #region Public Methods and Operators 20 | 21 | /// 22 | /// Возвращает скриншот рабочего стола. 23 | /// 24 | public Screenshot GetScreenshot() 25 | { 26 | byte[] imageBytes; 27 | var rect = new Rectangle( 28 | (int)SystemParameters.VirtualScreenLeft, 29 | (int)SystemParameters.VirtualScreenTop, 30 | (int)SystemParameters.VirtualScreenWidth, 31 | (int)SystemParameters.VirtualScreenHeight); 32 | using (var bitmap = new Bitmap(rect.Width, rect.Height)) 33 | { 34 | using (var graphics = Graphics.FromImage(bitmap)) 35 | { 36 | graphics.CopyFromScreen(new Point(rect.Left, rect.Top), Point.Empty, rect.Size); 37 | } 38 | 39 | using (var stream = new MemoryStream()) 40 | { 41 | bitmap.Save(stream, ImageFormat.Png); 42 | imageBytes = stream.ToArray(); 43 | } 44 | } 45 | 46 | return new Screenshot(imageBytes); 47 | } 48 | 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Core/SendKeysExt.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Core 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Threading; 7 | using System.Windows.Forms; 8 | 9 | using NLog; 10 | 11 | using WindowsInput.Native; 12 | 13 | #endregion 14 | 15 | /// 16 | /// Симулятор клавиатуры. Обёртка над System.Windows.Forms.SendKeys . 17 | /// 18 | public class SendKeysExt : IKeyboard 19 | { 20 | #region Constants 21 | 22 | /// 23 | /// Кнопка Alt. 24 | /// 25 | public const char Alt = '%'; 26 | 27 | /// 28 | /// Кнопка Backspace. 29 | /// 30 | public const string Backspace = "{BACKSPACE}"; 31 | 32 | /// 33 | /// Кнопка Ctrl. 34 | /// 35 | public const char Ctrl = '^'; 36 | 37 | /// 38 | /// Кнопка Enter. 39 | /// 40 | public const string Enter = "{ENTER}"; 41 | 42 | /// 43 | /// Кнопка Escape. 44 | /// 45 | public const string Escape = "{ESCAPE}"; 46 | 47 | /// 48 | /// Кнопка + 49 | /// 50 | public const char Shift = '+'; 51 | 52 | #endregion 53 | 54 | #region Fields 55 | 56 | private readonly Logger logger; 57 | 58 | #endregion 59 | 60 | #region Constructors and Destructors 61 | 62 | internal SendKeysExt(Logger logger) 63 | { 64 | this.logger = logger; 65 | } 66 | 67 | #endregion 68 | 69 | #region Public Methods and Operators 70 | 71 | /// 72 | /// Эмулирует действие 'нажать и держать' над кнопкой. 73 | /// 74 | /// 75 | /// Ключ целевой кнопки. 76 | /// 77 | public IKeyboard KeyDown(VirtualKeyCode keyCode) 78 | { 79 | throw new NotImplementedException(); 80 | } 81 | 82 | /// 83 | /// Эмулирует действие 'отпустить' над кнопкой. 84 | /// 85 | /// 86 | /// Ключ целевой кнопки. 87 | /// 88 | public IKeyboard KeyUp(VirtualKeyCode keyCode) 89 | { 90 | throw new NotImplementedException(); 91 | } 92 | 93 | /// 94 | /// Эмулирует нажатие кнопки Backspace. 95 | /// 96 | public IKeyboard SendBackspace() 97 | { 98 | return this.SendKeysPrivate(Backspace); 99 | } 100 | 101 | /// 102 | /// Эмулирует нажатие сочетания кнопок Ctrl + A. 103 | /// 104 | public IKeyboard SendCtrlA() 105 | { 106 | return this.SendKeysPrivate(Ctrl + "a"); 107 | } 108 | 109 | /// 110 | /// Эмулирует нажатие сочетания кнопок Ctrl + C. 111 | /// 112 | public IKeyboard SendCtrlC() 113 | { 114 | return this.SendKeysPrivate(Ctrl + "c"); 115 | } 116 | 117 | /// 118 | /// Эмулирует нажатие сочетания кнопок Ctrl + V. 119 | /// 120 | public IKeyboard SendCtrlV() 121 | { 122 | return this.SendKeysPrivate(Ctrl + "v"); 123 | } 124 | 125 | /// 126 | /// Эмулирует нажатие кнопки Enter. 127 | /// 128 | public IKeyboard SendEnter() 129 | { 130 | return this.SendKeysPrivate(Enter); 131 | } 132 | 133 | /// 134 | /// Эмулирует нажатие кнопки Escape. 135 | /// 136 | public IKeyboard SendEscape() 137 | { 138 | return this.SendKeysPrivate(Escape); 139 | } 140 | 141 | /// 142 | /// Эмулирует ввод текста. 143 | /// 144 | /// 145 | /// Текст. 146 | /// 147 | public IKeyboard SendText(string text) 148 | { 149 | this.logger.Info("Send text '{0}'", text); 150 | return this.SendWaitPrivate(text); 151 | } 152 | 153 | #endregion 154 | 155 | #region Methods 156 | 157 | private IKeyboard SendKeysPrivate(string keys) 158 | { 159 | this.logger.Info("Send keys '{0}'", keys); 160 | return this.SendWaitPrivate(keys); 161 | } 162 | 163 | private IKeyboard SendWaitPrivate(string text) 164 | { 165 | if (!string.IsNullOrEmpty(text)) 166 | { 167 | SendKeys.SendWait(text); 168 | Thread.Sleep(250); 169 | } 170 | 171 | return this; 172 | } 173 | 174 | #endregion 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/CheckBox.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Extensions; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Представляет элемент управления чекбокс. 14 | /// 15 | public class CheckBox : CruciatusElement 16 | { 17 | #region Constructors and Destructors 18 | 19 | /// 20 | /// Создает экземпляр чекбокса. 21 | /// 22 | /// 23 | /// Исходный элемент. 24 | /// 25 | public CheckBox(CruciatusElement element) 26 | : base(element) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр чекбокса. Поиск осуществится только при необходимости. 32 | /// 33 | /// 34 | /// Родительский элемент. 35 | /// 36 | /// 37 | /// Стратегия поиска элемента. 38 | /// 39 | public CheckBox(CruciatusElement parent, By getStrategy) 40 | : base(parent, getStrategy) 41 | { 42 | } 43 | 44 | #endregion 45 | 46 | #region Public Properties 47 | 48 | /// 49 | /// Возвращает значение, указывающее, чекнут ли чекбокс. 50 | /// 51 | public bool IsToggleOn 52 | { 53 | get 54 | { 55 | return this.ToggleState == ToggleState.On; 56 | } 57 | } 58 | 59 | #endregion 60 | 61 | #region Properties 62 | 63 | internal ToggleState ToggleState 64 | { 65 | get 66 | { 67 | return this.GetAutomationPropertyValue(TogglePattern.ToggleStateProperty); 68 | } 69 | } 70 | 71 | #endregion 72 | 73 | #region Public Methods and Operators 74 | 75 | /// 76 | /// Устанавливает чекбокс в состояние чекнут. 77 | /// 78 | public void Check() 79 | { 80 | if (this.IsToggleOn) 81 | { 82 | return; 83 | } 84 | 85 | this.Click(); 86 | } 87 | 88 | /// 89 | /// Устанавливает чекбокс в состояние не чекнут. 90 | /// 91 | public void Uncheck() 92 | { 93 | if (!this.IsToggleOn) 94 | { 95 | return; 96 | } 97 | 98 | this.Click(); 99 | } 100 | 101 | #endregion 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/ListBox.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Extensions; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Элемент список. 14 | /// 15 | public class ListBox : CruciatusElement 16 | { 17 | #region Constructors and Destructors 18 | 19 | /// 20 | /// Создает экземпляр списка. 21 | /// 22 | /// 23 | /// Исходный элемент. 24 | /// 25 | public ListBox(CruciatusElement element) 26 | : base(element) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр списка. Поиск осуществится только при необходимости. 32 | /// 33 | /// 34 | /// Родительский элемент. 35 | /// 36 | /// 37 | /// Стратегия поиска элемента. 38 | /// 39 | public ListBox(CruciatusElement parent, By getStrategy) 40 | : base(parent, getStrategy) 41 | { 42 | } 43 | 44 | #endregion 45 | 46 | #region Public Methods and Operators 47 | 48 | /// 49 | /// Прокручивает список до элемента, удовлетворяющего стратегии поиска. 50 | /// Возвращает целевой элемент, либо null, если он не найден. 51 | /// 52 | /// 53 | /// Стратегия поиска целевого элемента. 54 | /// 55 | public CruciatusElement ScrollTo(By getStrategy) 56 | { 57 | if (!this.Instance.Current.IsEnabled) 58 | { 59 | Logger.Error("Element '{0}' not enabled. Scroll failed.", this.ToString()); 60 | CruciatusFactory.Screenshoter.AutomaticScreenshotCaptureIfNeeded(); 61 | throw new ElementNotEnabledException("NOT SCROLL"); 62 | } 63 | 64 | var scrollPattern = this.Instance.GetCurrentPattern(ScrollPattern.Pattern) as ScrollPattern; 65 | if (scrollPattern == null) 66 | { 67 | Logger.Debug("{0} does not support ScrollPattern.", this); 68 | throw new ElementNotEnabledException("NOT SCROLL"); 69 | } 70 | 71 | // Стартовый поиск элемента 72 | var element = CruciatusCommand.FindFirst(this, getStrategy, 1000); 73 | 74 | // Вертикальная прокрутка (при необходимости и возможности) 75 | if (element == null && scrollPattern.Current.VerticallyScrollable) 76 | { 77 | // Установка самого верхнего положения прокрутки 78 | while (scrollPattern.Current.VerticalScrollPercent > 0.1) 79 | { 80 | scrollPattern.ScrollVertical(ScrollAmount.LargeDecrement); 81 | } 82 | 83 | // Установка самого левого положения прокрутки (при возможности) 84 | if (scrollPattern.Current.HorizontallyScrollable) 85 | { 86 | while (scrollPattern.Current.HorizontalScrollPercent > 0.1) 87 | { 88 | scrollPattern.ScrollHorizontal(ScrollAmount.LargeDecrement); 89 | } 90 | } 91 | 92 | // Основная вертикальная прокрутка 93 | while (element == null && scrollPattern.Current.VerticalScrollPercent < 99.9) 94 | { 95 | scrollPattern.ScrollVertical(ScrollAmount.LargeIncrement); 96 | element = CruciatusCommand.FindFirst(this, getStrategy, 1000); 97 | } 98 | } 99 | 100 | if (element == null) 101 | { 102 | Logger.Debug("No elements matching {1} were found in {0}.", this, getStrategy); 103 | return null; 104 | } 105 | 106 | // Если точка клика элемента под границей списка - докручиваем по вертикали вниз 107 | while (element.Instance.ClickablePointUnder(this.Instance, scrollPattern)) 108 | { 109 | scrollPattern.ScrollVertical(ScrollAmount.SmallIncrement); 110 | } 111 | 112 | // Если точка клика элемента над границей списка - докручиваем по вертикали вверх 113 | while (element.Instance.ClickablePointOver(this.Instance)) 114 | { 115 | scrollPattern.ScrollVertical(ScrollAmount.SmallDecrement); 116 | } 117 | 118 | // Если точка клика элемента справа от границы списка - докручиваем по горизонтали вправо 119 | while (element.Instance.ClickablePointRight(this.Instance, scrollPattern)) 120 | { 121 | scrollPattern.ScrollHorizontal(ScrollAmount.SmallIncrement); 122 | } 123 | 124 | // Если точка клика элемента слева от границы списка - докручиваем по горизонтали влево 125 | while (element.Instance.ClickablePointLeft(this.Instance)) 126 | { 127 | scrollPattern.ScrollHorizontal(ScrollAmount.SmallDecrement); 128 | } 129 | 130 | return element; 131 | } 132 | 133 | #endregion 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/Menu.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Linq; 7 | 8 | using Winium.Cruciatus.Core; 9 | using Winium.Cruciatus.Exceptions; 10 | using Winium.Cruciatus.Extensions; 11 | 12 | #endregion 13 | 14 | /// 15 | /// Элемент меню. 16 | /// 17 | public class Menu : CruciatusElement 18 | { 19 | #region Constructors and Destructors 20 | 21 | /// 22 | /// Создает экземпляр меню. 23 | /// 24 | /// 25 | /// Исходный элемент. 26 | /// 27 | public Menu(CruciatusElement element) 28 | : base(element) 29 | { 30 | } 31 | 32 | /// 33 | /// Создает экземпляр меню. Поиск осуществится только при необходимости. 34 | /// 35 | /// 36 | /// Родительский элемент. 37 | /// 38 | /// 39 | /// Стратегия поиска элемента. 40 | /// 41 | public Menu(CruciatusElement parent, By getStrategy) 42 | : base(parent, getStrategy) 43 | { 44 | } 45 | 46 | #endregion 47 | 48 | #region Public Methods and Operators 49 | 50 | /// 51 | /// Возвращает элемент меню, указанный последним в пути. 52 | /// 53 | /// 54 | /// Путь из заголовков для прохода (пример: control$view$zoom). 55 | /// 56 | public CruciatusElement GetItem(string headersPath) 57 | { 58 | if (string.IsNullOrEmpty(headersPath)) 59 | { 60 | throw new ArgumentNullException("headersPath"); 61 | } 62 | 63 | var item = (CruciatusElement)this; 64 | var headers = headersPath.Split('$'); 65 | for (var i = 0; i < headers.Length - 1; ++i) 66 | { 67 | var name = headers[i]; 68 | item = item.FindElement(By.Name(name)); 69 | if (item == null) 70 | { 71 | Logger.Error("Item '{0}' not found. Find item failed.", name); 72 | throw new CruciatusException("NOT GET ITEM"); 73 | } 74 | 75 | item.Click(); 76 | } 77 | 78 | return item.FindElement(By.Name(headers.Last())); 79 | } 80 | 81 | /// 82 | /// Выбирает элемент меню, указанный последним в пути. 83 | /// 84 | /// 85 | /// Путь из заголовков для прохода (пример: control$view$zoom). 86 | /// 87 | public virtual void SelectItem(string headersPath) 88 | { 89 | if (!this.Instance.Current.IsEnabled) 90 | { 91 | Logger.Error("Element '{0}' not enabled. Select item failed.", this.ToString()); 92 | CruciatusFactory.Screenshoter.AutomaticScreenshotCaptureIfNeeded(); 93 | throw new CruciatusException("NOT SELECT ITEM"); 94 | } 95 | 96 | var item = this.GetItem(headersPath); 97 | if (item == null) 98 | { 99 | Logger.Error("Item '{0}' not found. Select item failed.", headersPath); 100 | throw new CruciatusException("NOT SELECT ITEM"); 101 | } 102 | 103 | item.Click(); 104 | } 105 | 106 | #endregion 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/OpenFileDialog.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Extensions; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Класс для работы с диалоговым окном Microsoft.Win32.OpenFileDialog. 14 | /// 15 | public class OpenFileDialog : CruciatusElement 16 | { 17 | #region Constructors and Destructors 18 | 19 | /// 20 | /// Конструктор класса по объекту диалогового окна. 21 | /// 22 | /// 23 | /// Исходный элемент. 24 | /// 25 | public OpenFileDialog(CruciatusElement element) 26 | : base(element) 27 | { 28 | } 29 | 30 | /// 31 | /// Конструторк класса. Поиск осуществится только при необходимости. 32 | /// 33 | /// 34 | /// Родительский элемент. 35 | /// 36 | /// 37 | /// Стретегия поиска. 38 | /// 39 | public OpenFileDialog(CruciatusElement parent, By getStrategy) 40 | : base(parent, getStrategy) 41 | { 42 | } 43 | 44 | #endregion 45 | 46 | #region Public Properties 47 | 48 | /// 49 | /// Возвращает кнопку Отмена. 50 | /// 51 | public CruciatusElement CancelButton 52 | { 53 | get 54 | { 55 | var uid = CruciatusFactory.Settings.OpenFileDialogUid.CancelButton; 56 | return this.FindElement(By.Uid(TreeScope.Children, uid)); 57 | } 58 | } 59 | 60 | /// 61 | /// Возвращает выпадающий список с именем открываемого файла. 62 | /// 63 | public ComboBox FileNameComboBox 64 | { 65 | get 66 | { 67 | var uid = CruciatusFactory.Settings.OpenFileDialogUid.FileNameEditableComboBox; 68 | return this.FindElement(By.Uid(TreeScope.Children, uid)).ToComboBox(); 69 | } 70 | } 71 | 72 | /// 73 | /// Возвращает кнопку Открыть. 74 | /// 75 | public CruciatusElement OpenButton 76 | { 77 | get 78 | { 79 | var uid = CruciatusFactory.Settings.OpenFileDialogUid.OpenButton; 80 | return this.FindElement(By.Uid(TreeScope.Children, uid)); 81 | } 82 | } 83 | 84 | #endregion 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/SaveFileDialog.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Extensions; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Класс для работы с диалоговым окном Microsoft.Win32.SaveFileDialog. 14 | /// 15 | public class SaveFileDialog : CruciatusElement 16 | { 17 | #region Constructors and Destructors 18 | 19 | /// 20 | /// Создает экземпляр диалогового окна. 21 | /// 22 | /// 23 | /// Исходный элемент. 24 | /// 25 | public SaveFileDialog(CruciatusElement element) 26 | : base(element) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр диалогового окна. Поиск осуществится только при необходимости. 32 | /// 33 | /// 34 | /// Родительский элемент. 35 | /// 36 | /// 37 | /// Стратегия поиска элемента. 38 | /// 39 | public SaveFileDialog(CruciatusElement parent, By getStrategy) 40 | : base(parent, getStrategy) 41 | { 42 | } 43 | 44 | #endregion 45 | 46 | #region Public Properties 47 | 48 | /// 49 | /// Возвращает кнопку Отмена. 50 | /// 51 | public CruciatusElement CancelButton 52 | { 53 | get 54 | { 55 | var uid = CruciatusFactory.Settings.SaveFileDialogUid.CancelButton; 56 | return this.FindElement(By.Uid(TreeScope.Children, uid)); 57 | } 58 | } 59 | 60 | /// 61 | /// Возвращает выпадающий список с именем открываемого файла. 62 | /// 63 | public ComboBox FileNameComboBox 64 | { 65 | get 66 | { 67 | var uid = CruciatusFactory.Settings.SaveFileDialogUid.FileNameEditableComboBox; 68 | return this.FindElement(By.Uid(TreeScope.Subtree, uid)).ToComboBox(); 69 | } 70 | } 71 | 72 | /// 73 | /// Возвращает выпадающий список с типом открываемого файла. 74 | /// 75 | public ComboBox FileTypeComboBox 76 | { 77 | get 78 | { 79 | var uid = CruciatusFactory.Settings.SaveFileDialogUid.FileTypeComboBox; 80 | return this.FindElement(By.Uid(TreeScope.Subtree, uid)).ToComboBox(); 81 | } 82 | } 83 | 84 | /// 85 | /// Возвращает кнопку Сохранить. 86 | /// 87 | public CruciatusElement SaveButton 88 | { 89 | get 90 | { 91 | var uid = CruciatusFactory.Settings.SaveFileDialogUid.SaveButton; 92 | return this.FindElement(By.Uid(TreeScope.Children, uid)); 93 | } 94 | } 95 | 96 | #endregion 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Elements/TabItem.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Elements 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | 7 | using Winium.Cruciatus.Core; 8 | using Winium.Cruciatus.Extensions; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Элемент вкладка. Требуется поддержка интерфейса SelectionItemPattern. 14 | /// 15 | public class TabItem : CruciatusElement 16 | { 17 | #region Constructors and Destructors 18 | 19 | /// 20 | /// Создает экземпляр вкладки. Поиск осуществится только при необходимости. 21 | /// 22 | /// 23 | /// Родительский элемент. 24 | /// 25 | /// 26 | /// Стратегия поиска элемента. 27 | /// 28 | public TabItem(CruciatusElement parent, By getStrategy) 29 | : base(parent, getStrategy) 30 | { 31 | } 32 | 33 | #endregion 34 | 35 | #region Public Properties 36 | 37 | /// 38 | /// Возвращает значение, указывающее, выбрана ли вкладка. 39 | /// 40 | public bool IsSelection 41 | { 42 | get 43 | { 44 | return this.GetAutomationPropertyValue(SelectionItemPattern.IsSelectedProperty); 45 | } 46 | } 47 | 48 | #endregion 49 | 50 | #region Public Methods and Operators 51 | 52 | /// 53 | /// Выбирает вкладку текущей. 54 | /// 55 | public void Select() 56 | { 57 | if (this.IsSelection) 58 | { 59 | return; 60 | } 61 | 62 | this.Click(); 63 | } 64 | 65 | #endregion 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Exceptions/CruciatusException.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Exceptions 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Runtime.Serialization; 7 | 8 | #endregion 9 | 10 | /// 11 | /// Исключение фреймворка Cruciatus. 12 | /// 13 | [Serializable] 14 | public class CruciatusException : Exception 15 | { 16 | #region Constructors and Destructors 17 | 18 | /// 19 | /// Конструктор по умолчанию. 20 | /// 21 | public CruciatusException() 22 | { 23 | } 24 | 25 | /// 26 | /// Параметризованный конструктор. 27 | /// 28 | public CruciatusException(string message) 29 | : base(message) 30 | { 31 | } 32 | 33 | /// 34 | /// Параметризованный конструктор. 35 | /// 36 | public CruciatusException(string message, Exception innerException) 37 | : base(message, innerException) 38 | { 39 | } 40 | 41 | /// 42 | /// Параметризованный конструктор. 43 | /// 44 | protected CruciatusException(SerializationInfo info, StreamingContext context) 45 | : base(info, context) 46 | { 47 | } 48 | 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Exceptions/NoSuchElementException.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Exceptions 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Runtime.Serialization; 7 | 8 | #endregion 9 | 10 | /// 11 | /// Элемент не может быть найден. 12 | /// 13 | [Serializable] 14 | public class NoSuchElementException : CruciatusException 15 | { 16 | #region Constructors and Destructors 17 | 18 | /// 19 | /// Конструктор по умолчанию. 20 | /// 21 | public NoSuchElementException() 22 | { 23 | } 24 | 25 | /// 26 | /// Параметризованный конструктор. 27 | /// 28 | public NoSuchElementException(string message) 29 | : base(message) 30 | { 31 | } 32 | 33 | /// 34 | /// Параметризованный конструктор. 35 | /// 36 | public NoSuchElementException(string message, Exception innerException) 37 | : base(message, innerException) 38 | { 39 | } 40 | 41 | /// 42 | /// Параметризованный конструктор. 43 | /// 44 | protected NoSuchElementException(SerializationInfo info, StreamingContext context) 45 | : base(info, context) 46 | { 47 | } 48 | 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Extensions/CruciatusElementExtension.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Extensions 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Windows.Automation; 9 | 10 | using WindowsInput.Native; 11 | 12 | using Winium.Cruciatus.Elements; 13 | using Winium.Cruciatus.Exceptions; 14 | 15 | #endregion 16 | 17 | /// 18 | /// Набор расширений для объектов CruciatusElement. 19 | /// 20 | public static class CruciatusElementExtension 21 | { 22 | #region Public Methods and Operators 23 | 24 | /// 25 | /// Кликнуть по элементу с зажатой кнопкой Control 26 | /// 27 | public static void ClickWithPressedCtrl(this CruciatusElement element) 28 | { 29 | ClickWithPressedKeys(element, new List { VirtualKeyCode.CONTROL }); 30 | } 31 | 32 | /// 33 | /// Клик по элементу с нажатыми кнопками (Ctrl, Shift, etc) 34 | /// 35 | /// 36 | /// Экземпляр элемента. 37 | /// 38 | /// 39 | /// Клавиши для "зажатия" 40 | /// 41 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", 42 | Justification = "First parameter in extension cannot be null.")] 43 | public static void ClickWithPressedKeys(this CruciatusElement element, List keys) 44 | { 45 | keys.ForEach(key => CruciatusFactory.Keyboard.KeyDown(key)); 46 | element.Click(); 47 | keys.ForEach(key => CruciatusFactory.Keyboard.KeyUp(key)); 48 | } 49 | 50 | /// 51 | /// Получает у элемента значение заданного свойства. 52 | /// 53 | /// 54 | /// Экземпляр элемента. 55 | /// 56 | /// 57 | /// Целевое свойство. 58 | /// 59 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", 60 | Justification = "First parameter in extension cannot be null.")] 61 | public static TOut GetAutomationPropertyValue( 62 | this CruciatusElement cruciatusElement, 63 | AutomationProperty property) 64 | { 65 | try 66 | { 67 | return cruciatusElement.Instance.GetPropertyValue(property); 68 | } 69 | catch (NotSupportedException) 70 | { 71 | var msg = string.Format("Element '{0}' not support '{1}'", cruciatusElement, property.ProgrammaticName); 72 | CruciatusFactory.Logger.Error(msg); 73 | 74 | throw new CruciatusException("GET PROPERTY VALUE FAILED"); 75 | } 76 | catch (InvalidCastException invalidCastException) 77 | { 78 | var msg = string.Format("Invalid cast from '{0}' to '{1}'.", invalidCastException.Message, typeof(TOut)); 79 | CruciatusFactory.Logger.Error(msg); 80 | 81 | throw new CruciatusException("GET PROPERTY VALUE FAILED"); 82 | } 83 | } 84 | 85 | /// 86 | /// Возвращает требуемый шаблон автоматизации. 87 | /// 88 | /// 89 | /// Экземпляр элемента. 90 | /// 91 | /// 92 | /// Требуемый шаблон (например ExpandCollapsePattern.Pattern). 93 | /// 94 | /// 95 | /// Тип требуемого шаблона. 96 | /// 97 | /// 98 | public static T GetPattern(this CruciatusElement element, AutomationPattern pattern) where T : class 99 | { 100 | return element.Instance.GetPattern(pattern); 101 | } 102 | 103 | /// 104 | /// Преобразовать элемент в CheckBox. 105 | /// 106 | public static CheckBox ToCheckBox(this CruciatusElement element) 107 | { 108 | return new CheckBox(element); 109 | } 110 | 111 | /// 112 | /// Преобразовать элемент в ComboBox. 113 | /// 114 | public static ComboBox ToComboBox(this CruciatusElement element) 115 | { 116 | return new ComboBox(element); 117 | } 118 | 119 | /// 120 | /// Преобразовать элемент в DataGrid. 121 | /// 122 | public static DataGrid ToDataGrid(this CruciatusElement element) 123 | { 124 | return new DataGrid(element); 125 | } 126 | 127 | /// 128 | /// Преобразовать элемент в ListBox. 129 | /// 130 | public static ListBox ToListBox(this CruciatusElement element) 131 | { 132 | return new ListBox(element); 133 | } 134 | 135 | /// 136 | /// Преобразовать элемент в Menu. 137 | /// 138 | public static Menu ToMenu(this CruciatusElement element) 139 | { 140 | return new Menu(element); 141 | } 142 | 143 | #endregion 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Extensions/IScreenshoterExtension.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Extensions 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Diagnostics.CodeAnalysis; 7 | using System.IO; 8 | 9 | using Winium.Cruciatus.Core; 10 | 11 | #endregion 12 | 13 | /// 14 | /// Набор расширений для объектов, реализующих интерфейс IScreenshoter. 15 | /// 16 | // ReSharper disable once InconsistentNaming 17 | public static class IScreenshoterExtension 18 | { 19 | #region Public Methods and Operators 20 | 21 | /// 22 | /// Снимает и сохраняет скриншот в случае когда флаг 23 | /// CruciatusFactory.Settings.AutomaticScreenshotCapture равен true. 24 | /// 25 | public static void AutomaticScreenshotCaptureIfNeeded(this IScreenshoter screenshoter) 26 | { 27 | if (CruciatusFactory.Settings.AutomaticScreenshotCapture) 28 | { 29 | screenshoter.TakeScreenshot(); 30 | } 31 | } 32 | 33 | /// 34 | /// Снимает и сохраняет скриншот. 35 | /// 36 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", 37 | Justification = "Main argument in extension method cannot be null")] 38 | public static void TakeScreenshot(this IScreenshoter screenshoter) 39 | { 40 | var timeStamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff"); 41 | var screenshotPath = Path.Combine(CruciatusFactory.Settings.ScreenshotsPath, timeStamp + ".png"); 42 | screenshoter.GetScreenshot().SaveAsFile(screenshotPath); 43 | CruciatusFactory.Logger.Info("Saved screenshot to '{0}' file.", Path.GetFullPath(screenshotPath)); 44 | } 45 | 46 | #endregion 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/FullReleaseNotes.txt: -------------------------------------------------------------------------------- 1 | Version 2.7.0 2 | * Default search timeout is 10 seconds 3 | Version 2.6.1 4 | * More simple creation DataGrid 5 | Version 2.6.0 6 | + Add extension (to CruciatusElement) for getting UI automation patterns 7 | Version 2.5.0 8 | + Add KeyUp and KeyDown methods for CruciatusFactory.Keyboard (only works with InputSimulator keyboard type) 9 | + Add CruciatusElement extension for click with any pressed keys 10 | Version 2.4.0 11 | + Support relative path for tested app 12 | + Support arguments for start tested app 13 | + Add path of unfound tested app file to exception text 14 | + All error have english language 15 | Version 2.3.0 16 | + Add FocusedElement property to CruciatusFactory 17 | + Implement IEquatable<CruciatusElement>.Equals method 18 | + Override Object.Equals and Object.GetHashCode implementations 19 | Version 2.2.1 20 | * Inner minor changes in Core.MouseButtons enum 21 | Version 2.2.0 22 | + Add RuntimeId property to CruciatusElement.Properties 23 | Version 2.1.1 24 | + Add BoundingRectangle property to CruciatusElement.Properties 25 | + Add CurrentCursorPos property in mouse simulator 26 | + Add MoveCursorPos method -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/AutomationElementHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Windows; 9 | using System.Windows.Automation; 10 | using System.Xml.XPath; 11 | 12 | using Winium.Cruciatus.Helpers.XPath; 13 | 14 | using Condition = System.Windows.Automation.Condition; 15 | 16 | #endregion 17 | 18 | internal static class AutomationElementHelper 19 | { 20 | #region Methods 21 | 22 | internal static IEnumerable FindAll( 23 | AutomationElement parent, 24 | TreeScope scope, 25 | Condition condition, 26 | int timeout) 27 | { 28 | var dtn = DateTime.Now.AddMilliseconds(timeout); 29 | 30 | // ReSharper disable once LoopVariableIsNeverChangedInsideLoop 31 | while (DateTime.Now <= dtn) 32 | { 33 | var elements = parent.FindAll(scope, condition); 34 | if (elements.Count > 0) 35 | { 36 | return elements.Cast(); 37 | } 38 | } 39 | 40 | return Enumerable.Empty(); 41 | } 42 | 43 | internal static IEnumerable FindAll(AutomationElement parent, string xpath, int timeout) 44 | { 45 | var navigator = new DesktopTreeXPathNavigator(parent); 46 | var dtn = DateTime.Now.AddMilliseconds(timeout); 47 | 48 | // ReSharper disable once LoopVariableIsNeverChangedInsideLoop 49 | while (DateTime.Now <= dtn) 50 | { 51 | var obj = navigator.Evaluate(xpath); 52 | var nodeIterator = obj as XPathNodeIterator; 53 | if (nodeIterator == null) 54 | { 55 | CruciatusFactory.Logger.Warn("XPath expression '{0}' not searching nodes", xpath); 56 | break; 57 | } 58 | 59 | var nodes = nodeIterator.Cast(); 60 | var elementNodes = nodes.Where(item => item.NodeType == XPathNodeType.Element).ToList(); 61 | if (elementNodes.Any()) 62 | { 63 | return elementNodes.Select(item => (AutomationElement)item.TypedValue); 64 | } 65 | } 66 | 67 | return Enumerable.Empty(); 68 | } 69 | 70 | internal static AutomationElement FindFirst(AutomationElement parent, TreeScope scope, Condition condition) 71 | { 72 | return FindFirst(parent, scope, condition, CruciatusFactory.Settings.SearchTimeout); 73 | } 74 | 75 | internal static AutomationElement FindFirst( 76 | AutomationElement parent, 77 | TreeScope scope, 78 | Condition condition, 79 | int timeout) 80 | { 81 | var dtn = DateTime.Now.AddMilliseconds(timeout); 82 | 83 | // ReSharper disable once LoopVariableIsNeverChangedInsideLoop 84 | while (DateTime.Now <= dtn) 85 | { 86 | var element = parent.FindFirst(scope, condition); 87 | if (element != null) 88 | { 89 | return element; 90 | } 91 | } 92 | 93 | return null; 94 | } 95 | 96 | internal static bool TryGetBoundingRectangleCenter(AutomationElement element, out Point point) 97 | { 98 | var rect = element.Current.BoundingRectangle; 99 | if (rect.IsEmpty) 100 | { 101 | point = new Point(); 102 | return false; 103 | } 104 | 105 | point = rect.Location; 106 | point.Offset(rect.Width / 2, rect.Height / 2); 107 | return true; 108 | } 109 | 110 | internal static bool TryGetClickablePoint(AutomationElement element, out Point point) 111 | { 112 | return element.TryGetClickablePoint(out point); 113 | } 114 | 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/AutomationPropertyHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers 2 | { 3 | #region using 4 | 5 | using System.Text.RegularExpressions; 6 | using System.Windows.Automation; 7 | 8 | #endregion 9 | 10 | internal static class AutomationPropertyHelper 11 | { 12 | #region Methods 13 | 14 | internal static string GetPropertyName(AutomationIdentifier property) 15 | { 16 | var pattern = new Regex(@".*\.(?.*)Property"); 17 | return pattern.Match(property.ProgrammaticName).Groups["name"].Value; 18 | } 19 | 20 | #endregion 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/ScreenCoordinatesHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers 2 | { 3 | #region using 4 | 5 | using System.Windows; 6 | 7 | #endregion 8 | 9 | internal static class ScreenCoordinatesHelper 10 | { 11 | #region Static Fields 12 | 13 | internal static readonly Point VirtualScreenLowerRightCorner = new Point(65535, 65535); 14 | 15 | #endregion 16 | 17 | #region Methods 18 | 19 | internal static Point ScreenPointToVirtualScreenPoint(Point point) 20 | { 21 | var sX = point.X; 22 | var sY = point.Y; 23 | 24 | var virtualScreenLeft = SystemParameters.VirtualScreenLeft; 25 | if (virtualScreenLeft < 0) 26 | { 27 | sX -= virtualScreenLeft; 28 | } 29 | 30 | var vsX = sX * (VirtualScreenLowerRightCorner.X / SystemParameters.VirtualScreenWidth); 31 | var vsY = sY * (VirtualScreenLowerRightCorner.Y / SystemParameters.VirtualScreenHeight); 32 | 33 | return new Point(vsX, vsY); 34 | } 35 | 36 | #endregion 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/XPath/DesktopTreeXPathNavigator.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers.XPath 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Windows.Automation; 7 | using System.Xml; 8 | using System.Xml.XPath; 9 | 10 | #endregion 11 | 12 | internal class DesktopTreeXPathNavigator : XPathNavigator 13 | { 14 | #region Fields 15 | 16 | private XPathItem item; 17 | 18 | #endregion 19 | 20 | #region Constructors and Destructors 21 | 22 | public DesktopTreeXPathNavigator() 23 | : this(AutomationElement.RootElement) 24 | { 25 | } 26 | 27 | internal DesktopTreeXPathNavigator(AutomationElement element) 28 | { 29 | if (element == null) 30 | { 31 | throw new ArgumentNullException("element"); 32 | } 33 | 34 | this.item = ElementItem.Create(element); 35 | } 36 | 37 | internal DesktopTreeXPathNavigator(XPathItem item) 38 | { 39 | if (item == null) 40 | { 41 | throw new ArgumentNullException("item"); 42 | } 43 | 44 | this.item = item; 45 | } 46 | 47 | #endregion 48 | 49 | #region Public Properties 50 | 51 | public override string BaseURI 52 | { 53 | get 54 | { 55 | return string.Empty; 56 | } 57 | } 58 | 59 | public override bool IsEmptyElement 60 | { 61 | get 62 | { 63 | return this.item.IsEmptyElement; 64 | } 65 | } 66 | 67 | public override string LocalName 68 | { 69 | get 70 | { 71 | return this.Name; 72 | } 73 | } 74 | 75 | public override string Name 76 | { 77 | get 78 | { 79 | return this.item.Name; 80 | } 81 | } 82 | 83 | public override XmlNameTable NameTable 84 | { 85 | get 86 | { 87 | return null; 88 | } 89 | } 90 | 91 | public override string NamespaceURI 92 | { 93 | get 94 | { 95 | return string.Empty; 96 | } 97 | } 98 | 99 | public override XPathNodeType NodeType 100 | { 101 | get 102 | { 103 | return this.item.NodeType; 104 | } 105 | } 106 | 107 | public override string Prefix 108 | { 109 | get 110 | { 111 | return string.Empty; 112 | } 113 | } 114 | 115 | public override object TypedValue 116 | { 117 | get 118 | { 119 | return this.item.TypedValue(); 120 | } 121 | } 122 | 123 | public override string Value 124 | { 125 | get 126 | { 127 | return this.item.Value; 128 | } 129 | } 130 | 131 | #endregion 132 | 133 | #region Public Methods and Operators 134 | 135 | public override XPathNavigator Clone() 136 | { 137 | return new DesktopTreeXPathNavigator(this.item); 138 | } 139 | 140 | public override bool IsSamePosition(XPathNavigator other) 141 | { 142 | var obj = other as DesktopTreeXPathNavigator; 143 | return obj != null && obj.item.IsSamePosition(this.item); 144 | } 145 | 146 | public override bool MoveTo(XPathNavigator other) 147 | { 148 | var obj = other as DesktopTreeXPathNavigator; 149 | if (obj == null) 150 | { 151 | return false; 152 | } 153 | 154 | this.item = obj.item; 155 | return true; 156 | } 157 | 158 | public override bool MoveToFirstAttribute() 159 | { 160 | return this.MoveToItem(this.item.MoveToFirstProperty()); 161 | } 162 | 163 | public override bool MoveToFirstChild() 164 | { 165 | return this.MoveToItem(this.item.MoveToFirstChild()); 166 | } 167 | 168 | public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) 169 | { 170 | return false; 171 | } 172 | 173 | public override bool MoveToId(string id) 174 | { 175 | return false; 176 | } 177 | 178 | public override bool MoveToNext() 179 | { 180 | return this.MoveToItem(this.item.MoveToNext()); 181 | } 182 | 183 | public override bool MoveToNextAttribute() 184 | { 185 | return this.MoveToItem(this.item.MoveToNextProperty()); 186 | } 187 | 188 | public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) 189 | { 190 | return false; 191 | } 192 | 193 | public override bool MoveToParent() 194 | { 195 | return this.MoveToItem(this.item.MoveToParent()); 196 | } 197 | 198 | public override bool MoveToPrevious() 199 | { 200 | return this.MoveToItem(this.item.MoveToPrevious()); 201 | } 202 | 203 | #endregion 204 | 205 | #region Methods 206 | 207 | private bool MoveToItem(XPathItem newItem) 208 | { 209 | if (newItem == null) 210 | { 211 | return false; 212 | } 213 | 214 | this.item = newItem; 215 | return true; 216 | } 217 | 218 | #endregion 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/XPath/ElementItem.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers.XPath 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Windows.Automation; 9 | using System.Xml.XPath; 10 | 11 | using Winium.Cruciatus.Elements; 12 | using Winium.Cruciatus.Exceptions; 13 | 14 | #endregion 15 | 16 | internal class ElementItem : XPathItem 17 | { 18 | #region Fields 19 | 20 | private readonly AutomationElement element; 21 | 22 | private readonly TreeWalker treeWalker = TreeWalker.ControlViewWalker; 23 | 24 | private List properties; 25 | 26 | #endregion 27 | 28 | #region Constructors and Destructors 29 | 30 | internal ElementItem(AutomationElement element) 31 | { 32 | if (element == null) 33 | { 34 | throw new ArgumentNullException("element"); 35 | } 36 | 37 | this.element = element; 38 | } 39 | 40 | #endregion 41 | 42 | #region Properties 43 | 44 | internal override bool IsEmptyElement 45 | { 46 | get 47 | { 48 | var hasChild = this.MoveToFirstChild() != null; 49 | if (hasChild) 50 | { 51 | return false; 52 | } 53 | 54 | try 55 | { 56 | new CruciatusElement(null, this.element, null).Text(); 57 | return false; 58 | } 59 | catch (CruciatusException) 60 | { 61 | return true; 62 | } 63 | } 64 | } 65 | 66 | internal override string Name 67 | { 68 | get 69 | { 70 | return this.element.Current.Name; 71 | } 72 | } 73 | 74 | internal override XPathNodeType NodeType 75 | { 76 | get 77 | { 78 | return XPathNodeType.Element; 79 | } 80 | } 81 | 82 | internal List SupportedProperties 83 | { 84 | get 85 | { 86 | return this.properties ?? (this.properties = this.element.GetSupportedProperties().ToList()); 87 | } 88 | } 89 | 90 | #endregion 91 | 92 | #region Public Methods and Operators 93 | 94 | public override object TypedValue() 95 | { 96 | return this.element; 97 | } 98 | 99 | #endregion 100 | 101 | #region Methods 102 | 103 | internal static XPathItem Create(AutomationElement instance) 104 | { 105 | return instance.Equals(AutomationElement.RootElement) ? new RootItem() : new ElementItem(instance); 106 | } 107 | 108 | internal AutomationProperty GetNextPropertyOrNull(AutomationProperty property) 109 | { 110 | var index = this.SupportedProperties.IndexOf(property); 111 | return this.SupportedProperties.ElementAtOrDefault(index + 1); 112 | } 113 | 114 | internal object GetPropertyValue(AutomationProperty property) 115 | { 116 | return this.element.GetCurrentPropertyValue(property); 117 | } 118 | 119 | internal override bool IsSamePosition(XPathItem item) 120 | { 121 | var obj = item as ElementItem; 122 | return obj != null && obj.element.Equals(this.element); 123 | } 124 | 125 | internal override XPathItem MoveToFirstChild() 126 | { 127 | var firstChild = this.treeWalker.GetFirstChild(this.element); 128 | return (firstChild == null) ? null : Create(firstChild); 129 | } 130 | 131 | internal override XPathItem MoveToFirstProperty() 132 | { 133 | return this.SupportedProperties.Any() ? new PropertyItem(this, this.SupportedProperties[0]) : null; 134 | } 135 | 136 | internal override XPathItem MoveToNext() 137 | { 138 | var next = this.treeWalker.GetNextSibling(this.element); 139 | return (next == null) ? null : Create(next); 140 | } 141 | 142 | internal override XPathItem MoveToNextProperty() 143 | { 144 | return null; 145 | } 146 | 147 | internal override XPathItem MoveToParent() 148 | { 149 | var parent = this.treeWalker.GetParent(this.element); 150 | return (parent == null) ? null : Create(parent); 151 | } 152 | 153 | internal override XPathItem MoveToPrevious() 154 | { 155 | var previous = this.treeWalker.GetPreviousSibling(this.element); 156 | return (previous == null) ? null : Create(previous); 157 | } 158 | 159 | #endregion 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/XPath/PropertyItem.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers.XPath 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | using System.Xml.XPath; 7 | 8 | #endregion 9 | 10 | internal class PropertyItem : XPathItem 11 | { 12 | #region Fields 13 | 14 | private readonly ElementItem parent; 15 | 16 | private readonly AutomationProperty property; 17 | 18 | #endregion 19 | 20 | #region Constructors and Destructors 21 | 22 | public PropertyItem(ElementItem parent, AutomationProperty property) 23 | { 24 | this.parent = parent; 25 | this.property = property; 26 | } 27 | 28 | #endregion 29 | 30 | #region Properties 31 | 32 | internal override bool IsEmptyElement 33 | { 34 | get 35 | { 36 | return false; 37 | } 38 | } 39 | 40 | internal override string Name 41 | { 42 | get 43 | { 44 | return AutomationPropertyHelper.GetPropertyName(this.property); 45 | } 46 | } 47 | 48 | internal override XPathNodeType NodeType 49 | { 50 | get 51 | { 52 | return XPathNodeType.Attribute; 53 | } 54 | } 55 | 56 | internal override string Value 57 | { 58 | get 59 | { 60 | var value = this.TypedValue(); 61 | var type = value as ControlType; 62 | return type != null ? type.ProgrammaticName : value.ToString(); 63 | } 64 | } 65 | 66 | #endregion 67 | 68 | #region Public Methods and Operators 69 | 70 | public override object TypedValue() 71 | { 72 | return this.parent.GetPropertyValue(this.property); 73 | } 74 | 75 | #endregion 76 | 77 | #region Methods 78 | 79 | internal override bool IsSamePosition(XPathItem item) 80 | { 81 | var obj = item as PropertyItem; 82 | return obj != null && obj.parent == this.parent && obj.property.Equals(this.property); 83 | } 84 | 85 | internal override XPathItem MoveToFirstChild() 86 | { 87 | return null; 88 | } 89 | 90 | internal override XPathItem MoveToFirstProperty() 91 | { 92 | return null; 93 | } 94 | 95 | internal override XPathItem MoveToNext() 96 | { 97 | return null; 98 | } 99 | 100 | internal override XPathItem MoveToNextProperty() 101 | { 102 | var nextProperty = this.parent.GetNextPropertyOrNull(this.property); 103 | return (nextProperty == null) ? null : new PropertyItem(this.parent, nextProperty); 104 | } 105 | 106 | internal override XPathItem MoveToParent() 107 | { 108 | return this.parent; 109 | } 110 | 111 | internal override XPathItem MoveToPrevious() 112 | { 113 | return null; 114 | } 115 | 116 | #endregion 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/XPath/RootItem.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers.XPath 2 | { 3 | #region using 4 | 5 | using System.Windows.Automation; 6 | using System.Xml.XPath; 7 | 8 | #endregion 9 | 10 | internal class RootItem : ElementItem 11 | { 12 | #region Constructors and Destructors 13 | 14 | internal RootItem() 15 | : base(AutomationElement.RootElement) 16 | { 17 | } 18 | 19 | #endregion 20 | 21 | #region Properties 22 | 23 | internal override bool IsEmptyElement 24 | { 25 | get 26 | { 27 | return false; 28 | } 29 | } 30 | 31 | internal override string Name 32 | { 33 | get 34 | { 35 | return "Desktop Window"; 36 | } 37 | } 38 | 39 | internal override XPathNodeType NodeType 40 | { 41 | get 42 | { 43 | return XPathNodeType.Root; 44 | } 45 | } 46 | 47 | #endregion 48 | 49 | #region Methods 50 | 51 | internal override XPathItem MoveToNext() 52 | { 53 | return null; 54 | } 55 | 56 | internal override XPathItem MoveToParent() 57 | { 58 | return null; 59 | } 60 | 61 | internal override XPathItem MoveToPrevious() 62 | { 63 | return null; 64 | } 65 | 66 | #endregion 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Helpers/XPath/XPathItem.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Helpers.XPath 2 | { 3 | #region using 4 | 5 | using System.Xml.XPath; 6 | 7 | #endregion 8 | 9 | internal abstract class XPathItem 10 | { 11 | #region Properties 12 | 13 | internal abstract bool IsEmptyElement { get; } 14 | 15 | internal abstract string Name { get; } 16 | 17 | internal abstract XPathNodeType NodeType { get; } 18 | 19 | internal virtual string Value 20 | { 21 | get 22 | { 23 | return string.Empty; 24 | } 25 | } 26 | 27 | #endregion 28 | 29 | #region Public Methods and Operators 30 | 31 | public abstract object TypedValue(); 32 | 33 | #endregion 34 | 35 | #region Methods 36 | 37 | internal abstract bool IsSamePosition(XPathItem item); 38 | 39 | internal abstract XPathItem MoveToFirstChild(); 40 | 41 | internal abstract XPathItem MoveToFirstProperty(); 42 | 43 | internal abstract XPathItem MoveToNext(); 44 | 45 | internal abstract XPathItem MoveToNextProperty(); 46 | 47 | internal abstract XPathItem MoveToParent(); 48 | 49 | internal abstract XPathItem MoveToPrevious(); 50 | 51 | #endregion 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/MessageBox.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Windows; 7 | using System.Windows.Automation; 8 | 9 | using Winium.Cruciatus.Core; 10 | using Winium.Cruciatus.Elements; 11 | using Winium.Cruciatus.Exceptions; 12 | using Winium.Cruciatus.Helpers; 13 | 14 | #endregion 15 | 16 | /// 17 | /// Класс для работы с диалоговым окном MessageBox. 18 | /// 19 | public static class MessageBox 20 | { 21 | #region Public Methods and Operators 22 | 23 | /// 24 | /// Кликает по заданной кнопке диалогового окна. 25 | /// 26 | /// 27 | /// Диалоговое окно. 28 | /// 29 | /// 30 | /// Тип набора кнопок диалогово окна. 31 | /// 32 | /// 33 | /// Целевая кнопка. 34 | /// 35 | public static void ClickButton( 36 | CruciatusElement dialogWindow, 37 | MessageBoxButton buttonsType, 38 | MessageBoxResult targetButton) 39 | { 40 | if (dialogWindow == null) 41 | { 42 | throw new ArgumentNullException("dialogWindow"); 43 | } 44 | 45 | var condition = new PropertyCondition(WindowPattern.IsModalProperty, true); 46 | var modalwindow = AutomationElementHelper.FindFirst(dialogWindow.Instance, TreeScope.Children, condition); 47 | if (modalwindow == null) 48 | { 49 | throw new CruciatusException("NOT CLICK BUTTON"); 50 | } 51 | 52 | string uid; 53 | if (targetButton == MessageBoxResult.None) 54 | { 55 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.CloseButton; 56 | } 57 | else 58 | { 59 | switch (buttonsType) 60 | { 61 | case MessageBoxButton.OK: 62 | switch (targetButton) 63 | { 64 | case MessageBoxResult.OK: 65 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.OkType.Ok; 66 | break; 67 | default: 68 | throw new CruciatusException("NOT CLICK BUTTON"); 69 | } 70 | 71 | break; 72 | 73 | case MessageBoxButton.OKCancel: 74 | switch (targetButton) 75 | { 76 | case MessageBoxResult.OK: 77 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.OkCancelType.Ok; 78 | break; 79 | case MessageBoxResult.Cancel: 80 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.OkCancelType.Cancel; 81 | break; 82 | default: 83 | throw new CruciatusException("NOT CLICK BUTTON"); 84 | } 85 | 86 | break; 87 | 88 | case MessageBoxButton.YesNo: 89 | switch (targetButton) 90 | { 91 | case MessageBoxResult.Yes: 92 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.YesNoType.Yes; 93 | break; 94 | case MessageBoxResult.No: 95 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.YesNoType.No; 96 | break; 97 | default: 98 | throw new CruciatusException("NOT CLICK BUTTON"); 99 | } 100 | 101 | break; 102 | 103 | case MessageBoxButton.YesNoCancel: 104 | switch (targetButton) 105 | { 106 | case MessageBoxResult.Yes: 107 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.YesNoCancelType.Yes; 108 | break; 109 | case MessageBoxResult.No: 110 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.YesNoCancelType.No; 111 | break; 112 | case MessageBoxResult.Cancel: 113 | uid = CruciatusFactory.Settings.MessageBoxButtonUid.YesNoCancelType.Cancel; 114 | break; 115 | default: 116 | throw new CruciatusException("NOT CLICK BUTTON"); 117 | } 118 | 119 | break; 120 | 121 | default: 122 | throw new CruciatusException("NOT CLICK BUTTON"); 123 | } 124 | } 125 | 126 | var buttonElement = new CruciatusElement(dialogWindow, modalwindow, null).FindElement(By.Uid(uid)); 127 | buttonElement.Click(); 128 | } 129 | 130 | #endregion 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region using 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | #endregion 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("Winium.Cruciatus")] 12 | [assembly: AssemblyDescription("C# Framework for automated testing of Windows application based on WinFroms and WPF platforms.")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("Winium.Cruciatus")] 16 | [assembly: AssemblyCopyright("Copyright © 2015")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("8d0fd035-b765-414a-a9f5-0f39ed1085cd")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("2.7.0.0")] 37 | [assembly: AssemblyFileVersion("2.10.0.*")] 38 | [assembly: AssemblyInformationalVersion("2.10.0")] 39 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/KeyboardSimulatorType.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings 2 | { 3 | /// 4 | /// Перечисление поддерживаемых симуляторов клавиатуры. 5 | /// 6 | public enum KeyboardSimulatorType 7 | { 8 | /// 9 | /// Список поддерживаемых ключей клавиш и конструкций https://msdn.microsoft.com/ru-ru/library/system.windows.forms.sendkeys(v=vs.110).aspx 10 | /// 11 | BasedOnWindowsFormsSendKeysClass, 12 | 13 | /// 14 | /// Для получения допольнительных методов необходимо привести к KeyboardSimulatorExt. 15 | /// Подробности о библиотеке http://inputsimulator.codeplex.com/ 16 | /// 17 | BasedOnInputSimulatorLib 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/MessageBoxSettings/MessageBoxButtonUid.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings.MessageBoxSettings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс описывающий уникальные идентификаторы кнопок диалогового окна MessageBox. 11 | /// 12 | public class MessageBoxButtonUid : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Уникальный идентификатор кнопки Отмена. 18 | /// 19 | public string CloseButton { get; set; } 20 | 21 | /// 22 | /// Тип набор из 2 кнопок - Ок и Отмена. 23 | /// 24 | public OkCancelType OkCancelType { get; set; } 25 | 26 | /// 27 | /// Тип набор из 1 кнопки - Ок. 28 | /// 29 | public OkType OkType { get; set; } 30 | 31 | /// 32 | /// Тип набор из 2 кнопок - Да, Нет и Отмена. 33 | /// 34 | public YesNoCancelType YesNoCancelType { get; set; } 35 | 36 | /// 37 | /// Тип набор из 2 кнопок - Да и Нет. 38 | /// 39 | public YesNoType YesNoType { get; set; } 40 | 41 | #endregion 42 | 43 | #region Public Methods and Operators 44 | 45 | public object Clone() 46 | { 47 | return new MessageBoxButtonUid 48 | { 49 | CloseButton = this.CloseButton, 50 | OkType = (OkType)this.OkType.Clone(), 51 | OkCancelType = (OkCancelType)this.OkCancelType.Clone(), 52 | YesNoType = (YesNoType)this.YesNoType.Clone(), 53 | YesNoCancelType = (YesNoCancelType)this.YesNoCancelType.Clone() 54 | }; 55 | } 56 | 57 | #endregion 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/MessageBoxSettings/OkCancelType.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings.MessageBoxSettings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс описывающий набор из 2 кнопок - Ок и Отмена. 11 | /// 12 | public class OkCancelType : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Уникальный идентификатор кнопки Отмена. 18 | /// 19 | public string Cancel { get; set; } 20 | 21 | /// 22 | /// Уникальный идентификатор кнопки Ок. 23 | /// 24 | public string Ok { get; set; } 25 | 26 | #endregion 27 | 28 | #region Public Methods and Operators 29 | 30 | public object Clone() 31 | { 32 | return new OkCancelType { Ok = this.Ok, Cancel = this.Cancel }; 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/MessageBoxSettings/OkType.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings.MessageBoxSettings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс описывающий набор из 1 кнопки - Ок. 11 | /// 12 | public class OkType : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Уникальный идентификатор кнопки Ок. 18 | /// 19 | public string Ok { get; set; } 20 | 21 | #endregion 22 | 23 | #region Public Methods and Operators 24 | 25 | public object Clone() 26 | { 27 | return new OkType { Ok = this.Ok }; 28 | } 29 | 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/MessageBoxSettings/YesNoCancelType.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings.MessageBoxSettings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс описывающий набор из 3 кнопок - Да, Нет и Отмена. 11 | /// 12 | public class YesNoCancelType : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Уникальный идентификатор кнопки Отмена. 18 | /// 19 | public string Cancel { get; set; } 20 | 21 | /// 22 | /// Уникальный идентификатор кнопки Нет. 23 | /// 24 | public string No { get; set; } 25 | 26 | /// 27 | /// Уникальный идентификатор кнопки Да. 28 | /// 29 | public string Yes { get; set; } 30 | 31 | #endregion 32 | 33 | #region Public Methods and Operators 34 | 35 | public object Clone() 36 | { 37 | return new YesNoCancelType { Yes = this.Yes, No = this.No, Cancel = this.Cancel }; 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/MessageBoxSettings/YesNoType.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings.MessageBoxSettings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс описывающий набор из 2 кнопок - Да и Нет. 11 | /// 12 | public class YesNoType : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Уникальный идентификатор кнопки Нет. 18 | /// 19 | public string No { get; set; } 20 | 21 | /// 22 | /// Уникальный идентификатор кнопки Да. 23 | /// 24 | public string Yes { get; set; } 25 | 26 | #endregion 27 | 28 | #region Public Methods and Operators 29 | 30 | public object Clone() 31 | { 32 | return new YesNoType { Yes = this.Yes, No = this.No }; 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/OpenFileDialogUid.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс, описывающий уникальные идентификаторы элементов диалога OpenFileDialog. 11 | /// 12 | public class OpenFileDialogUid : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Кнопка Отмена. 18 | /// 19 | public string CancelButton { get; set; } 20 | 21 | /// 22 | /// Редактируемый выпадающий список с именем открываемого файла. 23 | /// 24 | public string FileNameEditableComboBox { get; set; } 25 | 26 | /// 27 | /// Кнопка Открыть. 28 | /// 29 | public string OpenButton { get; set; } 30 | 31 | #endregion 32 | 33 | #region Public Methods and Operators 34 | 35 | public object Clone() 36 | { 37 | return new OpenFileDialogUid 38 | { 39 | OpenButton = this.OpenButton, 40 | CancelButton = this.CancelButton, 41 | FileNameEditableComboBox = this.FileNameEditableComboBox 42 | }; 43 | } 44 | 45 | #endregion 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Settings/SaveFileDialogUid.cs: -------------------------------------------------------------------------------- 1 | namespace Winium.Cruciatus.Settings 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Класс, описывающий уникальные идентификаторы элементов диалога SaveFileDialog. 11 | /// 12 | public class SaveFileDialogUid : ICloneable 13 | { 14 | #region Public Properties 15 | 16 | /// 17 | /// Кнопка Отмена. 18 | /// 19 | public string CancelButton { get; set; } 20 | 21 | /// 22 | /// Редактируемый выпадающий список с именем сохраняемого файла. 23 | /// 24 | public string FileNameEditableComboBox { get; set; } 25 | 26 | /// 27 | /// Выпадающий список с типом сохраняемого файла. 28 | /// 29 | public string FileTypeComboBox { get; set; } 30 | 31 | /// 32 | /// Кнопка Сохранить. 33 | /// 34 | public string SaveButton { get; set; } 35 | 36 | #endregion 37 | 38 | #region Public Methods and Operators 39 | 40 | public object Clone() 41 | { 42 | return new SaveFileDialogUid 43 | { 44 | SaveButton = this.SaveButton, 45 | CancelButton = this.CancelButton, 46 | FileNameEditableComboBox = this.FileNameEditableComboBox, 47 | FileTypeComboBox = this.FileTypeComboBox 48 | }; 49 | } 50 | 51 | #endregion 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/Winium.Cruciatus.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | 2GIS 7 | 2GIS 8 | https://github.com/2gis/Winium.Cruciatus 9 | false 10 | $description$ 11 | 12 | v2.10.0 13 | - Add `RotationManager` for get and set display orientation (thanks to @jonstoneman) 14 | 15 | Copyright @ 2015 16 | Automation Desktop C# 17 | 18 | -------------------------------------------------------------------------------- /src/Winium.Cruciatus/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Winium.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Winium.Cruciatus", "Winium.Cruciatus\Winium.Cruciatus.csproj", "{45982320-D316-4AFB-B350-15EAE32F4D4C}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestApplications", "TestApplications", "{EB335D6E-0D73-4125-AD82-8230F91EA3ED}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestApplications.Tests", "TestApplications.Tests", "{0948A51D-EF5B-4279-863E-B908B4CCF528}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsTestApplication", "TestApplications\WindowsFormsTestApplication\WindowsFormsTestApplication.csproj", "{5A44C751-4393-4BE1-9912-4C4C84B382B4}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfTestApplication", "TestApplications\WpfTestApplication\WpfTestApplication.csproj", "{5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfTestApplication.Tests", "TestApplications.Tests\WpfTestApplication.Tests\WpfTestApplication.Tests.csproj", "{9D5915DE-F329-47BA-B382-E70976B1A4B2}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsTestApplication.Tests", "TestApplications.Tests\WindowsFormsTestApplication.Tests\WindowsFormsTestApplication.Tests.csproj", "{470F6A5F-5138-47C8-B1FC-D0494F7DFD8A}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E0563C53-24A0-487B-99EF-AB7905613312}" 21 | ProjectSection(SolutionItems) = preProject 22 | .nuget\NuGet.Config = .nuget\NuGet.Config 23 | .nuget\NuGet.targets = .nuget\NuGet.targets 24 | EndProjectSection 25 | EndProject 26 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F3AAC82D-1933-40EC-8BF1-00C7C4A2E099}" 27 | ProjectSection(SolutionItems) = preProject 28 | Settings.StyleCop = Settings.StyleCop 29 | Winium.sln.DotSettings = Winium.sln.DotSettings 30 | EndProjectSection 31 | EndProject 32 | Global 33 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 34 | Debug|Any CPU = Debug|Any CPU 35 | Release|Any CPU = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 38 | {45982320-D316-4AFB-B350-15EAE32F4D4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {45982320-D316-4AFB-B350-15EAE32F4D4C}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {45982320-D316-4AFB-B350-15EAE32F4D4C}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {45982320-D316-4AFB-B350-15EAE32F4D4C}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {5A44C751-4393-4BE1-9912-4C4C84B382B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {5A44C751-4393-4BE1-9912-4C4C84B382B4}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {5A44C751-4393-4BE1-9912-4C4C84B382B4}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {5A44C751-4393-4BE1-9912-4C4C84B382B4}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {9D5915DE-F329-47BA-B382-E70976B1A4B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {9D5915DE-F329-47BA-B382-E70976B1A4B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {9D5915DE-F329-47BA-B382-E70976B1A4B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {9D5915DE-F329-47BA-B382-E70976B1A4B2}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A}.Release|Any CPU.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(NestedProjects) = preSolution 63 | {5A44C751-4393-4BE1-9912-4C4C84B382B4} = {EB335D6E-0D73-4125-AD82-8230F91EA3ED} 64 | {5B591917-AC83-4BA4-BD6B-1C36D7DB0E7F} = {EB335D6E-0D73-4125-AD82-8230F91EA3ED} 65 | {9D5915DE-F329-47BA-B382-E70976B1A4B2} = {0948A51D-EF5B-4279-863E-B908B4CCF528} 66 | {470F6A5F-5138-47C8-B1FC-D0494F7DFD8A} = {0948A51D-EF5B-4279-863E-B908B4CCF528} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /tools/UISpy/UISpy.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2gis/Winium.Cruciatus/09ff49c971a6bdb4c18ddfecdd88508439519187/tools/UISpy/UISpy.exe --------------------------------------------------------------------------------