├── .gitignore ├── LICENSE ├── README.md ├── README_RU.md ├── assets ├── winium.png └── winium.svg ├── dotnet ├── CHANGELOG.md ├── README.md ├── scripts │ ├── ci-release.ps1 │ ├── ci.ps1 │ ├── prepare-release.ps1 │ └── setup.ps1 └── src │ ├── .nuget │ ├── NuGet.Config │ └── NuGet.targets │ ├── OpenQA.Selenium.Winium │ ├── CommandExecutorFactory.cs │ ├── DesktopOptions.cs │ ├── IWiniumOptions.cs │ ├── OpenQA.Selenium.Winium.csproj │ ├── OpenQA.Selenium.Winium.nuspec │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SilverlightOptions.cs │ ├── StoreAppsOptions.cs │ ├── WiniumDriver.cs │ ├── WiniumDriverCommandExecutor.cs │ ├── WiniumDriverService.cs │ └── packages.config │ ├── Settings.StyleCop │ ├── Winium.sln │ └── Winium.sln.DotSettings ├── java ├── .gitignore ├── CHANGELOG.md ├── README.md ├── pom.xml ├── scripts │ └── ci.ps1 └── src │ └── main │ └── java │ └── org │ └── openqa │ └── selenium │ └── winium │ ├── DesktopOptions.java │ ├── KeyboardSimulatorType.java │ ├── SilverlightOptions.java │ ├── StoreAppsOptions.java │ ├── WiniumDriver.java │ ├── WiniumDriverCommandExecutor.java │ ├── WiniumDriverService.java │ └── WiniumOptions.java └── scripts └── ci.ps1 /.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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | 364 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

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

4 | 5 | # Winium 6 |

7 | Winium is Selenium Remote WebDriver implementations for automated testing on Windows platforms 8 |

9 | 10 | Automation framework for Windows platforms. It is free. It is opensource. It is Selenium-based. 11 | 12 | # Why Winium? 13 | You have Selenium WebDriver for testing of web apps, Appium for testing of iOS and Android apps. And now you have Selenium-based tools for testing of Windows apps too. What are some of the benefits? As said by Appium: 14 | > - You can write tests with your favorite dev tools using any WebDriver-compatible language such as Java, Objective-C, JavaScript with Node.js (in promise, callback or generator flavors), PHP, Python, Ruby, C#, Clojure, or Perl with the Selenium WebDriver API and language-specific client libraries. 15 | > - You can use any testing framework. 16 | 17 | # Supported Platforms 18 | - Windows Desktop (WPF, WinForms) Apps 19 | - Windows Store or Universal Apps for Windows Phone 20 | - Windows Phone Silverlight Apps 21 | 22 | # [Winium for Desktop](https://github.com/2gis/Winium.Desktop) 23 | [![GitHub release](https://img.shields.io/github/release/2gis/Winium.Desktop.svg?style=flat-square)](https://github.com/2gis/Winium.Desktop/releases/) 24 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](LICENSE) 25 | 26 | Winium.Desktop is Selenium Remote WebDriver implementation for automated testing of Windows application based on WinFroms and WPF platforms. 27 | 28 | ### Supported Platforms 29 | - WinForms 30 | - WPF 31 | 32 | 33 | # [Winium for Mobile](https://github.com/2gis/Winium.Mobile) 34 | [![Winium.StoreApps.InnerServer Inner Server NuGet version](https://img.shields.io/nuget/v/Winium.StoreApps.InnerServer.svg?style=flat-square&label=nuget%20storeapps)](https://www.nuget.org/packages/Winium.StoreApps.InnerServer/) 35 | [![Winium.Silverlight.InnerServer NuGet version](https://img.shields.io/nuget/v/Winium.Silverlight.InnerServer.svg?style=flat-square&label=nuget%20silverlight)](https://www.nuget.org/packages/Winium.Silverlight.InnerServer/) 36 | [![GitHub release](https://img.shields.io/github/release/2gis/Winium.StoreApps.svg?style=flat-square)](https://github.com/2gis/Winium.StoreApps/releases/) 37 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](LICENSE) 38 | 39 | 40 | Winium.Mobile is Selenium Remote WebDriver implementation for automated testing of Windows StoreApps and Silverlight apps, tested on emulators (currently only Windows Phone/Mobile apps are supported) 41 | 42 | ### Supported Platforms 43 | - Windows Phone 8.1 Store Apps (or Universal App for Windows Phone) 44 | - Windows Phone 8.1 Silverlight apps 45 | - Windows 10 Mobile (there are some known [issues](https://github.com/2gis/Winium.Mobile/labels/windows10)) 46 | 47 | # [Winium.Mobile CodedUI Driver](https://github.com/2gis/winium.storeapps.codedui) 48 | Prototype of Winium Mobile driver using CodedUI. It is Selenium Remote WebDriver implementation for automation of Windows Phone 8.1 and Windows 10 Mobile applications. 49 | -------------------------------------------------------------------------------- /README_RU.md: -------------------------------------------------------------------------------- 1 | # Winium 2 |

3 | Winium это реализация Selenium Remote WebDriver для автоматизации тестирования под Windows плафтормами 4 |

5 | 6 | Фреймворк автоматизации под Windows платформы. Бесплатно. Open-source. Selenium-based. 7 | 8 | ## Почему Winium? 9 | Уже есть Selenium WebDriver для тестирования веб приложений, Appium для тестирования iOS и Android приложений. А теперь появился и Selenium-based инструмент для тестирования Windows приложений. Какие он дает преимущества? Цитируя Appium: 10 | > - You can write tests with your favorite dev tools using any WebDriver-compatible language such as Java, Objective-C, JavaScript with Node.js (in promise, callback or generator flavors), PHP, Python, Ruby, C#, Clojure, or Perl with the Selenium WebDriver API and language-specific client libraries. 11 | > - You can use any testing framework. 12 | 13 | А по-русски можно? 14 | - Пишите тесты, используя ваши любимые инструменты, любой WebDriver-совместимый язык программирования, например, Java, Objective-C, JavaScript with Node.js, PHP, Python, Ruby, C#, Clojure... 15 | - Используйте любой тестовый фреймворк. 16 | 17 | # Поддерживаемые платформы 18 | - Windows Desktop (WPF, WinForms) Apps 19 | - Windows Store or Universal Apps for Windows Phone 20 | - Windows Phone Silverlight Apps 21 | 22 | # [Winium for Desktop](https://github.com/2gis/Winium.Desktop) 23 | [![GitHub release](https://img.shields.io/github/release/2gis/Winium.Desktop.svg?style=flat-square)](https://github.com/2gis/Winium.Desktop/releases/) 24 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](LICENSE) 25 | 26 | Winium.Desktop это open-source инструмент для автоматизации тестирования Windows приложений построенных на WinFroms и WPF платформах 27 | 28 | ### Поддерживаемые платформы 29 | - WinForms 30 | - WPF 31 | 32 | 33 | # [Winium for Mobile](https://github.com/2gis/Winium.Mobile) 34 | [![Winium.StoreApps.InnerServer Inner Server NuGet version](https://img.shields.io/nuget/v/Winium.StoreApps.InnerServer.svg?style=flat-square&label=nuget%20storeapps)](https://www.nuget.org/packages/Winium.StoreApps.InnerServer/) 35 | [![Winium.Silverlight.InnerServer NuGet version](https://img.shields.io/nuget/v/Winium.Silverlight.InnerServer.svg?style=flat-square&label=nuget%20silverlight)](https://www.nuget.org/packages/Winium.Silverlight.InnerServer/) 36 | [![GitHub release](https://img.shields.io/github/release/2gis/Winium.StoreApps.svg?style=flat-square)](https://github.com/2gis/Winium.StoreApps/releases/) 37 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](LICENSE) 38 | 39 | 40 | Winium.Mobile это open-source инструмент для автоматизации Windows Store и Silverlight мобильных приложений, тестируемых на эмуляторах (поддерживаются Windows Phone 8.1 и Windows 10 Mobile приложения). 41 | 42 | ### Поддерживаемые платформы 43 | - Windows Phone 8.1 Store Apps (or Universal App for Windows Phone) 44 | - Windows Phone 8.1 Silverlight apps 45 | - Windows 10 Mobile (there are some known [issues](https://github.com/2gis/Winium.Mobile/labels/windows10)) 46 | 47 | # [Winium.Mobile CodedUI Driver](https://github.com/2gis/winium.storeapps.codedui) 48 | Прототип Winium Mobile драйвера на основе CodedUI. Реализует Selenium Remote WebDriver implementation для автоматизации Windows Phone 8.1 и Windows 10 Mobile приложений. 49 | -------------------------------------------------------------------------------- /assets/winium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2gis/Winium/69b7aacef51f735a1d40ea8d90cfd6a9eb6ea4cd/assets/winium.png -------------------------------------------------------------------------------- /assets/winium.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 24 | image/svg+xml 25 | 27 | 28 | 29 | 30 | 31 | 33 | 53 | 58 | 63 | 68 | 73 | 78 | 83 | 88 | 93 | 98 | 103 | 108 | 113 | 114 | -------------------------------------------------------------------------------- /dotnet/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | 4 | ## v0.1.1 5 | 6 | - Add constructor using specifed remote address 7 | 8 | 9 | ## v0.1.0 10 | 11 | - WebDriver .Net bindings for Winium 12 | - Exposes the service provided by the native WiniumDriver executable 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dotnet/README.md: -------------------------------------------------------------------------------- 1 | # Winium.WebDriver for .NET 2 | 3 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](../LICENSE) 4 | 5 |

6 | Winium.WebDriver is an extension of [WebDriver C# bindings](https://www.nuget.org/packages/Selenium.WebDriver/). 7 |

8 | 9 | This is an extension of [WebDriver C# bindings](https://www.nuget.org/packages/Selenium.WebDriver/). 10 | Provides a mechanism to write tests using [Winium.Desktop](https://github.com/2gis/Winium.Desktop), [Winium.StoreApps](https://github.com/2gis/Winium.StioreApps) or [winphonedriver](https://github.com/2gis/winphonedriver). 11 | 12 | Winium.WebDriver retains the functionality of common driver and has specific methods for interaction with the Winium Driver. 13 | 14 | 15 | ## Quick Start 16 | 1. Add reference to `Winium.WebDriver` in UI test project. 17 | 2. Initialize an instance of specific for Desktop, StoreApps, Silverlight Options class. 18 | 19 | [DesktopOptions] for example: 20 | ```cs 21 | var options = new DesktopOptions { ApplicationPath = @"C:\Windows\System32\notepad.exe" }; 22 | ``` 23 | 3. Create the instance of the [WebDriver] class. 24 | 25 | Use default constructor: 26 | ```cs 27 | var driver = new WiniumDriver(options); 28 | ``` 29 | Use the native WiniumDriver executable: 30 | ```cs 31 | var service = WiniumDriverService.CreateDesktopService("path_to_driver_executible_folder"); 32 | 33 | var driver = new WiniumDriver(service, options, TimeSpan.FromMinutes(30)); 34 | ``` 35 | 36 | ## Contributing 37 | 38 | Contributions are welcome! 39 | 40 | 1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. 41 | 2. Fork the repository to start making your changes to the master branch (or branch off of it). 42 | 3. We recommend to write a test which shows that the bug was fixed or that the feature works as expected. 43 | 4. Send a pull request and bug the maintainer until it gets merged and published. :smiley: 44 | 45 | ## Contact 46 | 47 | Have some questions? Found a bug? Create [new issue](https://github.com/2gis/Winium/issues/new) or contact us at t.kurnosova@2gis.ru 48 | 49 | ## License 50 | 51 | Winium is released under the MPL 2.0 license. See [LICENSE](../LICENSE) for details. 52 | -------------------------------------------------------------------------------- /dotnet/scripts/ci-release.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('git', 'versioning', 'changelog', 'msbuild', 'nuget')) 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 | # Create nuget-package 26 | New-Item -ItemType directory -Path $releaseDir | Out-Null 27 | Invoke-NuGetPack $project $configuration $releaseDir -Verbose 28 | 29 | # Git add changes 30 | Invoke-Git ('add', $assemblyInfoPath) -Verbose 31 | Invoke-Git ('add', $changelogPath) -Verbose 32 | Invoke-Git ('add', $nuspecPath) -Verbose 33 | 34 | # Git commit and push 35 | Invoke-GitCommit "Winium WebDriver version $version" -Verbose 36 | Invoke-Git ('push', 'origin', 'master') -Verbose 37 | 38 | # Git tag and push 39 | $buildUrl = $env:BUILD_URL 40 | Invoke-GitTag "Winium WebDriver version '$version'. Build url '$buildUrl'." "v$version" -Verbose 41 | Invoke-Git ('push', 'origin', 'master', "v$version") -Verbose 42 | 43 | # Push nuget-package 44 | $package = Join-Path $releaseDir '*.nupkg' 45 | Invoke-NuGetPush $package -Verbose 46 | -------------------------------------------------------------------------------- /dotnet/scripts/ci.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('msbuild')) 6 | 7 | # Build 8 | Invoke-MSBuild $solution $msbuildProperties -Verbose 9 | -------------------------------------------------------------------------------- /dotnet/scripts/prepare-release.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | Import-Module '.\setup.ps1' -Args (,('msbuild', '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-Host "Update version in Assemblies" 16 | Write-Host "Update release notes in Nuspec file" 17 | 18 | Pause 19 | 20 | # Build 21 | Invoke-MSBuild $solution $msbuildProperties -Verbose 22 | 23 | # Create nuget-package 24 | Invoke-NuGetPack $project $configuration $releaseDir -Verbose 25 | 26 | Write-Output "Publish NuGet package using nuget.exe push $releaseDir\*.nupkg" 27 | Write-Output "Add and push tag using git tag -a -m 'Version *.*.*' v*.*.*" 28 | Write-Output "Upload and attach $releaseDir\* files to release" 29 | -------------------------------------------------------------------------------- /dotnet/scripts/setup.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string[]]$modules 3 | ) 4 | 5 | Set-StrictMode -Version Latest 6 | $ErrorActionPreference = 'Stop' 7 | #------------------------------ 8 | 9 | $configuration = 'Release' 10 | $solutionDir = Join-Path $PSScriptRoot "../src" 11 | $solution = Join-Path $solutionDir 'Winium.sln' 12 | $project = Join-Path $solutionDir 'OpenQA.Selenium.Winium\OpenQA.Selenium.Winium.csproj' 13 | $releaseDir = Join-Path $PSScriptRoot '../Release' 14 | $assemblyInfoPath = Join-Path $solutionDir 'OpenQA.Selenium.Winium\Properties\AssemblyInfo.cs' 15 | $changelogPath = Join-Path $PSScriptRoot '..\CHANGELOG.md' 16 | $nuspecPath = Join-Path $solutionDir 'OpenQA.Selenium.Winium\OpenQA.Selenium.Winium.nuspec' 17 | 18 | $msbuildProperties = @{ 19 | 'Configuration' = $configuration 20 | } 21 | 22 | $modulesUrl = 'https://raw.githubusercontent.com/skyline-gleb/dev-help/v0.2.1/psm' 23 | 24 | if (!(Get-Module -ListAvailable -Name PsGet)) 25 | { 26 | (new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex 27 | } 28 | 29 | foreach ($module in $modules) 30 | { 31 | Install-Module -ModuleUrl "$modulesUrl/$module.psm1" -Update 32 | } 33 | -------------------------------------------------------------------------------- /dotnet/src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dotnet/src/.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config 41 | 42 | 43 | 44 | $(MSBuildProjectDirectory)\packages.config 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | $(NuGetToolsPath)\NuGet.exe 51 | @(PackageSource) 52 | 53 | "$(NuGetExePath)" 54 | mono --runtime=v4.0.30319 "$(NuGetExePath)" 55 | 56 | $(TargetDir.Trim('\\')) 57 | 58 | -RequireConsent 59 | -NonInteractive 60 | 61 | "$(SolutionDir) " 62 | "$(SolutionDir)" 63 | 64 | 65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 67 | 68 | 69 | 70 | RestorePackages; 71 | $(BuildDependsOn); 72 | 73 | 74 | 75 | 76 | $(BuildDependsOn); 77 | BuildPackage; 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/CommandExecutorFactory.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Reflection; 7 | 8 | using OpenQA.Selenium.Remote; 9 | 10 | #endregion 11 | 12 | internal static class CommandExecutorFactory 13 | { 14 | #region Public Methods and Operators 15 | 16 | public static ICommandExecutor GetHttpCommandExecutor(Uri remoteAddress, TimeSpan commandTimeout) 17 | { 18 | var seleniumAssembly = Assembly.Load("WebDriver"); 19 | var commandType = seleniumAssembly.GetType("OpenQA.Selenium.Remote.HttpCommandExecutor"); 20 | ICommandExecutor commandExecutor = null; 21 | 22 | if (null != commandType) 23 | { 24 | commandExecutor = 25 | Activator.CreateInstance(commandType, new object[] { remoteAddress, commandTimeout }) as 26 | ICommandExecutor; 27 | } 28 | 29 | return commandExecutor; 30 | } 31 | 32 | #endregion 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/DesktopOptions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System.Collections.Generic; 6 | 7 | using OpenQA.Selenium; 8 | using OpenQA.Selenium.Remote; 9 | 10 | #endregion 11 | 12 | /// 13 | /// The keyboard simulator type. 14 | /// 15 | public enum KeyboardSimulatorType 16 | { 17 | /// 18 | /// Based on SendKeys Class.See more. 19 | /// 20 | BasedOnWindowsFormsSendKeysClass, 21 | 22 | /// 23 | /// Based on Windows Input Simulator. 24 | /// For additional methods should be cast to the KeyboardSimulatorExt. See more. 25 | /// 26 | BasedOnInputSimulatorLib 27 | } 28 | 29 | /// 30 | /// Class to manage options specific to 31 | /// wich uses Winium.Desktop. 32 | /// 33 | public class DesktopOptions : IWiniumOptions 34 | { 35 | #region Constants 36 | 37 | private const string ApplicationPathOption = "app"; 38 | 39 | private const string ArgumentsOption = "args"; 40 | 41 | private const string DebugConnectToRunningAppOption = "debugConnectToRunningApp"; 42 | 43 | private const string KeyboardSimulatorOption = "keyboardSimulator"; 44 | 45 | private const string LaunchDelayOption = "launchDelay"; 46 | 47 | #endregion 48 | 49 | #region Fields 50 | 51 | private string applicationPath; 52 | 53 | private string arguments; 54 | 55 | private bool? debugConnectToRunningApp; 56 | 57 | private KeyboardSimulatorType? keyboardSimulator; 58 | 59 | private int? launchDelay; 60 | 61 | #endregion 62 | 63 | #region Public Properties 64 | 65 | /// 66 | /// Gets or sets the absolute local path to an .exe file to be started. 67 | /// This capability is not required if debugConnectToRunningApp is specified. 68 | /// 69 | public string ApplicationPath 70 | { 71 | set 72 | { 73 | this.applicationPath = value; 74 | } 75 | } 76 | 77 | /// 78 | /// Gets or sets startup argunments of the application under test. 79 | /// 80 | public string Arguments 81 | { 82 | set 83 | { 84 | this.arguments = value; 85 | } 86 | } 87 | 88 | /// 89 | /// Gets or sets a value indicating whether debug connect to running app. 90 | /// If true, then application starting step are skipped. 91 | /// 92 | public bool DebugConnectToRunningApp 93 | { 94 | set 95 | { 96 | this.debugConnectToRunningApp = value; 97 | } 98 | } 99 | 100 | /// 101 | /// Gets or sets the keyboard simulator type. 102 | /// 103 | public KeyboardSimulatorType KeyboardSimulator 104 | { 105 | set 106 | { 107 | this.keyboardSimulator = value; 108 | } 109 | } 110 | 111 | /// 112 | /// Gets or sets the launch delay in milliseconds, to be waited to let visuals to initialize after application started. 113 | /// 114 | public int LaunchDelay 115 | { 116 | set 117 | { 118 | this.launchDelay = value; 119 | } 120 | } 121 | 122 | #endregion 123 | 124 | #region Public Methods and Operators 125 | 126 | /// 127 | /// Convert options to DesiredCapabilities for Winium Desktop Driver 128 | /// 129 | /// The DesiredCapabilities for Winium Desktop Driver with these options. 130 | public ICapabilities ToCapabilities() 131 | { 132 | var capabilityDictionary = new Dictionary 133 | { 134 | { ApplicationPathOption, this.applicationPath } 135 | }; 136 | 137 | if (!string.IsNullOrEmpty(this.arguments)) 138 | { 139 | capabilityDictionary.Add(ArgumentsOption, this.arguments); 140 | } 141 | 142 | if (this.debugConnectToRunningApp.HasValue) 143 | { 144 | capabilityDictionary.Add(DebugConnectToRunningAppOption, this.debugConnectToRunningApp); 145 | } 146 | 147 | if (this.keyboardSimulator.HasValue) 148 | { 149 | capabilityDictionary.Add(KeyboardSimulatorOption, this.keyboardSimulator); 150 | } 151 | 152 | if (this.launchDelay.HasValue) 153 | { 154 | capabilityDictionary.Add(LaunchDelayOption, this.launchDelay); 155 | } 156 | 157 | return new DesiredCapabilities(capabilityDictionary); 158 | } 159 | 160 | #endregion 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/IWiniumOptions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using OpenQA.Selenium; 6 | 7 | #endregion 8 | 9 | /// 10 | /// Defines the interface to manage options specific to 11 | /// 12 | public interface IWiniumOptions 13 | { 14 | #region Public Methods and Operators 15 | 16 | /// 17 | /// Convert options to DesiredCapabilities for one of Winium Drivers 18 | /// 19 | /// The DesiredCapabilities for Winium Driver with these options. 20 | ICapabilities ToCapabilities(); 21 | 22 | #endregion 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/OpenQA.Selenium.Winium.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C2E62426-F3C3-45D9-A677-EBB9C7468252} 8 | Library 9 | Properties 10 | OpenQA.Selenium.Winium 11 | Winium.WebDriver 12 | v4.5 13 | 512 14 | ..\..\..\..\Winium.Elements\dotnet\src\ 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 | 37 | 38 | ..\packages\Selenium.WebDriver.2.48.0\lib\net40\WebDriver.dll 39 | True 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 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}. 58 | 59 | 60 | 61 | 68 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/OpenQA.Selenium.Winium.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | 2GIS 7 | 2GIS 8 | https://github.com/2gis/Winium 9 | false 10 | $description$ 11 | 12 | 13 | 14 | 15 | v0.1.1 16 | - Add constructor using specifed remote address 17 | 18 | Copyright @ 2015 19 | Winium WebDriver C# 20 | 21 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Winium WebDriber")] 9 | [assembly: AssemblyDescription("Winium WebDriver for .NET")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OpenQA.Selenium.Winium")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2f3d82bc-fc1e-4837-b7bc-708fec0c161d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 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("0.1.0.0")] 36 | [assembly: AssemblyFileVersion("0.1.1.*")] 37 | [assembly: AssemblyInformationalVersion("0.1.1")] 38 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/SilverlightOptions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System.Collections.Generic; 6 | 7 | using OpenQA.Selenium; 8 | using OpenQA.Selenium.Remote; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Class to manage options specific to 14 | /// wich uses Windows Phone Driver. 15 | /// 16 | public class SilverlightOptions : IWiniumOptions 17 | { 18 | #region Constants 19 | 20 | private const string ApplicationPathOption = "app"; 21 | 22 | private const string DebugConnectToRunningAppOption = "debugConnectToRunningApp"; 23 | 24 | private const string DeviceNameOption = "deviceName"; 25 | 26 | private const string InnerPortOption = "innerPort"; 27 | 28 | private const string LaunchDelayOption = "launchDelay"; 29 | 30 | private const string LaunchTimeoutOption = "launchTimeout"; 31 | 32 | #endregion 33 | 34 | #region Fields 35 | 36 | private string applicationPath; 37 | 38 | private bool? debugConnectToRunningApp; 39 | 40 | private string deviceName; 41 | 42 | private int? innerPort; 43 | 44 | private int? launchDelay; 45 | 46 | private int? launchTimeout; 47 | 48 | #endregion 49 | 50 | #region Public Properties 51 | 52 | /// 53 | /// Gets or sets the absolute local path to an .xap file to be installed and launched. 54 | /// This capability is not required if debugConnectToRunningApp is specified. 55 | /// 56 | public string ApplicationPath 57 | { 58 | set 59 | { 60 | this.applicationPath = value; 61 | } 62 | } 63 | 64 | /// 65 | /// Gets or sets a value indicating whether debug connect to running app. 66 | /// If true, then application starting step are skipped. 67 | /// 68 | public bool DebugConnectToRunningApp 69 | { 70 | set 71 | { 72 | this.debugConnectToRunningApp = value; 73 | } 74 | } 75 | 76 | /// 77 | /// Gets or sets name of emulator to use for running test. 78 | /// Note that this capability is not required, if no device name is specified, 79 | /// then a default emulator is used.You can specify only partial name, 80 | /// first emulator that starts with specified deviceName will be selected. 81 | /// 82 | public string DeviceName 83 | { 84 | set 85 | { 86 | this.deviceName = value; 87 | } 88 | } 89 | 90 | /// 91 | /// Gets or sets the inner port used to communicate between OuterDriver and InnerDrive (injected into Windows Phone app). 92 | /// Required only if non-default port was specified in tested app in AutomationServer.Instance.InitializeAndStart call. 93 | /// 94 | public int InnerPort 95 | { 96 | set 97 | { 98 | this.innerPort = value; 99 | } 100 | } 101 | 102 | /// 103 | /// Gets or sets launch delay in milliseconds, to be waited to let visuals to initialize after application launched (after successful ping or timeout). 104 | /// Use it if the system running emulator is slow. 105 | /// 106 | public int LaunchDelay 107 | { 108 | set 109 | { 110 | this.launchDelay = value; 111 | } 112 | } 113 | 114 | /// 115 | /// Gets or sets maximum timeout in milliseconds, to be waited for application to launch. 116 | /// 117 | public int LaunchTimeout 118 | { 119 | set 120 | { 121 | this.launchTimeout = value; 122 | } 123 | } 124 | 125 | #endregion 126 | 127 | #region Public Methods and Operators 128 | 129 | /// 130 | /// Convert options to DesiredCapabilities for Windows Phone Driver 131 | /// 132 | /// The DesiredCapabilities for Windows Phone Driver with these options. 133 | public ICapabilities ToCapabilities() 134 | { 135 | var capabilityDictionary = new Dictionary 136 | { 137 | { ApplicationPathOption, this.applicationPath } 138 | }; 139 | 140 | if (this.debugConnectToRunningApp.HasValue) 141 | { 142 | capabilityDictionary.Add(DebugConnectToRunningAppOption, this.debugConnectToRunningApp); 143 | } 144 | 145 | if (!string.IsNullOrEmpty(this.deviceName)) 146 | { 147 | capabilityDictionary.Add(DeviceNameOption, this.deviceName); 148 | } 149 | 150 | if (this.launchTimeout.HasValue) 151 | { 152 | capabilityDictionary.Add(LaunchTimeoutOption, this.launchTimeout); 153 | } 154 | 155 | if (this.launchDelay.HasValue) 156 | { 157 | capabilityDictionary.Add(LaunchDelayOption, this.launchDelay); 158 | } 159 | 160 | if (!string.IsNullOrEmpty(this.deviceName)) 161 | { 162 | capabilityDictionary.Add(DeviceNameOption, this.deviceName); 163 | } 164 | 165 | if (this.innerPort.HasValue) 166 | { 167 | capabilityDictionary.Add(InnerPortOption, this.innerPort); 168 | } 169 | 170 | return new DesiredCapabilities(capabilityDictionary); 171 | } 172 | 173 | #endregion 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/StoreAppsOptions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System.Collections.Generic; 6 | 7 | using OpenQA.Selenium; 8 | using OpenQA.Selenium.Remote; 9 | 10 | #endregion 11 | 12 | /// 13 | /// Class to manage options specific to 14 | /// wich uses Winium.StoreApps. 15 | /// 16 | public class StoreAppsOptions : IWiniumOptions 17 | { 18 | #region Constants 19 | 20 | private const string ApplicationPathOption = "app"; 21 | 22 | private const string DebugConnectToRunningAppOption = "debugConnectToRunningApp"; 23 | 24 | private const string DependenciesOption = "dependencies"; 25 | 26 | private const string DeviceNameOption = "deviceName"; 27 | 28 | private const string FilesOption = "files"; 29 | 30 | private const string LaunchDelayOption = "launchDelay"; 31 | 32 | private const string LaunchTimeoutOption = "launchTimeout"; 33 | 34 | #endregion 35 | 36 | #region Fields 37 | 38 | private string applicationPath; 39 | 40 | private bool? debugConnectToRunningApp; 41 | 42 | private List dependencies; 43 | 44 | private string deviceName; 45 | 46 | private Dictionary files; 47 | 48 | private int? launchDelay; 49 | 50 | private int? launchTimeout; 51 | 52 | #endregion 53 | 54 | #region Public Properties 55 | 56 | /// 57 | /// Gets or sets the absolute local path to an .appx file to be installed and launched. 58 | /// This capability is not required if debugConnectToRunningApp is specified. 59 | /// 60 | public string ApplicationPath 61 | { 62 | set 63 | { 64 | this.applicationPath = value; 65 | } 66 | } 67 | 68 | /// 69 | /// Gets or sets a value indicating whether debug connect to running app. 70 | /// If true, then application starting step are skipped. 71 | /// 72 | public bool DebugConnectToRunningApp 73 | { 74 | set 75 | { 76 | this.debugConnectToRunningApp = value; 77 | } 78 | } 79 | 80 | /// 81 | /// Gets or sets a list of dependencies. 82 | /// 83 | public List Dependencies 84 | { 85 | set 86 | { 87 | this.dependencies = value; 88 | } 89 | } 90 | 91 | /// 92 | /// Gets or sets name of emulator to use for running test. 93 | /// Note that this capability is not required, if no device name is specified, 94 | /// then a default emulator is used.You can specify only partial name, 95 | /// first emulator that starts with specified deviceName will be selected. 96 | /// 97 | public string DeviceName 98 | { 99 | set 100 | { 101 | this.deviceName = value; 102 | } 103 | } 104 | 105 | /// 106 | /// Gets or sets the files. 107 | /// Each key of the dictionary is "local file path", each corresponding value is "remote file path" 108 | /// 109 | public Dictionary Files 110 | { 111 | set 112 | { 113 | this.files = value; 114 | } 115 | } 116 | 117 | /// 118 | /// Gets or sets launch delay in milliseconds, to be waited to let visuals to initialize after application launched (after successful ping or timeout). 119 | /// Use it if the system running emulator is slow. 120 | /// 121 | public int LaunchDelay 122 | { 123 | set 124 | { 125 | this.launchDelay = value; 126 | } 127 | } 128 | 129 | /// 130 | /// Gets or sets maximum timeout in milliseconds, to be waited for application to launch. 131 | /// 132 | public int LaunchTimeout 133 | { 134 | set 135 | { 136 | this.launchTimeout = value; 137 | } 138 | } 139 | 140 | #endregion 141 | 142 | #region Public Methods and Operators 143 | 144 | /// 145 | /// Convert options to DesiredCapabilities for Winium StoreApps Driver 146 | /// 147 | /// The DesiredCapabilities for Winium StoreApps Driver with these options. 148 | public ICapabilities ToCapabilities() 149 | { 150 | var capabilityDictionary = new Dictionary 151 | { 152 | { ApplicationPathOption, this.applicationPath } 153 | }; 154 | 155 | if (this.files.Count > 0) 156 | { 157 | capabilityDictionary.Add(FilesOption, this.files); 158 | } 159 | 160 | if (this.debugConnectToRunningApp.HasValue) 161 | { 162 | capabilityDictionary.Add(DebugConnectToRunningAppOption, this.debugConnectToRunningApp); 163 | } 164 | 165 | if (!string.IsNullOrEmpty(this.deviceName)) 166 | { 167 | capabilityDictionary.Add(DeviceNameOption, this.deviceName); 168 | } 169 | 170 | if (this.launchTimeout.HasValue) 171 | { 172 | capabilityDictionary.Add(LaunchTimeoutOption, this.launchTimeout); 173 | } 174 | 175 | if (this.launchDelay.HasValue) 176 | { 177 | capabilityDictionary.Add(LaunchDelayOption, this.launchDelay); 178 | } 179 | 180 | if (this.dependencies.Count > 0) 181 | { 182 | capabilityDictionary.Add(DependenciesOption, this.dependencies); 183 | } 184 | 185 | return new DesiredCapabilities(capabilityDictionary); 186 | } 187 | 188 | #endregion 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/WiniumDriver.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System; 6 | 7 | using OpenQA.Selenium.Remote; 8 | 9 | #endregion 10 | 11 | /// 12 | /// Provides a mechanism to write tests using Winium driver. 13 | /// 14 | /// 15 | /// 16 | /// [TestFixture] 17 | /// public class Testing 18 | /// { 19 | /// private IWebDriver driver; 20 | /// 21 | /// [SetUp] 22 | /// public void SetUp() 23 | /// { 24 | /// var options = new DesktopOptions { ApplicationPath = @"‪C:\Windows\System32\notepad.exe" }; 25 | /// driver = new WiniumDriver(options); 26 | /// } 27 | /// 28 | /// [Test] 29 | /// public void TestGoogle() 30 | /// { 31 | /// /* 32 | /// * Rest of the test 33 | /// */ 34 | /// } 35 | /// 36 | /// [TearDown] 37 | /// public void TearDown() 38 | /// { 39 | /// driver.Quit(); 40 | /// } 41 | /// } 42 | /// 43 | /// 44 | public class WiniumDriver : RemoteWebDriver 45 | { 46 | #region Constructors and Destructors 47 | 48 | /// 49 | /// Initializes a new instance of the class using the specified path 50 | /// to the directory containing Winium.Driver executible file and options. 51 | /// 52 | /// 53 | /// The full path to the directory containing Winium.Driver executible. 54 | /// 55 | /// 56 | /// The to be used with the Winium driver. 57 | /// 58 | public WiniumDriver(string winiumDriverDirectory, IWiniumOptions options) 59 | : this(winiumDriverDirectory, options, RemoteWebDriver.DefaultCommandTimeout) 60 | { 61 | } 62 | 63 | /// 64 | /// Initializes a new instance of the class using the specified path 65 | /// to the directory containing Winium.Driver executible file, options, and command timeout. 66 | /// 67 | /// 68 | /// The full path to the directory containing Winium.Driver executible file. 69 | /// 70 | /// 71 | /// The to be used with the Winium driver. 72 | /// 73 | /// 74 | /// The maximum amount of time to wait for each command. 75 | /// 76 | public WiniumDriver(string winiumDriverDirectory, IWiniumOptions options, TimeSpan commandTimeout) 77 | : this(CreateDefaultService(options.GetType(), winiumDriverDirectory), options, commandTimeout) 78 | { 79 | } 80 | 81 | /// 82 | /// Initializes a new instance of the class using the specified 83 | /// and options. 84 | /// 85 | /// The to use. 86 | /// The used to initialize the driver. 87 | public WiniumDriver(WiniumDriverService service, IWiniumOptions options) 88 | : this(service, options, RemoteWebDriver.DefaultCommandTimeout) 89 | { 90 | } 91 | 92 | /// 93 | /// Initializes a new instance of the class using the specified . 94 | /// 95 | /// The to use. 96 | /// The object to be used with the Winium driver. 97 | /// The maximum amount of time to wait for each command. 98 | public WiniumDriver(WiniumDriverService service, IWiniumOptions options, TimeSpan commandTimeout) 99 | : base(new WiniumDriverCommandExecutor(service, commandTimeout), options.ToCapabilities()) 100 | { 101 | this.InitWiniumDriverCommands(); 102 | } 103 | 104 | /// 105 | /// Initializes a new instance of the class using the specified remote address and options. 106 | /// 107 | /// URI containing the address of the WiniumDriver remote server (e.g. http://127.0.0.1:4444/wd/hub). 108 | /// The object to be used with the Winium driver. 109 | public WiniumDriver(Uri remoteAddress, IWiniumOptions options) 110 | : this(remoteAddress, options, RemoteWebDriver.DefaultCommandTimeout) 111 | { 112 | } 113 | 114 | /// 115 | /// Initializes a new instance of the class using the specified remote address, desired capabilities, and command timeout. 116 | /// 117 | /// URI containing the address of the WiniumDriver remote server (e.g. http://127.0.0.1:4444/wd/hub). 118 | /// The object to be used with the Winium driver. 119 | /// The maximum amount of time to wait for each command. 120 | public WiniumDriver(Uri remoteAddress, IWiniumOptions options, TimeSpan commandTimeout) 121 | : base(CommandExecutorFactory.GetHttpCommandExecutor(remoteAddress, commandTimeout), options.ToCapabilities()) 122 | { 123 | this.InitWiniumDriverCommands(); 124 | } 125 | 126 | #endregion 127 | 128 | #region Methods 129 | 130 | private static WiniumDriverService CreateDefaultService(Type optionsType, string directory) 131 | { 132 | if (optionsType == typeof(DesktopOptions)) 133 | { 134 | return WiniumDriverService.CreateDesktopService(directory); 135 | } 136 | 137 | if (optionsType == typeof(StoreAppsOptions)) 138 | { 139 | return WiniumDriverService.CreateStoreAppsService(directory); 140 | } 141 | 142 | if (optionsType == typeof(SilverlightOptions)) 143 | { 144 | return WiniumDriverService.CreateSilverlightService(directory); 145 | } 146 | 147 | throw new ArgumentException( 148 | "Option type must be type of DesktopOptions, StoreAppsOptions or SilverlightOptions", 149 | "optionsType"); 150 | } 151 | 152 | private void InitWiniumDriverCommands() 153 | { 154 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 155 | "findDataGridCell", 156 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/datagrid/cell/{row}/{column}")); 157 | 158 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 159 | "getDataGridColumnCount", 160 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/datagrid/column/count")); 161 | 162 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 163 | "getDataGridRowCount", 164 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/datagrid/row/count")); 165 | 166 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 167 | "scrollToDataGridCell", 168 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/datagrid/scroll/{row}/{column}")); 169 | 170 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 171 | "selectDataGridCell", 172 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/datagrid/select/{row}/{column}")); 173 | 174 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 175 | "scrollToListBoxItem", 176 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/listbox/scroll")); 177 | 178 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 179 | "findMenuItem", 180 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/menu/item/{path}")); 181 | 182 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 183 | "selectMenuItem", 184 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/menu/select/{path}")); 185 | 186 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 187 | "isComboBoxExpanded", 188 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/combobox/expanded")); 189 | 190 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 191 | "expandComboBox", 192 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/combobox/expand")); 193 | 194 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 195 | "collapseComboBox", 196 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/combobox/collapse")); 197 | 198 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 199 | "findComboBoxSelectedItem", 200 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/combobox/items/selected")); 201 | 202 | this.CommandExecutor.CommandInfoRepository.TryAddCommand( 203 | "scrollToComboBoxItem", 204 | new CommandInfo("POST", "/session/{sessionId}/element/{id}/combobox/scroll")); 205 | } 206 | 207 | #endregion 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/WiniumDriverCommandExecutor.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Reflection; 7 | 8 | using OpenQA.Selenium.Remote; 9 | 10 | #endregion 11 | 12 | public class WiniumDriverCommandExecutor : ICommandExecutor 13 | { 14 | #region Fields 15 | 16 | private ICommandExecutor internalExecutor; 17 | 18 | private WiniumDriverService service; 19 | 20 | #endregion 21 | 22 | #region Constructors and Destructors 23 | 24 | public WiniumDriverCommandExecutor(WiniumDriverService driverService, TimeSpan commandTimeout) 25 | { 26 | this.service = driverService; 27 | this.internalExecutor = CommandExecutorFactory.GetHttpCommandExecutor(driverService.ServiceUrl, commandTimeout); 28 | } 29 | 30 | #endregion 31 | 32 | #region Public Properties 33 | 34 | public CommandInfoRepository CommandInfoRepository 35 | { 36 | get 37 | { 38 | return this.internalExecutor.CommandInfoRepository; 39 | } 40 | } 41 | 42 | #endregion 43 | 44 | #region Public Methods and Operators 45 | 46 | public Response Execute(Command commandToExecute) 47 | { 48 | if (commandToExecute == null) 49 | { 50 | throw new ArgumentNullException("commandToExecute", "Command may not be null"); 51 | } 52 | 53 | if (commandToExecute.Name == DriverCommand.NewSession) 54 | { 55 | this.service.Start(); 56 | } 57 | 58 | try 59 | { 60 | return this.internalExecutor.Execute(commandToExecute); 61 | } 62 | finally 63 | { 64 | if (commandToExecute.Name == DriverCommand.Quit) 65 | { 66 | this.service.Dispose(); 67 | } 68 | } 69 | } 70 | 71 | #endregion 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/WiniumDriverService.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Winium 2 | { 3 | #region using 4 | 5 | using System; 6 | using System.Globalization; 7 | using System.Net; 8 | using System.Net.Sockets; 9 | using System.Text; 10 | 11 | #endregion 12 | 13 | /// 14 | /// Exposes the service provided by the native Winium Driver executable. 15 | /// 16 | /// 17 | /// 18 | /// [TestFixture] 19 | /// public class Testing 20 | /// { 21 | /// private IWebDriver driver; 22 | /// 23 | /// [SetUp] 24 | /// public void SetUp() 25 | /// { 26 | /// var service = 27 | /// WiniumDriverService.CreateDesktopService("path_to_driver_executible_folder"); 28 | /// 29 | /// service.SuppressInitialDiagnosticInformation = false; 30 | /// service.EnableVerboseLogging = true; 31 | /// 32 | /// var options = new DesktopOptions { ApplicationPath = @"‪C:\Windows\System32\notepad.exe" }; 33 | /// driver = new WiniumDriver(service, options, TimeSpan.FromMinutes(30)); 34 | /// } 35 | /// 36 | /// [Test] 37 | /// public void TestGoogle() 38 | /// { 39 | /// /* 40 | /// * Rest of the test 41 | /// */ 42 | /// } 43 | /// 44 | /// [TearDown] 45 | /// public void TearDown() 46 | /// { 47 | /// driver.Quit(); 48 | /// } 49 | /// } 50 | /// 51 | /// 52 | public class WiniumDriverService : DriverService 53 | { 54 | #region Constants 55 | 56 | private const string DesktopDriverServiceFileName = "Winium.Desktop.Driver.exe"; 57 | 58 | private const string SilverlightDriverServiceFileName = "WindowsPhoneDriver.OuterDriver.exe"; 59 | 60 | private const string StoreAppsDriverServiceFileName = "Winium.StoreApps.Driver.exe"; 61 | 62 | #endregion 63 | 64 | #region Static Fields 65 | 66 | private static readonly Uri DesktopDriverDownloadUrl = new Uri( 67 | "https://github.com/2gis/Winium.Desktop/releases"); 68 | 69 | private static readonly Uri SilverlightDriverDownloadUrl = 70 | new Uri("https://github.com/2gis/winphonedriver/releases"); 71 | 72 | private static readonly Uri StoreAppsDriverDownloadUrl = 73 | new Uri("https://github.com/2gis/Winium.StoreApps/releases"); 74 | 75 | private static readonly Uri WiniumDownloUrl = new Uri("https://github.com/2gis/Winium"); 76 | 77 | #endregion 78 | 79 | #region Fields 80 | 81 | private bool enableVerboseLogging; 82 | 83 | private string logPath = string.Empty; 84 | 85 | #endregion 86 | 87 | #region Constructors and Destructors 88 | 89 | private WiniumDriverService(string executablePath, string executableFileName, int port, Uri downloadUrl) 90 | : base(executablePath, port, executableFileName, downloadUrl) 91 | { 92 | } 93 | 94 | #endregion 95 | 96 | #region Public Properties 97 | 98 | /// 99 | /// Gets or sets a value indicating whether to enable verbose logging for the Winium Driver executable. 100 | /// Defaults to . 101 | /// 102 | public bool EnableVerboseLogging 103 | { 104 | get 105 | { 106 | return this.enableVerboseLogging; 107 | } 108 | 109 | set 110 | { 111 | this.enableVerboseLogging = value; 112 | } 113 | } 114 | 115 | /// 116 | /// Gets or sets the location of the log file written to by the Winium Driver executable. 117 | /// 118 | public string LogPath 119 | { 120 | get 121 | { 122 | return this.logPath; 123 | } 124 | 125 | set 126 | { 127 | this.logPath = value; 128 | } 129 | } 130 | 131 | #endregion 132 | 133 | #region Properties 134 | 135 | /// 136 | /// Gets the command-line arguments for the driver service. 137 | /// 138 | protected override string CommandLineArguments 139 | { 140 | get 141 | { 142 | StringBuilder argsBuilder = new StringBuilder(base.CommandLineArguments); 143 | 144 | if (this.SuppressInitialDiagnosticInformation) 145 | { 146 | argsBuilder.Append(" --silent"); 147 | } 148 | 149 | if (this.enableVerboseLogging) 150 | { 151 | argsBuilder.Append(" --verbose"); 152 | } 153 | 154 | if (!string.IsNullOrEmpty(this.logPath)) 155 | { 156 | argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --log-path={0}", this.logPath); 157 | } 158 | 159 | return argsBuilder.ToString(); 160 | } 161 | } 162 | 163 | #endregion 164 | 165 | #region Public Methods and Operators 166 | 167 | /// 168 | /// Creates a default instance of the WiniumDriverService using a specified path to the Winium Driver executable with the given name. 169 | /// 170 | /// The directory containing the Winium Driver executable. 171 | /// The name of the Winium Driver executable file. 172 | /// A using a random port. 173 | public static WiniumDriverService CreateDefaultService(string driverPath, string driverExecutableFileName) 174 | { 175 | return new WiniumDriverService( 176 | driverPath, 177 | driverExecutableFileName, 178 | FindFreePort(), 179 | WiniumDownloUrl); 180 | } 181 | 182 | /// 183 | /// Creates a default instance of the WiniumDriverService using a specified path to the Winium Desktop Driver. 184 | /// 185 | /// The directory containing the Winium Desktop Driver executable. 186 | /// A using Winium Deaktop and random port. 187 | public static WiniumDriverService CreateDesktopService(string driverPath) 188 | { 189 | return new WiniumDriverService( 190 | driverPath, 191 | DesktopDriverServiceFileName, 192 | FindFreePort(), 193 | DesktopDriverDownloadUrl); 194 | } 195 | 196 | /// 197 | /// Creates a default instance of the WiniumDriverService using a specified path to the WindowsPhone Driver. 198 | /// 199 | /// The directory containing the WindowsPhone Driver executable. 200 | /// A using WindowsPhone Driver and random port. 201 | public static WiniumDriverService CreateSilverlightService(string driverPath) 202 | { 203 | return new WiniumDriverService( 204 | driverPath, 205 | SilverlightDriverServiceFileName, 206 | FindFreePort(), 207 | SilverlightDriverDownloadUrl); 208 | } 209 | 210 | /// 211 | /// Creates a default instance of the WiniumDriverService using a specified path to the Winium AtoreApps Driver. 212 | /// 213 | /// The directory containing the Winium StoreApps Driver executable. 214 | /// A using Winium StoreApps and random port. 215 | public static WiniumDriverService CreateStoreAppsService(string driverPath) 216 | { 217 | return new WiniumDriverService( 218 | driverPath, 219 | StoreAppsDriverServiceFileName, 220 | FindFreePort(), 221 | StoreAppsDriverDownloadUrl); 222 | } 223 | 224 | #endregion 225 | 226 | private static int FindFreePort() 227 | { 228 | var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 229 | try 230 | { 231 | socket.Bind(new IPEndPoint(IPAddress.Any, 0)); 232 | return ((IPEndPoint)socket.LocalEndPoint).Port; 233 | } 234 | finally 235 | { 236 | socket.Close(); 237 | } 238 | } 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /dotnet/src/OpenQA.Selenium.Winium/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /dotnet/src/Settings.StyleCop: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | False 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | False 15 | 16 | 17 | 18 | 19 | False 20 | 21 | 22 | 23 | 24 | False 25 | 26 | 27 | 28 | 29 | False 30 | 31 | 32 | 33 | 34 | False 35 | 36 | 37 | 38 | 39 | False 40 | 41 | 42 | 43 | 44 | False 45 | 46 | 47 | 48 | 49 | False 50 | 51 | 52 | 53 | 54 | False 55 | 56 | 57 | 58 | 59 | False 60 | 61 | 62 | 63 | 64 | False 65 | 66 | 67 | 68 | 69 | False 70 | 71 | 72 | 73 | 74 | False 75 | 76 | 77 | 78 | 79 | False 80 | 81 | 82 | 83 | 84 | False 85 | 86 | 87 | 88 | 89 | False 90 | 91 | 92 | 93 | 94 | False 95 | 96 | 97 | 98 | 99 | False 100 | 101 | 102 | 103 | 104 | False 105 | 106 | 107 | 108 | 109 | False 110 | 111 | 112 | 113 | 114 | False 115 | 116 | 117 | 118 | 119 | False 120 | 121 | 122 | 123 | 124 | False 125 | 126 | 127 | 128 | 129 | False 130 | 131 | 132 | 133 | 134 | False 135 | 136 | 137 | 138 | 139 | False 140 | 141 | 142 | 143 | 144 | False 145 | 146 | 147 | 148 | 149 | False 150 | 151 | 152 | 153 | 154 | False 155 | 156 | 157 | 158 | 159 | False 160 | 161 | 162 | 163 | 164 | False 165 | 166 | 167 | 168 | 169 | False 170 | 171 | 172 | 173 | 174 | False 175 | 176 | 177 | 178 | 179 | False 180 | 181 | 182 | 183 | 184 | False 185 | 186 | 187 | 188 | 189 | False 190 | 191 | 192 | 193 | 194 | False 195 | 196 | 197 | 198 | 199 | False 200 | 201 | 202 | 203 | 204 | False 205 | 206 | 207 | 208 | 209 | False 210 | 211 | 212 | 213 | 214 | False 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /dotnet/src/Winium.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F3DA72A-A97C-41EB-AB54-5D22125C4CC3}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.targets = .nuget\NuGet.targets 10 | EndProjectSection 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenQA.Selenium.Winium", "OpenQA.Selenium.Winium\OpenQA.Selenium.Winium.csproj", "{C2E62426-F3C3-45D9-A677-EBB9C7468252}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {C2E62426-F3C3-45D9-A677-EBB9C7468252}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {C2E62426-F3C3-45D9-A677-EBB9C7468252}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {C2E62426-F3C3-45D9-A677-EBB9C7468252}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {C2E62426-F3C3-45D9-A677-EBB9C7468252}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /dotnet/src/Winium.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <?xml version="1.0" encoding="utf-16"?><Profile name="StyleCop"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>True</EmbraceInRegion><RegionName>using</RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>True</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>True</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>True</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>True</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Maintainability><SA1119StatementMustNotUseUnnecessaryParenthesis>True</SA1119StatementMustNotUseUnnecessaryParenthesis></StyleCop.Maintainability><StyleCop.Ordering><AlphabeticalUsingDirectives>Alphabetical</AlphabeticalUsingDirectives><ExpandUsingDirectives>FullyQualify</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>True</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>True</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>True</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>True</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>True</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>True</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing></Profile> 3 | StyleCop 4 | StyleCop 5 | True 6 | True 7 | True 8 | True 9 | True 10 | True 11 | True 12 | True 13 | True 14 | NEXT_LINE_SHIFTED_2 15 | 1 16 | 1 17 | 1 18 | 1 19 | 1 20 | NEXT_LINE_SHIFTED_2 21 | SEPARATE 22 | ALWAYS_ADD 23 | ALWAYS_ADD 24 | ALWAYS_ADD 25 | ALWAYS_ADD 26 | ALWAYS_ADD 27 | NEXT_LINE_SHIFTED_2 28 | 1 29 | 1 30 | False 31 | True 32 | public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async 33 | False 34 | False 35 | False 36 | False 37 | True 38 | ALWAYS_USE 39 | ON_SINGLE_LINE 40 | False 41 | True 42 | False 43 | False 44 | True 45 | False 46 | True 47 | True 48 | CHOP_IF_LONG 49 | True 50 | True 51 | CHOP_IF_LONG 52 | CHOP_IF_LONG 53 | <?xml version="1.0" encoding="utf-8"?> 54 | <!-- Last updated 15.05.2012 --> 55 | <Patterns xmlns="urn:shemas-jetbrains-com:member-reordering-patterns"> 56 | 57 | <!-- Do not reorder COM interfaces --> 58 | <Pattern> 59 | <Match> 60 | <And Weight="2000"> 61 | <Kind Is="interface"/> 62 | <Or> 63 | <HasAttribute CLRName="System.Runtime.InteropServices.InterfaceTypeAttribute"/> 64 | <HasAttribute CLRName="System.Runtime.InteropServices.ComImport"/> 65 | </Or> 66 | </And> 67 | </Match> 68 | </Pattern> 69 | 70 | <!-- Do not reorder P/Invoke structs --> 71 | <Pattern> 72 | <Match> 73 | <And Weight="2000"> 74 | <Or> 75 | <Kind Is="struct"/> 76 | <Kind Is="class"/> 77 | </Or> 78 | <HasAttribute CLRName="System.Runtime.InteropServices.StructLayoutAttribute"/> 79 | </And> 80 | </Match> 81 | </Pattern> 82 | 83 | <!-- Do not reorder P/Invoke classes (called xxxNativeMethods) --> 84 | <Pattern> 85 | <Match> 86 | <And Weight="2000"> 87 | <Kind Is="class"/> 88 | <Name Is=".*NativeMethods" /> 89 | </And> 90 | </Match> 91 | </Pattern> 92 | 93 | <!-- StyleCop pattern --> 94 | <Pattern RemoveAllRegions="true"> 95 | <Match> 96 | <Or Weight="1000" > 97 | <Kind Is="class" /> 98 | <Kind Is="struct" /> 99 | <Kind Is="interface"/> 100 | </Or> 101 | </Match> 102 | 103 | <!-- Constants --> 104 | <Entry> 105 | <Match> 106 | <Kind Is="constant"/> 107 | </Match> 108 | <Sort> 109 | <Access Order="public internal protected-internal protected private"/> 110 | <Name/> 111 | </Sort> 112 | <Group Region="Constants"/> 113 | </Entry> 114 | 115 | <!-- Static fields --> 116 | <Entry> 117 | <Match> 118 | <And> 119 | <Kind Is="field"/> 120 | <Static /> 121 | </And> 122 | </Match> 123 | <Sort> 124 | <Access Order="public internal protected-internal protected private"/> 125 | <Readonly/> 126 | <Name/> 127 | </Sort> 128 | <Group Region="Static Fields"/> 129 | </Entry> 130 | 131 | <!-- Fields --> 132 | <Entry> 133 | <Match> 134 | <Kind Is="field"/> 135 | </Match> 136 | <Sort> 137 | <Access Order="public internal protected-internal protected private"/> 138 | <Readonly/> 139 | <Name/> 140 | </Sort> 141 | <Group Region="Fields"/> 142 | </Entry> 143 | 144 | <!-- constructors and destructors --> 145 | <Entry> 146 | <Match> 147 | <Or Weight="200"> 148 | <Kind Is="constructor"/> 149 | <Kind Is="destructor"/> 150 | </Or> 151 | </Match> 152 | <Sort> 153 | <Static/> 154 | <Kind Order="constructor destructor"/> 155 | <Access Order="public internal protected-internal protected private"/> 156 | </Sort> 157 | <Group Region="Constructors and Destructors"/> 158 | </Entry> 159 | 160 | <!-- delegates --> 161 | <Entry> 162 | <Match> 163 | <Kind Is="delegate"/> 164 | </Match> 165 | <Sort> 166 | <Access Order="public internal protected-internal protected private" /> 167 | <Static /> 168 | <Name/> 169 | </Sort> 170 | <Group Region="Delegates"/> 171 | </Entry> 172 | 173 | <!-- public events --> 174 | <Entry> 175 | <Match> 176 | <And> 177 | <Kind Is="event"/> 178 | <Access Is="public"/> 179 | </And> 180 | </Match> 181 | <Sort> 182 | <Access Order="public" /> 183 | <Static /> 184 | <Name/> 185 | </Sort> 186 | <Group Region="Public Events"/> 187 | </Entry> 188 | 189 | <!-- interface events --> 190 | <Entry> 191 | <Match> 192 | <And> 193 | <Kind Is="event"/> 194 | <ImplementsInterface/> 195 | </And> 196 | </Match> 197 | <Sort> 198 | <ImplementsInterface Immediate="true"/> 199 | <Name/> 200 | </Sort> 201 | <Group Region="Explicit Interface Events" /> 202 | </Entry> 203 | 204 | <!-- other events --> 205 | <Entry> 206 | <Match> 207 | <Kind Is="event"/> 208 | </Match> 209 | <Sort> 210 | <Access Order="public internal protected-internal protected private" /> 211 | <Static /> 212 | <Name/> 213 | </Sort> 214 | <Group Region="Events"/> 215 | </Entry> 216 | 217 | <!-- enum --> 218 | <Entry> 219 | <Match> 220 | <Kind Is="enum"/> 221 | </Match> 222 | <Sort> 223 | <Access Order="public internal protected-internal protected private" /> 224 | <Name/> 225 | </Sort> 226 | <Group Region="Enums"/> 227 | </Entry> 228 | 229 | <!-- interfaces --> 230 | <Entry> 231 | <Match> 232 | <Kind Is="interface" /> 233 | </Match> 234 | <Sort> 235 | <Access Order="public internal protected-internal protected private" /> 236 | <Name/> 237 | </Sort> 238 | <Group Region="Interfaces"/> 239 | </Entry> 240 | 241 | <!-- public properties --> 242 | <Entry> 243 | <Match> 244 | <And> 245 | <Kind Is="property"/> 246 | <Access Is="public"/> 247 | </And> 248 | </Match> 249 | <Sort> 250 | <Access Order="public"/> 251 | <Static/> 252 | <Name/> 253 | </Sort> 254 | <Group Region="Public Properties"/> 255 | </Entry> 256 | 257 | <!-- interface properties --> 258 | <Entry> 259 | <Match> 260 | <And> 261 | <Kind Is="property"/> 262 | <ImplementsInterface/> 263 | </And> 264 | </Match> 265 | <Sort> 266 | <ImplementsInterface Immediate="true"/> 267 | <Name/> 268 | </Sort> 269 | <Group Region="Explicit Interface Properties" /> 270 | </Entry> 271 | 272 | <!-- other properties --> 273 | <Entry> 274 | <Match> 275 | <Kind Is="property"/> 276 | </Match> 277 | <Sort> 278 | <Access Order="public internal protected-internal protected private"/> 279 | <Static/> 280 | <Name/> 281 | </Sort> 282 | <Group Region="Properties"/> 283 | </Entry> 284 | 285 | <!-- public indexers --> 286 | <Entry> 287 | <Match> 288 | <And> 289 | <Kind Is="indexer" Weight="1000" /> 290 | <Access Is="public"/> 291 | </And> 292 | </Match> 293 | <Sort> 294 | <Access Order="public" /> 295 | <Static/> 296 | <Name/> 297 | </Sort> 298 | <Group Region="Public Indexers"/> 299 | </Entry> 300 | 301 | <!-- interface indexers --> 302 | <Entry> 303 | <Match> 304 | <And> 305 | <Kind Is="indexer" Weight="1000"/> 306 | <ImplementsInterface/> 307 | </And> 308 | </Match> 309 | <Sort> 310 | <ImplementsInterface Immediate="true"/> 311 | <Name/> 312 | </Sort> 313 | <Group Region="Explicit Interface Indexers" /> 314 | </Entry> 315 | 316 | <!-- other indexers --> 317 | <Entry> 318 | <Match> 319 | <Kind Is="indexer" Weight="1000" /> 320 | </Match> 321 | <Sort> 322 | <Access Order="public internal protected-internal protected private" /> 323 | <Static/> 324 | <Name/> 325 | </Sort> 326 | <Group Region="Indexers"/> 327 | </Entry> 328 | 329 | <!-- public methods (includes operators) --> 330 | <Entry> 331 | <Match> 332 | <And> 333 | <Or> 334 | <Kind Is="method"/> 335 | <Kind Is="operator"/> 336 | </Or> 337 | <Access Is="public"/> 338 | </And> 339 | </Match> 340 | <Sort> 341 | <Access Order="public"/> 342 | <Static/> 343 | <Name/> 344 | </Sort> 345 | <Group Region="Public Methods and Operators"/> 346 | </Entry> 347 | 348 | <!-- interface methods --> 349 | <Entry> 350 | <Match> 351 | <And> 352 | <Kind Is="method"/> 353 | <ImplementsInterface/> 354 | </And> 355 | </Match> 356 | <Sort> 357 | <ImplementsInterface Immediate="true"/> 358 | <Name/> 359 | </Sort> 360 | <Group Region="Explicit Interface Methods" /> 361 | </Entry> 362 | 363 | <!-- other methods --> 364 | <Entry> 365 | <Match> 366 | <Kind Is="method"/> 367 | </Match> 368 | <Sort> 369 | <Access Order="public internal protected-internal protected private"/> 370 | <Static/> 371 | <Name/> 372 | </Sort> 373 | <Group Region="Methods"/> 374 | </Entry> 375 | 376 | <!-- operators --> 377 | <Entry> 378 | <Match> 379 | <Kind Is="operator"/> 380 | </Match> 381 | <Sort> 382 | <Access Order="public internal protected-internal protected private" /> 383 | <Static/> 384 | <Name/> 385 | </Sort> 386 | <Group Region="Operators"/> 387 | </Entry> 388 | 389 | <!-- Nested structs --> 390 | <Entry> 391 | <Match> 392 | <Kind Is="struct" 393 | Weight="600" /> 394 | </Match> 395 | <Sort> 396 | <Static /> 397 | <Access Order="public internal protected-internal protected private" /> 398 | <Name/> 399 | </Sort> 400 | </Entry> 401 | 402 | <!-- Nested classes --> 403 | <Entry> 404 | <Match> 405 | <Kind Is="class" 406 | Weight="700" /> 407 | </Match> 408 | <Sort> 409 | <Static /> 410 | <Access Order="public internal protected-internal protected private" /> 411 | <Name/> 412 | </Sort> 413 | </Entry> 414 | 415 | <!-- all other members --> 416 | <Entry/> 417 | 418 | </Pattern> 419 | </Patterns> 420 | CustomLayout 421 | True 422 | True 423 | $object$_On$event$ 424 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 425 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 426 | <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> 427 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 428 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 429 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 430 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 431 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 432 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 433 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 434 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 435 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 436 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 437 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 438 | <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> 439 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 440 | True 441 | True 442 | CSharpOtherPage 443 | OverriddenFalse 444 | OverriddenFalse -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target 4 | -------------------------------------------------------------------------------- /java/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | 4 | 5 | ## v0.1.0-1 6 | 7 | - WebDriver Java bindings for Winium 8 | - Exposes the service provided by the native WiniumDriver executable 9 | -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | # Winium.WebDriver for Java 2 | 3 | [![GitHub license](https://img.shields.io/badge/license-MPL 2.0-blue.svg?style=flat-square)](../LICENSE) 4 | 5 |

6 | Winium.WebDriver is an extension of [WebDriver Java bindings](http://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver). 7 |

8 | 9 | This is an extension of [WebDriver Java bindings](http://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver). 10 | Provides a mechanism to write tests using [Winium.Desktop](https://github.com/2gis/Winium.Desktop), [Winium.StoreApps](https://github.com/2gis/Winium.StioreApps) or [winphonedriver](https://github.com/2gis/winphonedriver). 11 | 12 | Winium.WebDriver retains the functionality of common driver and has specific methods for interaction with the Winium Driver. 13 | 14 | 15 | ## Quick Start 16 | 1. Add reference to `winium-web-driver` to your pom.xml file: 17 | 18 | ```xml 19 | 20 | 21 | com.github.2gis.winium 22 | winium-webdriver 23 | 0.1.0-1 24 | 25 | 26 | ``` 27 | 2. Initialize an instance of specific for Desktop, StoreApps, Silverlight Options class. 28 | 29 | [DesktopOptions] for example: 30 | ```java 31 | DesktopOptions options = DesktopOptions(); 32 | options.setApplicationPath("C:\\Windows\\System32\\notepad.exe"); 33 | ``` 34 | 3. Create the instance of the [WebDriver] class. 35 | 36 | Use default constructor: 37 | ```java 38 | WiniumDriver driver = new WiniumDriver(options); 39 | ``` 40 | Use the native WiniumDriver executable: 41 | ```java 42 | WiniumDriverService service = new WiniumDriverService.Builder() 43 | .usingDriverExecutable("path_to_driver_executable") 44 | .usingAnyFreePort() 45 | .withVerbose(true) 46 | .withSilent(false); 47 | .buildDesktopService(); 48 | 49 | WiniumDriver driver = new WiniumDriver(service, options); 50 | ``` 51 | 52 | ## Contributing 53 | 54 | Contributions are welcome! 55 | 56 | 1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. 57 | 2. Fork the repository to start making your changes to the master branch (or branch off of it). 58 | 3. We recommend to write a test which shows that the bug was fixed or that the feature works as expected. 59 | 4. Send a pull request and bug the maintainer until it gets merged and published. :smiley: 60 | 61 | ## Contact 62 | 63 | Have some questions? Found a bug? Create [new issue](https://github.com/2gis/Winium/issues/new) or contact us at zebraxxl@mail.ru 64 | 65 | ## License 66 | 67 | Winium is released under the MPL 2.0 license. See [LICENSE](../LICENSE) for details. 68 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.2gis.winium 8 | winium-webdriver 9 | 0.1.0-1 10 | 11 | Winium.WebDriver 12 | https://github.com/2gis/Winium/tree/master/java 13 | Winium.WebDriver retains the functionality of common driver and has specific methods for 14 | interaction with the Winium Driver. 15 | 16 | 17 | Mozilla Public License, version 2.0 18 | https://www.mozilla.org/en-US/MPL/2.0/ 19 | 20 | 21 | 22 | https://github.com/2gis/Winium/ 23 | 24 | 25 | 26 | Artem Pryanichnikov 27 | https://github.com/zebraxxl 28 | 29 | 30 | 31 | 32 | UTF-8 33 | 34 | 35 | 36 | 37 | ossrh 38 | https://oss.sonatype.org/content/repositories/snapshots 39 | 40 | 41 | 42 | 43 | 44 | org.seleniumhq.selenium 45 | selenium-java 46 | 2.48.2 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-compiler-plugin 55 | 3.3 56 | 57 | 1.6 58 | 1.6 59 | 60 | 61 | 62 | org.apache.maven.plugins 63 | maven-source-plugin 64 | 2.2.1 65 | 66 | 67 | attach-sources 68 | 69 | jar-no-fork 70 | 71 | 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-javadoc-plugin 77 | 2.9.1 78 | 79 | 80 | attach-javadocs 81 | 82 | jar 83 | 84 | 85 | 86 | 87 | 88 | org.apache.maven.plugins 89 | maven-gpg-plugin 90 | 1.5 91 | 92 | 93 | sign-artifacts 94 | verify 95 | 96 | sign 97 | 98 | 99 | 100 | 101 | 102 | org.sonatype.plugins 103 | nexus-staging-maven-plugin 104 | 1.6.3 105 | true 106 | 107 | ossrh 108 | https://oss.sonatype.org/ 109 | true 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /java/scripts/ci.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | $mvnPath = '' 6 | if (Get-Command 'mvn' -ErrorAction SilentlyContinue) 7 | { 8 | $mvnPath = 'mvn' 9 | } 10 | else 11 | { 12 | Write-Output 'Unable to find mvn in your PATH' 13 | Exit 1 14 | } 15 | 16 | $projectDir = Join-Path $PSScriptRoot "../" 17 | 18 | # Compile 19 | & $mvnPath -f $projectDir compile 20 | if ($LASTEXITCODE -ne 0) 21 | { 22 | Write-Output "Compile failed. See output" 23 | Exit $LASTEXITCODE 24 | } 25 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/DesktopOptions.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import org.openqa.selenium.Capabilities; 4 | import org.openqa.selenium.remote.DesiredCapabilities; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * Class to manage options specific to {@link WiniumDriver} 10 | * which uses Winium.Desktop 11 | */ 12 | public class DesktopOptions implements WiniumOptions { 13 | private static final String APPLICATION_PATH_OPTION = "app"; 14 | private static final String ARGUMENTS_OPTION = "args"; 15 | private static final String DEBUG_CONNECT_TO_RUNNING_APP_OPTION = "debugConnectToRunningApp"; 16 | private static final String KEYBOARD_SIMULATOR_OPTION = "keyboardSimulator"; 17 | private static final String LAUNCH_DELAY_OPTION = "launchDelay"; 18 | 19 | private String applicationPath; 20 | private String arguments; 21 | private Boolean debugConnectToRunningApp; 22 | private KeyboardSimulatorType keyboardSimulator; 23 | private Integer launchDelay; 24 | 25 | /** 26 | * Sets the absolute local path to an .exe file to be started. 27 | * This capability is not required if debugConnectToRunningApp is specified. 28 | * @param applicationPath Absolute local path to an .exe file to be started. 29 | */ 30 | public void setApplicationPath(String applicationPath) { 31 | this.applicationPath = applicationPath; 32 | } 33 | 34 | /** 35 | * Sets startup argunments of the application under test. 36 | * @param arguments Startup argunments of the application under test. 37 | */ 38 | public void setArguments(String arguments) { 39 | this.arguments = arguments; 40 | } 41 | 42 | /** 43 | * Sets a value indicating whether debug connect to running app. 44 | * If true, then application starting step are skipped. 45 | * @param debugConnectToRunningApp Value indicating whether debug connect to running app. 46 | */ 47 | public void setDebugConnectToRunningApp(Boolean debugConnectToRunningApp) { 48 | this.debugConnectToRunningApp = debugConnectToRunningApp; 49 | } 50 | 51 | /** 52 | * Sets the keyboard simulator type. 53 | * @param keyboardSimulator Keyboard simulator type 54 | */ 55 | public void setKeyboardSimulator(KeyboardSimulatorType keyboardSimulator) { 56 | this.keyboardSimulator = keyboardSimulator; 57 | } 58 | 59 | /** 60 | * Sets the launch delay in milliseconds, to be waited to let visuals to initialize after application started. 61 | * @param launchDelay Launch delay in milliseconds 62 | */ 63 | public void setLaunchDelay(Integer launchDelay) { 64 | this.launchDelay = launchDelay; 65 | } 66 | 67 | /** 68 | * Convert options to DesiredCapabilities for Winium Desktop Driver 69 | * @return The DesiredCapabilities for Winium Desktop Driver with these options. 70 | */ 71 | public Capabilities toCapabilities() { 72 | HashMap capabilityDictionary = new HashMap(); 73 | capabilityDictionary.put(APPLICATION_PATH_OPTION, applicationPath); 74 | 75 | if ((arguments != null) && (arguments.length() > 0)) { 76 | capabilityDictionary.put(ARGUMENTS_OPTION, arguments); 77 | } 78 | 79 | if (debugConnectToRunningApp != null) { 80 | capabilityDictionary.put(DEBUG_CONNECT_TO_RUNNING_APP_OPTION, debugConnectToRunningApp); 81 | } 82 | 83 | if (keyboardSimulator != null) { 84 | capabilityDictionary.put(KEYBOARD_SIMULATOR_OPTION, keyboardSimulator); 85 | } 86 | 87 | if (launchDelay != null) { 88 | capabilityDictionary.put(LAUNCH_DELAY_OPTION, launchDelay); 89 | } 90 | 91 | return new DesiredCapabilities(capabilityDictionary); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/KeyboardSimulatorType.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | /** 4 | * The keyboard simulator type. 5 | */ 6 | public enum KeyboardSimulatorType { 7 | /** 8 | * Based on SendKeys Class. 9 | * See more 10 | */ 11 | BasedOnWindowsFormsSendKeysClass, 12 | 13 | /** 14 | * Based on Windows Input Simulator. 15 | * For additional methods should be cast to the KeyboardSimulatorExt. 16 | * See more 17 | */ 18 | BasedOnInputSimulatorLib 19 | } 20 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/SilverlightOptions.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import org.openqa.selenium.Capabilities; 4 | import org.openqa.selenium.remote.DesiredCapabilities; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * Class to manage options specific to {@link WiniumDriver} 10 | * which uses Windows Phone Driver 11 | */ 12 | public class SilverlightOptions implements WiniumOptions { 13 | private static final String APPLICATION_PATH_OPTION = "app"; 14 | private static final String DEBUG_CONNECT_TO_RUNNING_APP_OPTION = "debugConnectToRunningApp"; 15 | private static final String DEVICE_NAME_OPTION = "deviceName"; 16 | private static final String INNER_PORT_OPTION = "innerPort"; 17 | private static final String LAUNCH_DELAY_OPTION = "launchDelay"; 18 | private static final String LAUNCH_TIMEOUT_OPTION = "launchTimeout"; 19 | 20 | private String applicationPath; 21 | private Boolean debugConnectToRunningApp; 22 | private String deviceName; 23 | private Integer innerPort; 24 | private Integer launchDelay; 25 | private Integer launchTimeout; 26 | 27 | /** 28 | * Sets the absolute local path to an .xap file to be installed and launched. 29 | * This capability is not required if debugConnectToRunningApp is specified. 30 | * @param applicationPath Absolute local path to an .xap file to be installed and launched. 31 | */ 32 | public void setApplicationPath(String applicationPath) { 33 | this.applicationPath = applicationPath; 34 | } 35 | 36 | /** 37 | * Sets a value indicating whether debug connect to running app. 38 | * If true, then application starting step are skipped. 39 | * @param debugConnectToRunningApp Value indicating whether debug connect to running app. 40 | */ 41 | public void setDebugConnectToRunningApp(Boolean debugConnectToRunningApp) { 42 | this.debugConnectToRunningApp = debugConnectToRunningApp; 43 | } 44 | 45 | /** 46 | * Sets name of emulator to use for running test. 47 | * Note that this capability is not required, if no device name is specified, 48 | * then a default emulator is used. You can specify only partial name, 49 | * first emulator that starts with specified deviceName will be selected. 50 | * @param deviceName Name of emulator to use for running test. 51 | */ 52 | public void setDeviceName(String deviceName) { 53 | this.deviceName = deviceName; 54 | } 55 | 56 | /** 57 | * Sets the inner port used to communicate between OuterDriver and InnerDrive (injected into Windows Phone app). 58 | * Required only if non-default port was specified in tested app in AutomationServer.Instance.InitializeAndStart call. 59 | * @param innerPort The inner port used to communicate between OuterDriver and InnerDrive 60 | */ 61 | public void setInnerPort(Integer innerPort) { 62 | this.innerPort = innerPort; 63 | } 64 | 65 | /** 66 | * Sets launch delay in milliseconds, to be waited to let visuals to initialize 67 | * after application launched (after successful ping or timeout). 68 | * Use it if the system running emulator is slow. 69 | * @param launchDelay Launch delay in milliseconds 70 | */ 71 | public void setLaunchDelay(Integer launchDelay) { 72 | this.launchDelay = launchDelay; 73 | } 74 | 75 | /** 76 | * Sets maximum timeout in milliseconds, to be waited for application to launch 77 | * @param launchTimeout Maximum timeout in milliseconds, to be waited for application to launch 78 | */ 79 | public void setLaunchTimeout(Integer launchTimeout) { 80 | this.launchTimeout = launchTimeout; 81 | } 82 | 83 | @Override 84 | public Capabilities toCapabilities() { 85 | HashMap capabilityDictionary = new HashMap(); 86 | capabilityDictionary.put(APPLICATION_PATH_OPTION, applicationPath); 87 | 88 | if (debugConnectToRunningApp != null) { 89 | capabilityDictionary.put(DEBUG_CONNECT_TO_RUNNING_APP_OPTION, debugConnectToRunningApp); 90 | } 91 | 92 | if ((deviceName != null) && (deviceName.length() > 0)) { 93 | capabilityDictionary.put(DEVICE_NAME_OPTION, deviceName); 94 | } 95 | 96 | if (launchTimeout != null) { 97 | capabilityDictionary.put(LAUNCH_TIMEOUT_OPTION, launchTimeout); 98 | } 99 | 100 | if (launchDelay != null) { 101 | capabilityDictionary.put(LAUNCH_DELAY_OPTION, launchDelay); 102 | } 103 | 104 | if (innerPort != null) { 105 | capabilityDictionary.put(INNER_PORT_OPTION, innerPort); 106 | } 107 | 108 | return new DesiredCapabilities(capabilityDictionary); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/StoreAppsOptions.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import org.openqa.selenium.Capabilities; 4 | import org.openqa.selenium.remote.DesiredCapabilities; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * Class to manage options specific to {@link WiniumDriver} 12 | * wich uses Winium.StoreApps 13 | */ 14 | public class StoreAppsOptions implements WiniumOptions { 15 | private static final String APPLICATION_PATH_OPTION = "app"; 16 | private static final String DEBUG_CONNECT_TO_RUNNING_APP_OPTION = "debugConnectToRunningApp"; 17 | private static final String DEPENDENCIES_OPTION = "dependencies"; 18 | private static final String DEVICE_NAME_OPTION = "deviceName"; 19 | private static final String FILES_OPTION = "files"; 20 | private static final String LAUNCH_DELAY_OPTION = "launchDelay"; 21 | private static final String LAUNCH_TIMEOUT_OPTION = "launchTimeout"; 22 | 23 | private String applicationPath; 24 | private Boolean debugConnectToRunningApp; 25 | private List dependencies; 26 | private String deviceName; 27 | private Map files; 28 | private Integer launchDelay; 29 | private Integer launchTimeout; 30 | 31 | /** 32 | * Sets the absolute local path to an .appx file to be installed and launched. 33 | * This capability is not required if debugConnectToRunningApp is specified. 34 | * @param applicationPath Absolute local path to an .xap file to be installed and launched. 35 | */ 36 | public void setApplicationPath(String applicationPath) { 37 | this.applicationPath = applicationPath; 38 | } 39 | 40 | /** 41 | * Sets a value indicating whether debug connect to running app. 42 | * If true, then application starting step are skipped. 43 | * @param debugConnectToRunningApp Value indicating whether debug connect to running app. 44 | */ 45 | public void setDebugConnectToRunningApp(Boolean debugConnectToRunningApp) { 46 | this.debugConnectToRunningApp = debugConnectToRunningApp; 47 | } 48 | 49 | /** 50 | * Sets a list of dependencies. 51 | * @param dependencies List of dependencies. 52 | */ 53 | public void setDependencies(List dependencies) { 54 | this.dependencies = dependencies; 55 | } 56 | 57 | /** 58 | * Sets name of emulator to use for running test. 59 | * Note that this capability is not required, if no device name is specified, 60 | * then a default emulator is used. You can specify only partial name, 61 | * first emulator that starts with specified deviceName will be selected. 62 | * @param deviceName Name of emulator to use for running test. 63 | */ 64 | public void setDeviceName(String deviceName) { 65 | this.deviceName = deviceName; 66 | } 67 | 68 | /** 69 | * Sets the files. 70 | * Each key of the map is "local file path", each corresponding value is "remote file path" 71 | * @param files files map 72 | */ 73 | public void setFiles(Map files) { 74 | this.files = files; 75 | } 76 | 77 | /** 78 | * Sets launch delay in milliseconds, to be waited to let visuals to initialize 79 | * after application launched (after successful ping or timeout). 80 | * Use it if the system running emulator is slow. 81 | * @param launchDelay Launch delay in milliseconds 82 | */ 83 | public void setLaunchDelay(Integer launchDelay) { 84 | this.launchDelay = launchDelay; 85 | } 86 | 87 | /** 88 | * Sets maximum timeout in milliseconds, to be waited for application to launch 89 | * @param launchTimeout Maximum timeout in milliseconds, to be waited for application to launch 90 | */ 91 | public void setLaunchTimeout(Integer launchTimeout) { 92 | this.launchTimeout = launchTimeout; 93 | } 94 | 95 | @Override 96 | public Capabilities toCapabilities() { 97 | HashMap capabilityDictionary = new HashMap(); 98 | capabilityDictionary.put(APPLICATION_PATH_OPTION, applicationPath); 99 | 100 | if (files != null && files.size() > 0) { 101 | capabilityDictionary.put(FILES_OPTION, files); 102 | } 103 | 104 | if (debugConnectToRunningApp != null) { 105 | capabilityDictionary.put(DEBUG_CONNECT_TO_RUNNING_APP_OPTION, debugConnectToRunningApp); 106 | } 107 | 108 | if ((deviceName != null) && (deviceName.length() > 0)) { 109 | capabilityDictionary.put(DEVICE_NAME_OPTION, deviceName); 110 | } 111 | 112 | if (launchTimeout != null) { 113 | capabilityDictionary.put(LAUNCH_TIMEOUT_OPTION, launchTimeout); 114 | } 115 | 116 | if (launchDelay != null) { 117 | capabilityDictionary.put(LAUNCH_DELAY_OPTION, launchDelay); 118 | } 119 | 120 | if (dependencies != null && dependencies.size() > 0) { 121 | capabilityDictionary.put(DEPENDENCIES_OPTION, dependencies); 122 | } 123 | 124 | return new DesiredCapabilities(capabilityDictionary); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/WiniumDriver.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import org.openqa.selenium.remote.RemoteWebDriver; 4 | 5 | import java.net.URL; 6 | 7 | /** 8 | * Provides a mechanism to write tests using Winium driver. 9 | * For example:
{@code
 10 |  * import static org.junit.Assert.assertEquals;
 11 |  *
 12 |  * import org.junit.*;
 13 |  * import org.junit.runner.RunWith;
 14 |  * import org.junit.runners.JUnit4;
 15 |  * import org.openqa.selenium.winium.WiniumDriver;
 16 |  * import org.openqa.selenium.winium.WiniumDriverService;
 17 |  * import org.openqa.selenium.winium.DesktopOptions;
 18 |  *
 19 |  * {@literal @RunWith(JUnit4.class)}
 20 |  * public class WiniumTest extends TestCase {
 21 |  *     private static WiniumDriverService service;
 22 |  *     private WebDriver driver;
 23 |  *
 24 |  *     {@literal @BeforeClass}
 25 |  *     public static void createAndStartService() {
 26 |  *         service = new WiniumDriverService.Builder()
 27 |  *             .usingAnyFreePort()
 28 |  *             .buildDesktopService();
 29 |  *         service.start();
 30 |  *     }
 31 |  *
 32 |  *     {@literal @AfterClass}
 33 |  *     public static void createAndStopService() {
 34 |  *         service.stop();
 35 |  *     }
 36 |  *
 37 |  *     {@literal @Before}
 38 |  *     public void createDriver() {
 39 |  *         DesktopOptions options = DesktopOptions();
 40 |  *         options.setApplicationPath("C:\\Windows\\System32\\notepad.exe");
 41 |  *
 42 |  *         driver = new WiniumDriver(service, options);
 43 |  *     }
 44 |  *
 45 |  *     {@literal @After}
 46 |  *     public void quitDriver() {
 47 |  *         driver.quit();
 48 |  *     }
 49 |  *
 50 |  *     {@literal @Test}
 51 |  *     public void testSomething() {
 52 |  *         // Rest of test
 53 |  *     }
 54 |  * }
 55 |  * }
56 | */ 57 | public class WiniumDriver extends RemoteWebDriver { 58 | 59 | /** 60 | * Initializes a new instance of the {@link WiniumDriver} class using the specified options 61 | * @param options Thre {@link WiniumOptions} to be used with the Winium driver. 62 | */ 63 | public WiniumDriver(WiniumOptions options) { 64 | this(createDefaultService(options.getClass()), options); 65 | } 66 | 67 | /** 68 | * Initializes a new instance of the {@link WiniumDriver} class using the specified {@link WiniumDriverService} 69 | * and options. 70 | * 71 | * @param service The {@link WiniumDriverService} to use. 72 | * @param options The {@link WiniumOptions} used to initialize the driver. 73 | */ 74 | public WiniumDriver(WiniumDriverService service, WiniumOptions options) { 75 | super(new WiniumDriverCommandExecutor(service), options.toCapabilities()); 76 | } 77 | 78 | /** 79 | * Initializes a new instance of the {@link WiniumDriver} lass using the specified remote address and options. 80 | * @param remoteAddress URL containing the address of the WiniumDriver remote server (e.g. http://127.0.0.1:4444/wd/hub). 81 | * @param options The {@link WiniumOptions} object to be used with the Winium driver. 82 | */ 83 | public WiniumDriver(URL remoteAddress, WiniumOptions options) { 84 | super(new WiniumDriverCommandExecutor(remoteAddress), options.toCapabilities()); 85 | } 86 | 87 | private static WiniumDriverService createDefaultService(Class optionsType) { 88 | if (optionsType == DesktopOptions.class) { 89 | return WiniumDriverService.createDesktopService(); 90 | } else if (optionsType == StoreAppsOptions.class) { 91 | return WiniumDriverService.createStoreAppsService(); 92 | } else if (optionsType == SilverlightOptions.class) { 93 | return WiniumDriverService.createSilverlightService(); 94 | } 95 | 96 | throw new IllegalArgumentException( 97 | "Option type must be type of DesktopOptions, StoreAppsOptions or SilverlightOptions"); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/WiniumDriverCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import com.google.common.base.Throwables; 4 | import org.openqa.selenium.WebDriverException; 5 | import org.openqa.selenium.remote.*; 6 | import org.openqa.selenium.remote.http.HttpMethod; 7 | import org.openqa.selenium.remote.service.DriverCommandExecutor; 8 | 9 | import java.io.IOException; 10 | import java.net.ConnectException; 11 | import java.net.URL; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | 16 | /** 17 | * {@link DriverCommandExecutor} that understands WiniumDriver specific commands. 18 | */ 19 | public class WiniumDriverCommandExecutor extends HttpCommandExecutor { 20 | private static final Map WINIUM_COMMAND_NAME_TO_URL; 21 | 22 | private final WiniumDriverService service; 23 | 24 | static { 25 | WINIUM_COMMAND_NAME_TO_URL = new HashMap(); 26 | 27 | WINIUM_COMMAND_NAME_TO_URL.put("findDataGridCell", 28 | new CommandInfo("/session/:sessionId/element/:id/datagrid/cell/:row/:column", HttpMethod.POST)); 29 | WINIUM_COMMAND_NAME_TO_URL.put("getDataGridColumnCount", 30 | new CommandInfo("/session/:sessionId/element/:id/datagrid/column/count", HttpMethod.POST)); 31 | WINIUM_COMMAND_NAME_TO_URL.put("getDataGridRowCount", 32 | new CommandInfo("/session/:sessionId/element/:id/datagrid/row/count", HttpMethod.POST)); 33 | WINIUM_COMMAND_NAME_TO_URL.put("scrollToDataGridCell", 34 | new CommandInfo("/session/:sessionId/element/:id/datagrid/scroll/:row/:column", HttpMethod.POST)); 35 | WINIUM_COMMAND_NAME_TO_URL.put("selectDataGridCell", 36 | new CommandInfo("/session/:sessionId/element/:id/datagrid/select/:row/:column", HttpMethod.POST)); 37 | 38 | WINIUM_COMMAND_NAME_TO_URL.put("scrollToListBoxItem", 39 | new CommandInfo("/session/:sessionId/element/:id/listbox/scroll", HttpMethod.POST)); 40 | 41 | WINIUM_COMMAND_NAME_TO_URL.put("findMenuItem", 42 | new CommandInfo("/session/:sessionId/element/:id/menu/item/:path", HttpMethod.POST)); 43 | WINIUM_COMMAND_NAME_TO_URL.put("selectMenuItem", 44 | new CommandInfo("/session/:sessionId/element/:id/menu/select/:path", HttpMethod.POST)); 45 | 46 | WINIUM_COMMAND_NAME_TO_URL.put("isComboBoxExpanded", 47 | new CommandInfo("/session/:sessionId/element/:id/combobox/expanded", HttpMethod.POST)); 48 | WINIUM_COMMAND_NAME_TO_URL.put("expandComboBox", 49 | new CommandInfo("/session/:sessionId/element/:id/combobox/expand", HttpMethod.POST)); 50 | WINIUM_COMMAND_NAME_TO_URL.put("collapseComboBox", 51 | new CommandInfo("/session/:sessionId/element/:id/combobox/collapse", HttpMethod.POST)); 52 | WINIUM_COMMAND_NAME_TO_URL.put("findComboBoxSelectedItem", 53 | new CommandInfo("/session/:sessionId/element/:id/combobox/items/selected", HttpMethod.POST)); 54 | WINIUM_COMMAND_NAME_TO_URL.put("scrollToComboBoxItem", 55 | new CommandInfo("/session/:sessionId/element/:id/combobox/scroll", HttpMethod.POST)); 56 | } 57 | 58 | public WiniumDriverCommandExecutor(WiniumDriverService driverService) { 59 | super(WINIUM_COMMAND_NAME_TO_URL, driverService.getUrl()); 60 | service = driverService; 61 | } 62 | 63 | public WiniumDriverCommandExecutor(URL remoteUrl) { 64 | super(WINIUM_COMMAND_NAME_TO_URL, remoteUrl); 65 | service = null; 66 | } 67 | 68 | @Override 69 | public Response execute(Command command) throws IOException { 70 | if (service != null) { 71 | if (DriverCommand.NEW_SESSION.equals(command.getName())) { 72 | service.start(); 73 | } 74 | } 75 | 76 | 77 | try { 78 | return super.execute(command); 79 | } catch (Throwable t) { 80 | Throwable rootCause = Throwables.getRootCause(t); 81 | if (rootCause instanceof ConnectException && "Connection refused".equals(rootCause.getMessage()) && 82 | ((service == null) || (!service.isRunning()))) { 83 | throw new WebDriverException("The driver server has unexpectedly died!", t); 84 | } 85 | Throwables.propagateIfPossible(t); 86 | throw new WebDriverException(t); 87 | } finally { 88 | if ((service != null) && (DriverCommand.QUIT.equals(command.getName()))) { 89 | service.stop(); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/WiniumDriverService.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import org.openqa.selenium.Beta; 6 | import org.openqa.selenium.WebDriverException; 7 | import org.openqa.selenium.net.PortProber; 8 | import org.openqa.selenium.remote.service.DriverService; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.util.Map; 13 | 14 | import static com.google.common.base.Preconditions.checkNotNull; 15 | 16 | /** 17 | * Exposes the service provided by the native Winium Driver executable. 18 | *
{@code
 19 |  * import static org.junit.Assert.assertEquals;
 20 |  *
 21 |  * import org.junit.*;
 22 |  * import org.junit.runner.RunWith;
 23 |  * import org.junit.runners.JUnit4;
 24 |  * import org.openqa.selenium.winium.WiniumDriver;
 25 |  * import org.openqa.selenium.winium.WiniumDriverService;
 26 |  * import org.openqa.selenium.winium.DesktopOptions;
 27 |  *
 28 |  * {@literal @RunWith(JUnit4.class)}
 29 |  * public class WiniumTest extends TestCase {
 30 |  *     private static WiniumDriverService service;
 31 |  *     private WebDriver driver;
 32 |  *
 33 |  *     {@literal @BeforeClass}
 34 |  *     public static void createAndStartService() {
 35 |  *         service = new WiniumDriverService.Builder()
 36 |  *             .usingDriverExecutable("path_to_driver_executable")
 37 |  *             .usingAnyFreePort()
 38 |  *             .withVerbose(true)
 39 |  *             .withSilent(false);
 40 |  *             .buildDesktopService();
 41 |  *         service.start();
 42 |  *     }
 43 |  *
 44 |  *     {@literal @AfterClass}
 45 |  *     public static void createAndStopService() {
 46 |  *         service.stop();
 47 |  *     }
 48 |  *
 49 |  *     {@literal @Before}
 50 |  *     public void createDriver() {
 51 |  *         DesktopOptions options = DesktopOptions();
 52 |  *         options.setApplicationPath("C:\\Windows\\System32\\notepad.exe");
 53 |  *
 54 |  *         driver = new WiniumDriver(service, options);
 55 |  *     }
 56 |  *
 57 |  *     {@literal @After}
 58 |  *     public void quitDriver() {
 59 |  *         driver.quit();
 60 |  *     }
 61 |  *
 62 |  *     {@literal @Test}
 63 |  *     public void testSomething() {
 64 |  *         // Rest of test
 65 |  *     }
 66 |  * }
 67 |  * }
68 | */ 69 | public class WiniumDriverService extends DriverService { 70 | 71 | /** 72 | * Boolean system property that defines whether the WiniumDriver executable should be started 73 | * with verbose logging. 74 | */ 75 | public static final String WINIUM_DRIVER_VERBOSE_LOG = "webdriver.winium.verbose"; 76 | 77 | /** 78 | * Boolean system property that defines whether the WiniumDriver executable should be started 79 | * without any output. 80 | */ 81 | public static final String WINIUM_DRIVER_SILENT = "webdriver.winium.silent"; 82 | 83 | /** 84 | * System property that defines the location of the log that will be written by service 85 | */ 86 | public static final String WINIUM_DRIVER_LOG_PATH_PROPERTY = "webdriver.winium.logpath"; 87 | 88 | /** 89 | * Creates a default instance of the WiniumDriverService using a default path to the Winium Desktop Driver. 90 | * @return A {@link WiniumDriverService} using Winium Desktop and random port 91 | */ 92 | public static WiniumDriverService createDesktopService() { 93 | return new Builder().usingAnyFreePort().buildDesktopService(); 94 | } 95 | 96 | /** 97 | * Creates a default instance of the WiniumDriverService using a default path to the Winium WindowsPhone Driver. 98 | * @return A {@link WiniumDriverService} using Winium WindowsPhone and random port 99 | */ 100 | public static WiniumDriverService createSilverlightService() { 101 | return new Builder().usingAnyFreePort().buildSilverlightService(); 102 | } 103 | 104 | /** 105 | * Creates a default instance of the WiniumDriverService using a default path to the Winium StoreApps Driver. 106 | * @return A {@link WiniumDriverService} using Winium StoreApps and random port 107 | */ 108 | public static WiniumDriverService createStoreAppsService() { 109 | return new Builder().usingAnyFreePort().buildStoreAppsService(); 110 | } 111 | 112 | protected WiniumDriverService(File executable, int port, ImmutableList args, 113 | ImmutableMap environment) throws IOException { 114 | super(executable, port, args, environment); 115 | } 116 | 117 | public static class Builder extends DriverService.Builder { 118 | private static final String DESKTOP_DRIVER_SERVICE_FILENAME = "Winium.Desktop.Driver.exe"; 119 | private static final String SILVERLIGHT_DRIVER_SERVICE_FILENAME = "WindowsPhoneDriver.OuterDriver.exe"; 120 | private static final String STORE_APPS_DRIVER_SERVICE_FILENAME = "Winium.StoreApps.Driver.exe"; 121 | 122 | private static final String DESKTOP_DRIVER_EXE_PROPERTY = "webdriver.winium.driver.desktop"; 123 | private static final String SILVERLIGHT_DRIVER_EXE_PROPERTY = "webdriver.winium.driver.silverlight"; 124 | private static final String STORE_APPS_DRIVER_EXE_PROPERTY = "webdriver.winium.driver.storeaps"; 125 | 126 | private static final String DESKTOP_DRIVER_DOCS_URL = "https://github.com/2gis/Winium.Desktop"; 127 | private static final String SILVERLIGHT_DRIVER_DOCS_URL = "https://github.com/2gis/winphonedriver"; 128 | private static final String STORE_APPS_DRIVER_DOCS_URL = "https://github.com/2gis/Winium.StoreApps"; 129 | 130 | private static final String DESKTOP_DRIVER_DOWNLOAD_URL = "https://github.com/2gis/Winium.Desktop/releases"; 131 | private static final String SILVERLIGHT_DRIVER_DOWNLOAD_URL = "https://github.com/2gis/winphonedriver/releases"; 132 | private static final String STORE_APPS_DRIVER_DOWNLOAD_URL = "https://github.com/2gis/Winium.StoreApps/releases"; 133 | 134 | private File exe = null; 135 | private boolean verbose = Boolean.getBoolean(WINIUM_DRIVER_VERBOSE_LOG); 136 | private boolean silent = Boolean.getBoolean(WINIUM_DRIVER_SILENT); 137 | 138 | /** 139 | * Sets which driver executable the builder will use. 140 | * 141 | * @param file The executable to use. 142 | * @return A self reference. 143 | */ 144 | @Override 145 | public Builder usingDriverExecutable(File file) { 146 | checkNotNull(file); 147 | checkExecutable(file); 148 | this.exe = file; 149 | return this; 150 | } 151 | 152 | /** 153 | * Configures the driver server verbosity. 154 | * 155 | * @param verbose true for verbose output, false otherwise. 156 | * @return A self reference. 157 | */ 158 | public Builder withVerbose(boolean verbose) { 159 | this.verbose = verbose; 160 | return this; 161 | } 162 | 163 | /** 164 | * Configures the driver server for silent output. 165 | * 166 | * @param silent true for silent output, false otherwise. 167 | * @return A self reference. 168 | */ 169 | public Builder withSilent(boolean silent) { 170 | this.silent = silent; 171 | return this; 172 | } 173 | 174 | /** 175 | * Creates a new {@link WiniumDriverService} to manage the Winium Desktop Driver server. 176 | * Before creating a new service, the builder will find a port for the server to listen to. 177 | * 178 | * @return The new {@link WiniumDriverService} object. 179 | */ 180 | public WiniumDriverService buildDesktopService() { 181 | int port = getPort(); 182 | if (port == 0) { 183 | port = PortProber.findFreePort(); 184 | } 185 | 186 | if (exe == null) { 187 | exe = findDesktopDriverExecutable(); 188 | } 189 | 190 | try { 191 | return new WiniumDriverService(exe, port, createArgs(), ImmutableMap.of()); 192 | } catch (IOException e) { 193 | throw new WebDriverException(e); 194 | } 195 | } 196 | 197 | /** 198 | * Creates a new {@link WiniumDriverService} to manage the Winium WindowsPhone Driver server. 199 | * Before creating a new service, the builder will find a port for the server to listen to. 200 | * 201 | * @return The new {@link WiniumDriverService} object. 202 | */ 203 | public WiniumDriverService buildSilverlightService() { 204 | int port = getPort(); 205 | if (port == 0) { 206 | port = PortProber.findFreePort(); 207 | } 208 | 209 | if (exe == null) { 210 | exe = findSilverlightDriverExecutable(); 211 | } 212 | 213 | try { 214 | return new WiniumDriverService(exe, port, createArgs(), ImmutableMap.of()); 215 | } catch (IOException e) { 216 | throw new WebDriverException(e); 217 | } 218 | } 219 | 220 | /** 221 | * Creates a new {@link WiniumDriverService} to manage the Winium StoreApps Driver server. 222 | * Before creating a new service, the builder will find a port for the server to listen to. 223 | * 224 | * @return The new {@link WiniumDriverService} object. 225 | */ 226 | public WiniumDriverService buildStoreAppsService() { 227 | int port = getPort(); 228 | if (port == 0) { 229 | port = PortProber.findFreePort(); 230 | } 231 | 232 | if (exe == null) { 233 | exe = findStoreAppsDriverExecutable(); 234 | } 235 | 236 | try { 237 | return new WiniumDriverService(exe, port, createArgs(), ImmutableMap.of()); 238 | } catch (IOException e) { 239 | throw new WebDriverException(e); 240 | } 241 | } 242 | 243 | @Override 244 | protected File findDefaultExecutable() { 245 | return findDesktopDriverExecutable(); 246 | } 247 | 248 | @Override 249 | protected ImmutableList createArgs() { 250 | if (getLogFile() == null) { 251 | String logFilePath = System.getProperty(WINIUM_DRIVER_LOG_PATH_PROPERTY); 252 | if (logFilePath != null) { 253 | withLogFile(new File(logFilePath)); 254 | } 255 | } 256 | 257 | ImmutableList.Builder argsBuidler = new ImmutableList.Builder(); 258 | if (silent) { 259 | argsBuidler.add("--silent"); 260 | } 261 | if (verbose) { 262 | argsBuidler.add("--verbose"); 263 | } 264 | if (getLogFile() != null) { 265 | argsBuidler.add(String.format("--log-path=%s", getLogFile().getAbsolutePath())); 266 | } 267 | 268 | return argsBuidler.build(); 269 | } 270 | 271 | @Override 272 | protected WiniumDriverService createDriverService(File exe, int port, ImmutableList args, 273 | ImmutableMap environment) { 274 | try { 275 | return new WiniumDriverService(exe, port, args, environment); 276 | } catch (IOException e) { 277 | throw new WebDriverException(e); 278 | } 279 | } 280 | 281 | private File findDesktopDriverExecutable() { 282 | return findExecutable(DESKTOP_DRIVER_SERVICE_FILENAME, DESKTOP_DRIVER_EXE_PROPERTY, 283 | DESKTOP_DRIVER_DOCS_URL, DESKTOP_DRIVER_DOWNLOAD_URL); 284 | } 285 | 286 | private File findSilverlightDriverExecutable() { 287 | return findExecutable(SILVERLIGHT_DRIVER_SERVICE_FILENAME, SILVERLIGHT_DRIVER_EXE_PROPERTY, 288 | SILVERLIGHT_DRIVER_DOCS_URL, SILVERLIGHT_DRIVER_DOWNLOAD_URL); 289 | } 290 | 291 | private File findStoreAppsDriverExecutable() { 292 | return findExecutable(STORE_APPS_DRIVER_SERVICE_FILENAME, STORE_APPS_DRIVER_EXE_PROPERTY, 293 | STORE_APPS_DRIVER_DOCS_URL, STORE_APPS_DRIVER_DOWNLOAD_URL); 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /java/src/main/java/org/openqa/selenium/winium/WiniumOptions.java: -------------------------------------------------------------------------------- 1 | package org.openqa.selenium.winium; 2 | 3 | import org.openqa.selenium.Capabilities; 4 | 5 | /** 6 | * Defines the interface to manage options specific to {@link WiniumDriver} 7 | */ 8 | public interface WiniumOptions { 9 | /** 10 | * Convert options to DesiredCapabilities for one of Winium Drivers 11 | * @return The DesiredCapabilities for Winium Driver with these options. 12 | */ 13 | Capabilities toCapabilities(); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/ci.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | #------------------------------ 4 | 5 | $root = $PWD 6 | 7 | # .NET 8 | cd ..\dotnet\scripts 9 | & .\ci.ps1 10 | if ($LASTEXITCODE -ne 0) 11 | { 12 | Write-Output ".NET build failed. See console output" 13 | Exit $LASTEXITCODE 14 | } 15 | 16 | # Java 17 | cd $root\..\java\scripts 18 | & .\ci.ps1 19 | if ($LASTEXITCODE -ne 0) 20 | { 21 | Write-Output "Java build failed. See console output" 22 | Exit $LASTEXITCODE 23 | } --------------------------------------------------------------------------------