├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── SECURITY.md ├── azure-pipelines.yml ├── dotnet ├── Edge.sln ├── Microsoft.Edge.SeleniumTools.StrongNamed │ ├── Microsoft.Edge.SeleniumTools.StrongNamed.csproj │ └── WebDriver.snk ├── Microsoft.Edge.SeleniumTools.Test │ ├── EdgeDriverTests.cs │ ├── Microsoft.Edge.SeleniumTools.Test.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Microsoft.Edge.SeleniumTools │ ├── AssemblyInfo.cs │ ├── EdgeDriver.cs │ ├── EdgeDriverService.cs │ ├── EdgeMobileEmulationDeviceSettings.cs │ ├── EdgeNetworkConditions.cs │ ├── EdgeOptions.cs │ ├── EdgePerformanceLoggingPreferences.cs │ └── Microsoft.Edge.SeleniumTools.csproj └── nuget.config ├── java ├── .gitignore ├── .idea │ ├── compiler.xml │ ├── encodings.xml │ ├── jarRepositories.xml │ └── misc.xml ├── java.iml ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── microsoft │ │ └── edge │ │ └── seleniumtools │ │ ├── EdgeDriver.java │ │ ├── EdgeDriverCommand.java │ │ ├── EdgeDriverCommandExecutor.java │ │ ├── EdgeDriverInfo.java │ │ ├── EdgeDriverService.java │ │ └── EdgeOptions.java │ └── test │ └── java │ └── com │ └── microsoft │ └── edge │ └── seleniumtools │ └── EdgeDriverTest.java ├── js ├── LICENSE ├── README.md ├── lib │ └── edge.js ├── package-lock.json ├── package.json └── test │ └── edge_driver_test.js └── py ├── LICENSE ├── README.md ├── msedge ├── __init__.py └── selenium_tools │ ├── __init__.py │ ├── options.py │ ├── remote_connection.py │ ├── service.py │ └── webdriver.py ├── setup.py └── tests └── edge_driver_test.py /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | 352 | 353 | py/build 354 | py/dist 355 | py/*.egg-info 356 | 357 | .vscode 358 | 359 | # Created by https://www.gitignore.io/api/node 360 | # Edit at https://www.gitignore.io/?templates=node 361 | 362 | ### Node ### 363 | # Logs 364 | logs 365 | *.log 366 | npm-debug.log* 367 | yarn-debug.log* 368 | yarn-error.log* 369 | lerna-debug.log* 370 | 371 | # Diagnostic reports (https://nodejs.org/api/report.html) 372 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 373 | 374 | # Runtime data 375 | pids 376 | *.pid 377 | *.seed 378 | *.pid.lock 379 | 380 | # Directory for instrumented libs generated by jscoverage/JSCover 381 | lib-cov 382 | 383 | # Coverage directory used by tools like istanbul 384 | coverage 385 | *.lcov 386 | 387 | # nyc test coverage 388 | .nyc_output 389 | 390 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 391 | .grunt 392 | 393 | # Bower dependency directory (https://bower.io/) 394 | bower_components 395 | 396 | # node-waf configuration 397 | .lock-wscript 398 | 399 | # Compiled binary addons (https://nodejs.org/api/addons.html) 400 | build/Release 401 | 402 | # Dependency directories 403 | node_modules/ 404 | jspm_packages/ 405 | 406 | # TypeScript v1 declaration files 407 | typings/ 408 | 409 | # TypeScript cache 410 | *.tsbuildinfo 411 | 412 | # Optional npm cache directory 413 | .npm 414 | 415 | # Optional eslint cache 416 | .eslintcache 417 | 418 | # Optional REPL history 419 | .node_repl_history 420 | 421 | # Output of 'npm pack' 422 | *.tgz 423 | 424 | # Yarn Integrity file 425 | .yarn-integrity 426 | 427 | # dotenv environment variables file 428 | .env 429 | .env.test 430 | 431 | # parcel-bundler cache (https://parceljs.org/) 432 | .cache 433 | 434 | # next.js build output 435 | .next 436 | 437 | # nuxt.js build output 438 | .nuxt 439 | 440 | # rollup.js default build output 441 | dist/ 442 | 443 | # Uncomment the public line if your project uses Gatsby 444 | # https://nextjs.org/blog/next-9-1#public-directory-support 445 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav 446 | # public 447 | 448 | # Storybook build outputs 449 | .out 450 | .storybook-out 451 | 452 | # vuepress build output 453 | .vuepress/dist 454 | 455 | # Serverless directories 456 | .serverless/ 457 | 458 | # FuseBox cache 459 | .fusebox/ 460 | 461 | # DynamoDB Local files 462 | .dynamodb/ 463 | 464 | # Temporary folders 465 | tmp/ 466 | temp/ 467 | 468 | # End of https://www.gitignore.io/api/node -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code]. 4 | For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments. 5 | 6 | [conduct-code]: https://opensource.microsoft.com/codeofconduct/ 7 | [conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ 8 | [conduct-email]: mailto:opencode@microsoft.com -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to 4 | agree to a Contributor License Agreement (CLA) declaring that you have the right to, 5 | and actually do, grant us the rights to use your contribution. For details, visit 6 | https://cla.microsoft.com. 7 | 8 | When you submit a pull request, a CLA-bot will automatically determine whether you need 9 | to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the 10 | instructions provided by the bot. You will only need to do this once across all repositories using our CLA. 11 | 12 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 13 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 14 | or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | NOTICES AND INFORMATION 2 | Do Not Translate or Localize 3 | 4 | This software incorporates material from third parties. Microsoft makes certain 5 | open source code available at https://3rdpartysource.microsoft.com, or you may 6 | send a check or money order for US $5.00, including the product name, the open 7 | source component name, and version number, to: 8 | 9 | Source Code Compliance Team 10 | Microsoft Corporation 11 | One Microsoft Way 12 | Redmond, WA 98052 13 | USA 14 | 15 | Notwithstanding any other terms, you may reverse engineer this software to the 16 | extent required to debug changes to any libraries licensed under the GNU Lesser 17 | General Public License. 18 | 19 | Selenium 3.141.59 20 | 21 | Copyright 2011-2019 Software Freedom Conservancy 22 | Copyright 2004-2011 Selenium committers 23 | 24 | Apache License 25 | Version 2.0, January 2004 26 | http://www.apache.org/licenses/ 27 | 28 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 29 | 30 | 1. Definitions. 31 | 32 | "License" shall mean the terms and conditions for use, reproduction, 33 | and distribution as defined by Sections 1 through 9 of this document. 34 | 35 | "Licensor" shall mean the copyright owner or entity authorized by 36 | the copyright owner that is granting the License. 37 | 38 | "Legal Entity" shall mean the union of the acting entity and all 39 | other entities that control, are controlled by, or are under common 40 | control with that entity. For the purposes of this definition, 41 | "control" means (i) the power, direct or indirect, to cause the 42 | direction or management of such entity, whether by contract or 43 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 44 | outstanding shares, or (iii) beneficial ownership of such entity. 45 | 46 | "You" (or "Your") shall mean an individual or Legal Entity 47 | exercising permissions granted by this License. 48 | 49 | "Source" form shall mean the preferred form for making modifications, 50 | including but not limited to software source code, documentation 51 | source, and configuration files. 52 | 53 | "Object" form shall mean any form resulting from mechanical 54 | transformation or translation of a Source form, including but 55 | not limited to compiled object code, generated documentation, 56 | and conversions to other media types. 57 | 58 | "Work" shall mean the work of authorship, whether in Source or 59 | Object form, made available under the License, as indicated by a 60 | copyright notice that is included in or attached to the work 61 | (an example is provided in the Appendix below). 62 | 63 | "Derivative Works" shall mean any work, whether in Source or Object 64 | form, that is based on (or derived from) the Work and for which the 65 | editorial revisions, annotations, elaborations, or other modifications 66 | represent, as a whole, an original work of authorship. For the purposes 67 | of this License, Derivative Works shall not include works that remain 68 | separable from, or merely link (or bind by name) to the interfaces of, 69 | the Work and Derivative Works thereof. 70 | 71 | "Contribution" shall mean any work of authorship, including 72 | the original version of the Work and any modifications or additions 73 | to that Work or Derivative Works thereof, that is intentionally 74 | submitted to Licensor for inclusion in the Work by the copyright owner 75 | or by an individual or Legal Entity authorized to submit on behalf of 76 | the copyright owner. For the purposes of this definition, "submitted" 77 | means any form of electronic, verbal, or written communication sent 78 | to the Licensor or its representatives, including but not limited to 79 | communication on electronic mailing lists, source code control systems, 80 | and issue tracking systems that are managed by, or on behalf of, the 81 | Licensor for the purpose of discussing and improving the Work, but 82 | excluding communication that is conspicuously marked or otherwise 83 | designated in writing by the copyright owner as "Not a Contribution." 84 | 85 | "Contributor" shall mean Licensor and any individual or Legal Entity 86 | on behalf of whom a Contribution has been received by Licensor and 87 | subsequently incorporated within the Work. 88 | 89 | 2. Grant of Copyright License. Subject to the terms and conditions of 90 | this License, each Contributor hereby grants to You a perpetual, 91 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 92 | copyright license to reproduce, prepare Derivative Works of, 93 | publicly display, publicly perform, sublicense, and distribute the 94 | Work and such Derivative Works in Source or Object form. 95 | 96 | 3. Grant of Patent License. Subject to the terms and conditions of 97 | this License, each Contributor hereby grants to You a perpetual, 98 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 99 | (except as stated in this section) patent license to make, have made, 100 | use, offer to sell, sell, import, and otherwise transfer the Work, 101 | where such license applies only to those patent claims licensable 102 | by such Contributor that are necessarily infringed by their 103 | Contribution(s) alone or by combination of their Contribution(s) 104 | with the Work to which such Contribution(s) was submitted. If You 105 | institute patent litigation against any entity (including a 106 | cross-claim or counterclaim in a lawsuit) alleging that the Work 107 | or a Contribution incorporated within the Work constitutes direct 108 | or contributory patent infringement, then any patent licenses 109 | granted to You under this License for that Work shall terminate 110 | as of the date such litigation is filed. 111 | 112 | 4. Redistribution. You may reproduce and distribute copies of the 113 | Work or Derivative Works thereof in any medium, with or without 114 | modifications, and in Source or Object form, provided that You 115 | meet the following conditions: 116 | 117 | (a) You must give any other recipients of the Work or 118 | Derivative Works a copy of this License; and 119 | 120 | (b) You must cause any modified files to carry prominent notices 121 | stating that You changed the files; and 122 | 123 | (c) You must retain, in the Source form of any Derivative Works 124 | that You distribute, all copyright, patent, trademark, and 125 | attribution notices from the Source form of the Work, 126 | excluding those notices that do not pertain to any part of 127 | the Derivative Works; and 128 | 129 | (d) If the Work includes a "NOTICE" text file as part of its 130 | distribution, then any Derivative Works that You distribute must 131 | include a readable copy of the attribution notices contained 132 | within such NOTICE file, excluding those notices that do not 133 | pertain to any part of the Derivative Works, in at least one 134 | of the following places: within a NOTICE text file distributed 135 | as part of the Derivative Works; within the Source form or 136 | documentation, if provided along with the Derivative Works; or, 137 | within a display generated by the Derivative Works, if and 138 | wherever such third-party notices normally appear. The contents 139 | of the NOTICE file are for informational purposes only and 140 | do not modify the License. You may add Your own attribution 141 | notices within Derivative Works that You distribute, alongside 142 | or as an addendum to the NOTICE text from the Work, provided 143 | that such additional attribution notices cannot be construed 144 | as modifying the License. 145 | 146 | You may add Your own copyright statement to Your modifications and 147 | may provide additional or different license terms and conditions 148 | for use, reproduction, or distribution of Your modifications, or 149 | for any such Derivative Works as a whole, provided Your use, 150 | reproduction, and distribution of the Work otherwise complies with 151 | the conditions stated in this License. 152 | 153 | 5. Submission of Contributions. Unless You explicitly state otherwise, 154 | any Contribution intentionally submitted for inclusion in the Work 155 | by You to the Licensor shall be under the terms and conditions of 156 | this License, without any additional terms or conditions. 157 | Notwithstanding the above, nothing herein shall supersede or modify 158 | the terms of any separate license agreement you may have executed 159 | with Licensor regarding such Contributions. 160 | 161 | 6. Trademarks. This License does not grant permission to use the trade 162 | names, trademarks, service marks, or product names of the Licensor, 163 | except as required for reasonable and customary use in describing the 164 | origin of the Work and reproducing the content of the NOTICE file. 165 | 166 | 7. Disclaimer of Warranty. Unless required by applicable law or 167 | agreed to in writing, Licensor provides the Work (and each 168 | Contributor provides its Contributions) on an "AS IS" BASIS, 169 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 170 | implied, including, without limitation, any warranties or conditions 171 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 172 | PARTICULAR PURPOSE. You are solely responsible for determining the 173 | appropriateness of using or redistributing the Work and assume any 174 | risks associated with Your exercise of permissions under this License. 175 | 176 | 8. Limitation of Liability. In no event and under no legal theory, 177 | whether in tort (including negligence), contract, or otherwise, 178 | unless required by applicable law (such as deliberate and grossly 179 | negligent acts) or agreed to in writing, shall any Contributor be 180 | liable to You for damages, including any direct, indirect, special, 181 | incidental, or consequential damages of any character arising as a 182 | result of this License or out of the use or inability to use the 183 | Work (including but not limited to damages for loss of goodwill, 184 | work stoppage, computer failure or malfunction, or any and all 185 | other commercial damages or losses), even if such Contributor 186 | has been advised of the possibility of such damages. 187 | 188 | 9. Accepting Warranty or Additional Liability. While redistributing 189 | the Work or Derivative Works thereof, You may choose to offer, 190 | and charge a fee for, acceptance of support, warranty, indemnity, 191 | or other liability obligations and/or rights consistent with this 192 | License. However, in accepting such obligations, You may act only 193 | on Your own behalf and on Your sole responsibility, not on behalf 194 | of any other Contributor, and only if You agree to indemnify, 195 | defend, and hold each Contributor harmless for any liability 196 | incurred by, or claims asserted against, such Contributor by reason 197 | of your accepting any such warranty or additional liability. 198 | 199 | END OF TERMS AND CONDITIONS 200 | 201 | APPENDIX: How to apply the Apache License to your work. 202 | 203 | To apply the Apache License to your work, attach the following 204 | boilerplate notice, with the fields enclosed by brackets "[]" 205 | replaced with your own identifying information. (Don't include 206 | the brackets!) The text should be enclosed in the appropriate 207 | comment syntax for the file format. We also recommend that a 208 | file or class name and description of purpose be included on the 209 | same "printed page" as the copyright notice for easier 210 | identification within third-party archives. 211 | 212 | Copyright 2019 Software Freedom Conservancy (SFC) 213 | 214 | Licensed under the Apache License, Version 2.0 (the "License"); 215 | you may not use this file except in compliance with the License. 216 | You may obtain a copy of the License at 217 | 218 | http://www.apache.org/licenses/LICENSE-2.0 219 | 220 | Unless required by applicable law or agreed to in writing, software 221 | distributed under the License is distributed on an "AS IS" BASIS, 222 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 223 | See the License for the specific language governing permissions and 224 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED: Selenium Tools for Microsoft Edge 2 | 3 | :warning: **This project is no longer maintained. Please uninstall Selenium Tools for Microsoft Edge and upgrade to [Selenium 4](https://www.selenium.dev/) which has built-in support for Microsoft Edge (Chromium). For help upgrading your Selenium 3 browser tests to Selenium 4, see Selenium's guide [here](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/).** :warning: 4 | 5 | This repository will remain available as an example, and for users that have not yet had a chance to upgrade. However, there will be no further activity on issues or pull requests. The [@EdgeDevTools](https://twitter.com/EdgeDevTools) team will continue to work with the Selenium project to contribute future Microsoft Edge Driver features and bug fixes directly to Selenium 4. 6 | 7 | * * * 8 | 9 | [![Build Status](https://dev.azure.com/ms/edge-selenium-tools/_apis/build/status/microsoft.edge-selenium-tools?branchName=master)](https://dev.azure.com/ms/edge-selenium-tools/_build/latest?definitionId=345&branchName=master) 10 | 11 | Selenium Tools for Microsoft Edge extends [Selenium 3](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-3.141.59) with a unified driver to help you write automated tests for both the Microsoft Edge (EdgeHTML) and new Microsoft Edge (Chromium) browsers. 12 | 13 | The libraries included in this project are fully compatible with Selenium's built-in Edge libraries, and run Microsoft Edge (EdgeHTML) by default so you can use our project as a seamless drop-in replacement. In addition to being compatible with your existing Selenium tests, Selenium Tools for Microsoft Edge gives you the ability to drive the new Microsoft Edge (Chromium) browser and unlock all of the latest functionality! 14 | 15 | The classes in this package are based on the existing ``Edge`` and ``Chrome`` driver classes included in the [Selenium](https://github.com/SeleniumHQ/selenium) project. 16 | 17 | ## Before you Begin 18 | 19 | Selenium Tools for Microsoft Edge was created as a compatibility solution for developers who have existing Selenium 3 browser tests and want to add coverage for the latest Microsoft Edge (Chromium) browser. The [Microsoft Edge Developer Tools Team](https://twitter.com/EdgeDevTools) recommends using Selenium 4 instead because Selenium 4 has built-in support for Microsoft Edge (Chromium). If you are able to upgrade your existing tests, or write new tests using Selenium 4, then there is no need to use this package as Selenium should already have everything you need built in! 20 | 21 | See Selenium's upgrade [guide](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/) for help with upgrading from Selenium 3 to Selenium 4. If you are unable to upgrade due to a compatibility issues, please consider opening an issue in the official Selenium GitHub repo [here](https://github.com/SeleniumHQ/selenium/issues). If you have determined that you cannot upgrade from Selenium 3 at this time, and would still like to add test coverage for Microsoft Edge (Chromium) to your project, see the steps in the section below. 22 | 23 | ## Getting Started 24 | 25 | ### Downloading Driver Executables 26 | 27 | You will need the correct [WebDriver executable][webdriver-download] for the version of Microsoft Edge you want to drive. The executables are not included with this package. WebDriver executables for all supported versions of Microsoft Edge are available for download [here][webdriver-download]. For more information, and instructions on downloading the correct driver for your browser, see the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs]. 28 | 29 | ### Installation 30 | 31 | Selenium Tools for Microsoft Edge depends on the official Selenium 3 package to run. You will need to ensure that both Selenium 3 and the Tools and included in your project. 32 | 33 | #### C# 34 | 35 | Add the [Microsoft.Edge.SeleniumTools](https://www.nuget.org/packages/Microsoft.Edge.SeleniumTools) and [Selenium.WebDriver](https://www.nuget.org/packages/Selenium.WebDriver/3.141.0) packages to your .NET project using the NuGet CLI or Visual Studio. 36 | 37 | #### JavaScript 38 | 39 | ``` 40 | npm install @microsoft/edge-selenium-tools 41 | ``` 42 | 43 | #### Java 44 | 45 | Add [msedge-selenium-tools-java](https://search.maven.org/search?q=a:msedge-selenium-tools-java) to your project using Maven: 46 | 47 | ```xml 48 | 49 | 50 | com.microsoft.edge 51 | msedge-selenium-tools-java 52 | 3.141.0 53 | 54 | 55 | ``` 56 | 57 | The Java package is also available for download on the [Releases](https://github.com/microsoft/edge-selenium-tools/releases/latest) page. 58 | 59 | #### Python 60 | 61 | Use pip to install the [msedge-selenium-tools](https://pypi.org/project/msedge-selenium-tools/) and [selenium](https://pypi.org/project/selenium/3.141.0/) packages: 62 | 63 | ``` 64 | pip install msedge-selenium-tools selenium==3.141 65 | ``` 66 | 67 | ## Example Code 68 | 69 | See the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs] for lots more information on using Microsoft Edge (Chromium) with WebDriver. 70 | 71 | ### C# 72 | 73 | ```csharp 74 | using Microsoft.Edge.SeleniumTools; 75 | 76 | // Launch Microsoft Edge (EdgeHTML) 77 | var driver = new EdgeDriver(); 78 | 79 | // Launch Microsoft Edge (Chromium) 80 | var options = new EdgeOptions(); 81 | options.UseChromium = true; 82 | var driver = new EdgeDriver(options); 83 | ``` 84 | 85 | ### Java 86 | 87 | Import `EdgeDriver` from the `com.microsoft.edge.seleniumtools` package to launch Microsoft Edge (Chromium). The `com.microsoft.edge.seleniumtools` package supports **Chromium** only. Use the official Selenium 3 package `org.openqa.selenium.edge` to launch **EdgeHTML**. 88 | 89 | ```java 90 | import com.microsoft.edge.seleniumtools.EdgeDriver; 91 | 92 | // Launch Microsoft Edge (Chromium) 93 | EdgeDriver driver = new EdgeDriver(); 94 | ``` 95 | 96 | ### JavaScript 97 | 98 | ```js 99 | const edge = require("@microsoft/edge-selenium-tools"); 100 | 101 | // Launch Microsoft Edge (EdgeHTML) 102 | let driver = edge.Driver.createSession(); 103 | 104 | // Launch Microsoft Edge (Chromium) 105 | let options = new edge.Options().setEdgeChromium(true); 106 | let driver = edge.Driver.createSession(options); 107 | ``` 108 | 109 | ### Python 110 | 111 | ```python 112 | from msedge.selenium_tools import Edge, EdgeOptions 113 | 114 | # Launch Microsoft Edge (EdgeHTML) 115 | driver = Edge() 116 | 117 | # Launch Microsoft Edge (Chromium) 118 | options = EdgeOptions() 119 | options.use_chromium = True 120 | driver = Edge(options = options) 121 | ``` 122 | 123 | ## Contributing 124 | 125 | We are glad you are interested in automating the latest Microsoft Edge browser and improving the automation experience for the rest of the community! 126 | 127 | Before you begin, please read & follow our [Contributor's Guide](CONTRIBUTING.md). Consider also contributing your feature or bug fix directly to [Selenium](https://github.com/SeleniumHQ/selenium) so that it will be included in future Selenium releases. 128 | 129 | ## Code of Conduct 130 | 131 | This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code]. 132 | For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments. 133 | 134 | [webdriver-download]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 135 | [webdriver-chromium-docs]: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium 136 | [conduct-code]: https://opensource.microsoft.com/codeofconduct/ 137 | [conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ 138 | [conduct-email]: mailto:opencode@microsoft.com 139 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | pool: 2 | vmImage: 'windows-latest' 3 | 4 | steps: 5 | - task: NuGetToolInstaller@1 6 | inputs: 7 | versionSpec: 8 | 9 | - powershell: | 10 | $SeleniumWebDriver = "selenium-dotnet-strongnamed-3.141.0" 11 | $SeleniumWebDriverZip = "$SeleniumWebDriver.zip" 12 | $SeleniumWebDriverDownloadUrl = "http://selenium-release.storage.googleapis.com/3.141/$SeleniumWebDriverZip" 13 | $OutFile = "$env:PIPELINE_WORKSPACE/$SeleniumWebDriverZip" 14 | Invoke-WebRequest $SeleniumWebDriverDownloadUrl -OutFile $OutFile 15 | Expand-Archive $OutFile -DestinationPath "$env:PIPELINE_WORKSPACE/$SeleniumWebDriver" 16 | displayName: download Selenium WebDriver strong-named package 17 | 18 | - task: NuGetCommand@2 19 | inputs: 20 | command: 'restore' 21 | restoreSolution: '**/*.sln' 22 | feedsToUse: 'config' 23 | nugetConfigPath: 'dotnet/nuget.config' 24 | 25 | - task: VSBuild@1 26 | inputs: 27 | solution: '**\*.sln' 28 | platform: 'any cpu' 29 | configuration: 'release' 30 | 31 | - task: VSTest@2 32 | inputs: 33 | testSelector: 'testAssemblies' 34 | testAssemblyVer2: | 35 | **\*test*.dll 36 | !**\*TestAdapter.dll 37 | !**\obj\** 38 | searchFolder: '$(System.DefaultWorkingDirectory)' 39 | 40 | - task: CopyFiles@2 41 | inputs: 42 | sourceFolder: 'dotnet\Microsoft.Edge.SeleniumTools\bin\Release' 43 | contents: '*.nupkg' 44 | targetFolder: '$(Build.ArtifactStagingDirectory)\dotnet' 45 | 46 | - task: CopyFiles@2 47 | inputs: 48 | sourceFolder: 'dotnet\Microsoft.Edge.SeleniumTools.StrongNamed\bin\Release' 49 | contents: '*.nupkg' 50 | targetFolder: '$(Build.ArtifactStagingDirectory)\dotnet-strongnamed' 51 | 52 | - script: | 53 | python -m pip install --upgrade pip setuptools wheel 54 | workingDirectory: 'py' 55 | displayName: 'Install python dependencies' 56 | 57 | - script: | 58 | python setup.py sdist bdist_wheel 59 | workingDirectory: 'py' 60 | displayName: 'Create python package' 61 | 62 | - task: CopyFiles@2 63 | inputs: 64 | sourceFolder: 'py\dist' 65 | contents: | 66 | *.tar.gz 67 | *.whl 68 | targetFolder: '$(Build.ArtifactStagingDirectory)\py' 69 | 70 | - task: Npm@1 71 | inputs: 72 | command: 'custom' 73 | customCommand: 'pack' 74 | workingDir: 'js' 75 | 76 | - task: CopyFiles@2 77 | inputs: 78 | sourceFolder: 'js' 79 | contents: | 80 | *.tgz 81 | targetFolder: '$(Build.ArtifactStagingDirectory)\js' 82 | 83 | - task: PublishBuildArtifacts@1 84 | inputs: 85 | PathtoPublish: '$(Build.ArtifactStagingDirectory)' 86 | ArtifactName: 'dist' 87 | publishLocation: 'Container' -------------------------------------------------------------------------------- /dotnet/Edge.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Edge.SeleniumTools", "Microsoft.Edge.SeleniumTools\Microsoft.Edge.SeleniumTools.csproj", "{341F7687-6C2A-41AE-99F1-6D9A0322422A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Edge.SeleniumTools.Test", "Microsoft.Edge.SeleniumTools.Test\Microsoft.Edge.SeleniumTools.Test.csproj", "{ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Edge.SeleniumTools.StrongNamed", "Microsoft.Edge.SeleniumTools.StrongNamed\Microsoft.Edge.SeleniumTools.StrongNamed.csproj", "{777E682A-238F-4C1F-BE09-9B0E8B560285}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {341F7687-6C2A-41AE-99F1-6D9A0322422A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {341F7687-6C2A-41AE-99F1-6D9A0322422A}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {341F7687-6C2A-41AE-99F1-6D9A0322422A}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {341F7687-6C2A-41AE-99F1-6D9A0322422A}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {777E682A-238F-4C1F-BE09-9B0E8B560285}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {777E682A-238F-4C1F-BE09-9B0E8B560285}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {777E682A-238F-4C1F-BE09-9B0E8B560285}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {777E682A-238F-4C1F-BE09-9B0E8B560285}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {94353967-B252-47EE-9FFC-516B04BE36C3} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.StrongNamed/Microsoft.Edge.SeleniumTools.StrongNamed.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net45;net40;net35;netstandard2.0 5 | Microsoft 6 | Microsoft.Edge.SeleniumTools.StrongNamed 7 | 3.141.3 8 | Selenium Tools for Microsoft Edge 9 | © Microsoft Corporation. All rights reserved. 10 | Apache-2.0 11 | An updated EdgeDriver implementation for Selenium 3 with newly-added support for Edge Chromium. 12 | Microsoft 13 | https://github.com/microsoft/edge-selenium-tools 14 | https://github.com/microsoft/edge-selenium-tools 15 | GitHub 16 | selenium webdriver edge dotnet 17 | true 18 | true 19 | WebDriver.snk 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.StrongNamed/WebDriver.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/edge-selenium-tools/59b98594e726b5181e11be392baa0dabf2a048c7/dotnet/Microsoft.Edge.SeleniumTools.StrongNamed/WebDriver.snk -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.Test/EdgeDriverTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2020 Microsoft 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using Microsoft.Edge.SeleniumTools; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | using OpenQA.Selenium; 22 | 23 | namespace Edge.Test 24 | { 25 | [TestClass] 26 | public class EdgeDriverTests 27 | { 28 | void UsesLegacy(EdgeDriver driver) 29 | { 30 | Assert.AreEqual("MicrosoftEdge", driver.Capabilities.GetCapability("browserName"), "Driver launches Edge Legacy."); 31 | } 32 | 33 | void UsesChromium(EdgeDriver driver) 34 | { 35 | Assert.AreEqual("msedge", driver.Capabilities.GetCapability("browserName"), "Driver launches Edge Chromium."); 36 | 37 | var result = driver.ExecuteChromiumCommandWithResult("Browser.getVersion", new Dictionary()); 38 | Assert.IsTrue((result as Dictionary).ContainsKey("userAgent"), "Driver can send Chromium-specific commands."); 39 | } 40 | 41 | [TestMethod] 42 | [Ignore] // Edge Legacy is not available on Azure hosted environment. 43 | public void TestDefault() 44 | { 45 | var driver = new EdgeDriver(); 46 | try 47 | { 48 | UsesLegacy(driver); 49 | } 50 | finally 51 | { 52 | driver.Quit(); 53 | } 54 | } 55 | 56 | [TestMethod] 57 | [Ignore] // Edge Legacy is not available on Azure hosted environment. 58 | public void TestLegacyOptions() 59 | { 60 | var driver = new EdgeDriver(new EdgeOptions() { UseChromium = false }); 61 | try 62 | { 63 | UsesLegacy(driver); 64 | } 65 | finally 66 | { 67 | driver.Quit(); 68 | } 69 | } 70 | 71 | [TestMethod] 72 | public void TestChromiumOptions() 73 | { 74 | var driver = new EdgeDriver(new EdgeOptions() { UseChromium = true }); 75 | try 76 | { 77 | UsesChromium(driver); 78 | } 79 | finally 80 | { 81 | driver.Quit(); 82 | } 83 | } 84 | 85 | [TestMethod] 86 | public void TestChromiumServiceWithLegacyOptions() 87 | { 88 | using (var service = EdgeDriverService.CreateChromiumService()) 89 | { 90 | try 91 | { 92 | var driver = new EdgeDriver(service, new EdgeOptions()); 93 | Assert.Fail(); 94 | } 95 | catch (WebDriverException e) 96 | { 97 | Assert.AreEqual("options.UseChromium must be set to true when using an Edge Chromium driver service.", e.Message); 98 | } 99 | } 100 | } 101 | 102 | [TestMethod] 103 | public void TestChromiumServiceWithChromiumOptions() 104 | { 105 | using (var service = EdgeDriverService.CreateChromiumService()) 106 | { 107 | var driver = new EdgeDriver(service, new EdgeOptions() { UseChromium = true }); 108 | try 109 | { 110 | UsesChromium(driver); 111 | } 112 | finally 113 | { 114 | driver.Quit(); 115 | } 116 | } 117 | } 118 | 119 | [TestMethod] 120 | [Ignore] // Edge Legacy is not available on Azure hosted environment. 121 | public void TestLegacyServiceWithLegacyOptions() 122 | { 123 | using (var service = EdgeDriverService.CreateDefaultService()) 124 | { 125 | var driver = new EdgeDriver(service, new EdgeOptions() { UseChromium = false }); 126 | try 127 | { 128 | UsesLegacy(driver); 129 | } 130 | finally 131 | { 132 | driver.Quit(); 133 | } 134 | } 135 | } 136 | 137 | [TestMethod] 138 | [Ignore] // Edge Legacy is not available on Azure hosted environment. 139 | public void TestLegacyServiceWithChromiumOptions() 140 | { 141 | using (var service = EdgeDriverService.CreateDefaultService()) 142 | { 143 | try 144 | { 145 | var driver = new EdgeDriver(service, new EdgeOptions() { UseChromium = true }); 146 | Assert.Fail(); 147 | } 148 | catch (WebDriverException e) 149 | { 150 | Assert.AreEqual("options.UseChromium must be set to false when using an Edge Legacy driver service.", e.Message); 151 | } 152 | } 153 | } 154 | 155 | [TestMethod] 156 | public void TestChromiumOptionsToCapabilities() 157 | { 158 | var options = new EdgeOptions() 159 | { 160 | UseChromium = true, 161 | PageLoadStrategy = PageLoadStrategy.Eager, // Common 162 | UseInPrivateBrowsing = true, // Legacy only 163 | DebuggerAddress = "localhost:9222" // Chromium only 164 | }; 165 | 166 | var capabilities = options.ToCapabilities(); 167 | 168 | Assert.AreEqual("MicrosoftEdge", capabilities.GetCapability("browserName")); 169 | Assert.AreEqual(true, capabilities.GetCapability("ms:edgeChromium")); 170 | Assert.AreEqual("eager", capabilities.GetCapability("pageLoadStrategy")); 171 | Assert.IsFalse(capabilities.HasCapability("ms:inPrivate")); 172 | 173 | var edgeOptionsDictionary = capabilities.GetCapability("ms:edgeOptions") as Dictionary; 174 | Assert.IsNotNull(edgeOptionsDictionary); 175 | Assert.AreEqual(1, edgeOptionsDictionary.Count); 176 | Assert.AreEqual("localhost:9222", edgeOptionsDictionary["debuggerAddress"]); 177 | } 178 | 179 | [TestMethod] 180 | public void TestLegacyOptionsToCapabilities() 181 | { 182 | var options = new EdgeOptions() 183 | { 184 | UseChromium = false, 185 | PageLoadStrategy = PageLoadStrategy.Eager, // Common 186 | UseInPrivateBrowsing = true, // Legacy only 187 | DebuggerAddress = "localhost:9222" // Chromium only 188 | }; 189 | 190 | var capabilities = options.ToCapabilities(); 191 | 192 | Assert.AreEqual("MicrosoftEdge", capabilities.GetCapability("browserName")); 193 | Assert.AreEqual(false, capabilities.GetCapability("ms:edgeChromium")); 194 | Assert.AreEqual("eager", capabilities.GetCapability("pageLoadStrategy")); 195 | Assert.AreEqual(true, capabilities.GetCapability("ms:inPrivate")); 196 | Assert.IsFalse(capabilities.HasCapability("ms:edgeOptions")); 197 | } 198 | 199 | [TestMethod] 200 | public void TestWebViewOptions() 201 | { 202 | var options = new EdgeOptions(); 203 | options.UseWebView = true; 204 | Assert.AreEqual("webview2", options.BrowserName); 205 | } 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.Test/Microsoft.Edge.SeleniumTools.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {ED6B9F74-7228-44CD-8F1E-B1E5329AFC1A} 9 | Library 10 | Properties 11 | Edge.Test 12 | Edge.Test 13 | v4.5 14 | 512 15 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | 15.0 17 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 18 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 19 | False 20 | UnitTest 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll 44 | 45 | 46 | ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll 47 | 48 | 49 | 50 | 51 | 52 | ..\packages\Selenium.WebDriver.3.141.0\lib\net45\WebDriver.dll 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {341F7687-6C2A-41AE-99F1-6D9A0322422A} 65 | Microsoft.Edge.SeleniumTools 66 | 67 | 68 | 69 | 70 | 71 | 72 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | [assembly: AssemblyTitle("Edge.Test")] 7 | [assembly: AssemblyDescription("")] 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Edge.Test")] 11 | [assembly: AssemblyCopyright("Copyright © 2020")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyCulture("")] 14 | 15 | [assembly: ComVisible(false)] 16 | 17 | [assembly: Guid("ed6b9f74-7228-44cd-8f1e-b1e5329afc1a")] 18 | 19 | // [assembly: AssemblyVersion("1.0.*")] 20 | [assembly: AssemblyVersion("1.0.0.0")] 21 | [assembly: AssemblyFileVersion("1.0.0.0")] 22 | 23 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools.Test/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.CLSCompliant(true)] 2 | -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/EdgeDriver.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Portions Copyright Microsoft 2020 4 | // Licensed under the Apache License, Version 2.0 5 | // 6 | // Licensed to the Software Freedom Conservancy (SFC) under one 7 | // or more contributor license agreements. See the NOTICE file 8 | // distributed with this work for additional information 9 | // regarding copyright ownership. The SFC licenses this file 10 | // to you under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | // 22 | 23 | using System; 24 | using OpenQA.Selenium.Remote; 25 | using System.Collections.Generic; 26 | using OpenQA.Selenium; 27 | 28 | namespace Microsoft.Edge.SeleniumTools 29 | { 30 | /// 31 | /// Provides a mechanism to write tests against Edge Legacy (EdgeHTML) and Edge Chromium 32 | /// 33 | /// 34 | /// 35 | /// [TestFixture] 36 | /// public class Testing 37 | /// { 38 | /// private IWebDriver driver; 39 | /// 40 | /// [SetUp] 41 | /// public void SetUp() 42 | /// { 43 | /// driver = new EdgeDriver(); 44 | /// } 45 | /// 46 | /// [Test] 47 | /// public void TestBing() 48 | /// { 49 | /// driver.Navigate().GoToUrl("https://www.bing.com"); 50 | /// /* 51 | /// * Rest of the test 52 | /// */ 53 | /// } 54 | /// 55 | /// [TearDown] 56 | /// public void TearDown() 57 | /// { 58 | /// driver.Quit(); 59 | /// } 60 | /// } 61 | /// 62 | /// 63 | [Obsolete("Selenium Tools for Microsoft Edge is deprecated. Please upgrade to Selenium 4 which has built-in support for Microsoft Edge (Chromium): https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/#upgrading-from-selenium-3", false)] 64 | public class EdgeDriver : RemoteWebDriver 65 | { 66 | /// 67 | /// Accept untrusted SSL Certificates 68 | /// 69 | public static readonly bool AcceptUntrustedCertificates = true; 70 | 71 | private const string GetNetworkConditionsCommand = "getNetworkConditions"; 72 | private const string SetNetworkConditionsCommand = "setNetworkConditions"; 73 | private const string DeleteNetworkConditionsCommand = "deleteNetworkConditions"; 74 | private const string SendChromiumCommand = "sendChromeCommand"; 75 | private const string SendChromiumCommandWithResult = "sendChromeCommandWithResult"; 76 | 77 | /// 78 | /// Initializes a new instance of the class. 79 | /// 80 | public EdgeDriver() 81 | : this(new EdgeOptions()) 82 | { 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the class using the specified options. 87 | /// 88 | /// The to be used with the Edge driver. 89 | public EdgeDriver(EdgeOptions options) 90 | : this(EdgeDriverService.CreateDefaultServiceFromOptions(options), options, RemoteWebDriver.DefaultCommandTimeout) 91 | { 92 | } 93 | 94 | /// 95 | /// Initializes a new instance of the class using the specified driver service. 96 | /// 97 | /// The used to initialize the driver. 98 | public EdgeDriver(EdgeDriverService service) 99 | : this(service, new EdgeOptions() { UseChromium = service.UsingChromium }) 100 | { 101 | } 102 | 103 | /// 104 | /// Initializes a new instance of the class using the specified path 105 | /// to the directory containing the WebDriver executable. 106 | /// 107 | /// The full path to the directory containing the WebDriver executable. 108 | public EdgeDriver(string edgeDriverDirectory) 109 | : this(edgeDriverDirectory, new EdgeOptions()) 110 | { 111 | } 112 | 113 | /// 114 | /// Initializes a new instance of the class using the specified path 115 | /// to the directory containing the WebDriver executable and options. 116 | /// 117 | /// The full path to the directory containing the WebDriver executable. 118 | /// The to be used with the Edge driver. 119 | public EdgeDriver(string edgeDriverDirectory, EdgeOptions options) 120 | : this(edgeDriverDirectory, options, RemoteWebDriver.DefaultCommandTimeout) 121 | { 122 | } 123 | 124 | /// 125 | /// Initializes a new instance of the class using the specified path 126 | /// to the directory containing the WebDriver executable, options, and command timeout. 127 | /// 128 | /// The full path to the directory containing the WebDriver executable. 129 | /// The to be used with the Edge driver. 130 | /// The maximum amount of time to wait for each command. 131 | public EdgeDriver(string edgeDriverDirectory, EdgeOptions options, TimeSpan commandTimeout) 132 | : this(EdgeDriverService.CreateDefaultServiceFromOptions(edgeDriverDirectory, options), options, commandTimeout) 133 | { 134 | } 135 | 136 | /// 137 | /// Initializes a new instance of the class using the specified 138 | /// and options. 139 | /// 140 | /// The to use. 141 | /// The used to initialize the driver. 142 | public EdgeDriver(EdgeDriverService service, EdgeOptions options) 143 | : this(service, options, RemoteWebDriver.DefaultCommandTimeout) 144 | { 145 | } 146 | 147 | /// 148 | /// Initializes a new instance of the class using the specified . 149 | /// 150 | /// The to use. 151 | /// The to be used with the Edge driver. 152 | /// The maximum amount of time to wait for each command. 153 | public EdgeDriver(EdgeDriverService service, EdgeOptions options, TimeSpan commandTimeout) 154 | : base(new DriverServiceCommandExecutor(service, commandTimeout), ConvertOptionsToCapabilities(options, service.UsingChromium)) 155 | { 156 | // Add the custom commands unique to Chromium 157 | this.AddCustomChromiumCommand(GetNetworkConditionsCommand, CommandInfo.GetCommand, "/session/{sessionId}/chromium/network_conditions"); 158 | this.AddCustomChromiumCommand(SetNetworkConditionsCommand, CommandInfo.PostCommand, "/session/{sessionId}/chromium/network_conditions"); 159 | this.AddCustomChromiumCommand(DeleteNetworkConditionsCommand, CommandInfo.DeleteCommand, "/session/{sessionId}/chromium/network_conditions"); 160 | this.AddCustomChromiumCommand(SendChromiumCommand, CommandInfo.PostCommand, "/session/{sessionId}/chromium/send_command"); 161 | this.AddCustomChromiumCommand(SendChromiumCommandWithResult, CommandInfo.PostCommand, "/session/{sessionId}/chromium/send_command_and_get_result"); 162 | } 163 | 164 | /// 165 | /// Gets or sets the responsible for detecting 166 | /// sequences of keystrokes representing file paths and names. 167 | /// 168 | /// The Edge driver does not allow a file detector to be set, 169 | /// as the server component of the Edge driver (msedgedriver.exe) only 170 | /// allows uploads from the local computer environment. Attempting to set 171 | /// this property has no effect, but does not throw an exception. If you 172 | /// are attempting to run the Edge driver remotely, use 173 | /// in conjunction with a standalone WebDriver server. 174 | public override IFileDetector FileDetector 175 | { 176 | get { return base.FileDetector; } 177 | set { } 178 | } 179 | 180 | /// 181 | /// Gets or sets the network condition emulation for Edge. 182 | /// 183 | public EdgeNetworkConditions NetworkConditions 184 | { 185 | get 186 | { 187 | Response response = this.Execute(GetNetworkConditionsCommand, null); 188 | return EdgeNetworkConditions.FromDictionary(response.Value as Dictionary); 189 | } 190 | 191 | set 192 | { 193 | if (value == null) 194 | { 195 | throw new ArgumentNullException("value", "value must not be null"); 196 | } 197 | 198 | Dictionary parameters = new Dictionary(); 199 | parameters["network_conditions"] = value.ToDictionary(); 200 | this.Execute(SetNetworkConditionsCommand, parameters); 201 | } 202 | } 203 | 204 | /// 205 | /// Executes a custom Chromium command. 206 | /// 207 | /// Name of the command to execute. 208 | /// Parameters of the command to execute. 209 | public void ExecuteChromiumCommand(string commandName, Dictionary commandParameters) 210 | { 211 | if (commandName == null) 212 | { 213 | throw new ArgumentNullException("commandName", "commandName must not be null"); 214 | } 215 | 216 | Dictionary parameters = new Dictionary(); 217 | parameters["cmd"] = commandName; 218 | parameters["params"] = commandParameters; 219 | this.Execute(SendChromiumCommand, parameters); 220 | } 221 | 222 | public object ExecuteChromiumCommandWithResult(string commandName, Dictionary commandParameters) 223 | { 224 | if (commandName == null) 225 | { 226 | throw new ArgumentNullException("commandName", "commandName must not be null"); 227 | } 228 | 229 | Dictionary parameters = new Dictionary(); 230 | parameters["cmd"] = commandName; 231 | parameters["params"] = commandParameters; 232 | Response response = this.Execute(SendChromiumCommandWithResult, parameters); 233 | return response.Value; 234 | } 235 | 236 | private static ICapabilities ConvertOptionsToCapabilities(EdgeOptions options, bool serviceUsingChromium) 237 | { 238 | if (options == null) 239 | { 240 | throw new ArgumentNullException("options", "options must not be null"); 241 | } 242 | 243 | if (serviceUsingChromium != options.UseChromium) 244 | { 245 | if (serviceUsingChromium) 246 | { 247 | throw new WebDriverException("options.UseChromium must be set to true when using an Edge Chromium driver service."); 248 | } 249 | else 250 | { 251 | throw new WebDriverException("options.UseChromium must be set to false when using an Edge Legacy driver service."); 252 | } 253 | } 254 | 255 | return options.ToCapabilities(); 256 | } 257 | 258 | private void AddCustomChromiumCommand(string commandName, string method, string resourcePath) 259 | { 260 | CommandInfo commandInfoToAdd = new CommandInfo(method, resourcePath); 261 | this.CommandExecutor.CommandInfoRepository.TryAddCommand(commandName, commandInfoToAdd); 262 | } 263 | } 264 | } -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/EdgeMobileEmulationDeviceSettings.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Portions Copyright Microsoft 2020 4 | // Licensed under the Apache License, Version 2.0 5 | // 6 | // Licensed to the Software Freedom Conservancy (SFC) under one 7 | // or more contributor license agreements. See the NOTICE file 8 | // distributed with this work for additional information 9 | // regarding copyright ownership. The SFC licenses this file 10 | // to you under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | // 22 | 23 | namespace Microsoft.Edge.SeleniumTools 24 | { 25 | /// 26 | /// Represents the type-safe options for setting settings for emulating a 27 | /// mobile device in the Edge browser. 28 | /// 29 | public class EdgeMobileEmulationDeviceSettings 30 | { 31 | private string userAgent = string.Empty; 32 | private long width; 33 | private long height; 34 | private double pixelRatio; 35 | private bool enableTouchEvents = true; 36 | 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | public EdgeMobileEmulationDeviceSettings() 41 | { 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the class. 46 | /// 47 | /// The user agent string to be used by the browser when emulating 48 | /// a mobile device. 49 | public EdgeMobileEmulationDeviceSettings(string userAgent) 50 | { 51 | this.userAgent = userAgent; 52 | } 53 | 54 | /// 55 | /// Gets or sets the user agent string to be used by the browser when emulating 56 | /// a mobile device. 57 | /// 58 | public string UserAgent 59 | { 60 | get { return this.userAgent; } 61 | set { this.userAgent = value; } 62 | } 63 | 64 | /// 65 | /// Gets or sets the width in pixels to be used by the browser when emulating 66 | /// a mobile device. 67 | /// 68 | public long Width 69 | { 70 | get { return this.width; } 71 | set { this.width = value; } 72 | } 73 | 74 | /// 75 | /// Gets or sets the height in pixels to be used by the browser when emulating 76 | /// a mobile device. 77 | /// 78 | public long Height 79 | { 80 | get { return this.height; } 81 | set { this.height = value; } 82 | } 83 | 84 | /// 85 | /// Gets or sets the pixel ratio to be used by the browser when emulating 86 | /// a mobile device. 87 | /// 88 | public double PixelRatio 89 | { 90 | get { return this.pixelRatio; } 91 | set { this.pixelRatio = value; } 92 | } 93 | 94 | /// 95 | /// Gets or sets a value indicating whether touch events should be enabled by 96 | /// the browser when emulating a mobile device. Defaults to . 97 | /// 98 | public bool EnableTouchEvents 99 | { 100 | get { return this.enableTouchEvents; } 101 | set { this.enableTouchEvents = value; } 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/EdgeNetworkConditions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Portions Copyright Microsoft 2020 4 | // Licensed under the Apache License, Version 2.0 5 | // 6 | // Licensed to the Software Freedom Conservancy (SFC) under one 7 | // or more contributor license agreements. See the NOTICE file 8 | // distributed with this work for additional information 9 | // regarding copyright ownership. The SFC licenses this file 10 | // to you under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | // 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | using System.Linq; 26 | using System.Text; 27 | 28 | namespace Microsoft.Edge.SeleniumTools 29 | { 30 | /// 31 | /// Provides manipulation of getting and setting network conditions from Edge. 32 | /// 33 | public class EdgeNetworkConditions 34 | { 35 | private bool offline; 36 | private TimeSpan latency = TimeSpan.Zero; 37 | private long downloadThroughput = -1; 38 | private long uploadThroughput = -1; 39 | 40 | /// 41 | /// Gets or sets a value indicating whether the network is offline. Defaults to . 42 | /// 43 | public bool IsOffline 44 | { 45 | get { return this.offline; } 46 | set { this.offline = value; } 47 | } 48 | 49 | /// 50 | /// Gets or sets the simulated latency of the connection. Typically given in milliseconds. 51 | /// 52 | public TimeSpan Latency 53 | { 54 | get { return this.latency; } 55 | set { this.latency = value; } 56 | } 57 | 58 | /// 59 | /// Gets or sets the throughput of the network connection in kb/second for downloading. 60 | /// 61 | public long DownloadThroughput 62 | { 63 | get { return this.downloadThroughput; } 64 | set { this.downloadThroughput = value; } 65 | } 66 | 67 | /// 68 | /// Gets or sets the throughput of the network connection in kb/second for uploading. 69 | /// 70 | public long UploadThroughput 71 | { 72 | get { return this.uploadThroughput; } 73 | set { this.uploadThroughput = value; } 74 | } 75 | 76 | static internal EdgeNetworkConditions FromDictionary(Dictionary dictionary) 77 | { 78 | EdgeNetworkConditions conditions = new EdgeNetworkConditions(); 79 | if (dictionary.ContainsKey("offline")) 80 | { 81 | conditions.IsOffline = (bool)dictionary["offline"]; 82 | } 83 | 84 | if (dictionary.ContainsKey("latency")) 85 | { 86 | conditions.Latency = TimeSpan.FromMilliseconds(Convert.ToDouble(dictionary["latency"])); 87 | } 88 | 89 | if (dictionary.ContainsKey("upload_throughput")) 90 | { 91 | conditions.UploadThroughput = (long)dictionary["upload_throughput"]; 92 | } 93 | 94 | if (dictionary.ContainsKey("download_throughput")) 95 | { 96 | conditions.DownloadThroughput = (long)dictionary["download_throughput"]; 97 | } 98 | 99 | return conditions; 100 | } 101 | 102 | internal Dictionary ToDictionary() 103 | { 104 | Dictionary dictionary = new Dictionary(); 105 | dictionary["offline"] = this.offline; 106 | if (this.latency != TimeSpan.Zero) 107 | { 108 | dictionary["latency"] = Convert.ToInt64(this.latency.TotalMilliseconds); 109 | } 110 | 111 | if (this.downloadThroughput >= 0) 112 | { 113 | dictionary["download_throughput"] = this.downloadThroughput; 114 | } 115 | 116 | if (this.uploadThroughput >= 0) 117 | { 118 | dictionary["upload_throughput"] = this.uploadThroughput; 119 | } 120 | 121 | return dictionary; 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/EdgePerformanceLoggingPreferences.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Portions Copyright Microsoft 2020 4 | // Licensed under the Apache License, Version 2.0 5 | // 6 | // Licensed to the Software Freedom Conservancy (SFC) under one 7 | // or more contributor license agreements. See the NOTICE file 8 | // distributed with this work for additional information 9 | // regarding copyright ownership. The SFC licenses this file 10 | // to you under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | // 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | 26 | namespace Microsoft.Edge.SeleniumTools 27 | { 28 | /// 29 | /// Represents the type-safe options for setting preferences for performance 30 | /// logging in the Edge browser. 31 | /// 32 | public class EdgePerformanceLoggingPreferences 33 | { 34 | private bool isCollectingNetworkEvents = true; 35 | private bool isCollectingPageEvents = true; 36 | private TimeSpan bufferUsageReportingInterval = TimeSpan.FromMilliseconds(1000); 37 | private List tracingCategories = new List(); 38 | 39 | /// 40 | /// Gets or sets a value indicating whether Edge will collect events from the Network domain. 41 | /// Defaults to . 42 | /// 43 | public bool IsCollectingNetworkEvents 44 | { 45 | get { return this.isCollectingNetworkEvents; } 46 | set { this.isCollectingNetworkEvents = value; } 47 | } 48 | 49 | /// 50 | /// Gets or sets a value indicating whether Edge will collect events from the Page domain. 51 | /// Defaults to . 52 | /// 53 | public bool IsCollectingPageEvents 54 | { 55 | get { return this.isCollectingPageEvents; } 56 | set { this.isCollectingPageEvents = value; } 57 | } 58 | 59 | /// 60 | /// Gets or sets the interval between Edge DevTools trace buffer usage events. 61 | /// Defaults to 1000 milliseconds. 62 | /// 63 | /// Thrown when an attempt is made to set 64 | /// the value to a time span of less tnan or equal to zero milliseconds. 65 | public TimeSpan BufferUsageReportingInterval 66 | { 67 | get 68 | { 69 | return this.bufferUsageReportingInterval; 70 | } 71 | 72 | set 73 | { 74 | if (value.TotalMilliseconds <= 0) 75 | { 76 | throw new ArgumentException("Interval must be greater than zero."); 77 | } 78 | 79 | this.bufferUsageReportingInterval = value; 80 | } 81 | } 82 | 83 | /// 84 | /// Gets a comma-separated list of the categories for which tracing is enabled. 85 | /// 86 | public string TracingCategories 87 | { 88 | get 89 | { 90 | if (this.tracingCategories.Count == 0) 91 | { 92 | return string.Empty; 93 | } 94 | 95 | return string.Join(",", this.tracingCategories.ToArray()); 96 | } 97 | } 98 | 99 | /// 100 | /// Adds a single category to the list of Edge tracing categories for which events should be collected. 101 | /// 102 | /// The category to add. 103 | public void AddTracingCategory(string category) 104 | { 105 | if (string.IsNullOrEmpty(category)) 106 | { 107 | throw new ArgumentException("category must not be null or empty", "category"); 108 | } 109 | 110 | this.AddTracingCategories(category); 111 | } 112 | 113 | /// 114 | /// Adds categories to the list of Edge tracing categories for which events should be collected. 115 | /// 116 | /// An array of categories to add. 117 | public void AddTracingCategories(params string[] categoriesToAdd) 118 | { 119 | this.AddTracingCategories(new List(categoriesToAdd)); 120 | } 121 | 122 | /// 123 | /// Adds categories to the list of Edge tracing categories for which events should be collected. 124 | /// 125 | /// An object of categories to add. 126 | public void AddTracingCategories(IEnumerable categoriesToAdd) 127 | { 128 | if (categoriesToAdd == null) 129 | { 130 | throw new ArgumentNullException("categoriesToAdd", "categoriesToAdd must not be null"); 131 | } 132 | 133 | // Adding a tracing category automatically turns timeline events off. 134 | this.tracingCategories.AddRange(categoriesToAdd); 135 | } 136 | } 137 | } -------------------------------------------------------------------------------- /dotnet/Microsoft.Edge.SeleniumTools/Microsoft.Edge.SeleniumTools.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net45;net40;net35;netstandard2.0 5 | Microsoft 6 | Microsoft.Edge.SeleniumTools 7 | 3.141.3 8 | Selenium Tools for Microsoft Edge 9 | © Microsoft Corporation. All rights reserved. 10 | Apache-2.0 11 | An updated EdgeDriver implementation for Selenium 3 with newly-added support for Edge Chromium. 12 | Microsoft 13 | https://github.com/microsoft/edge-selenium-tools 14 | https://github.com/microsoft/edge-selenium-tools 15 | GitHub 16 | selenium webdriver edge dotnet 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /dotnet/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/maven 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=maven 3 | 4 | ### Maven ### 5 | target/ 6 | pom.xml.tag 7 | pom.xml.releaseBackup 8 | pom.xml.versionsBackup 9 | pom.xml.next 10 | release.properties 11 | dependency-reduced-pom.xml 12 | buildNumber.properties 13 | .mvn/timing.properties 14 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 15 | .mvn/wrapper/maven-wrapper.jar 16 | 17 | # End of https://www.toptal.com/developers/gitignore/api/maven 18 | 19 | 20 | # Created by https://www.toptal.com/developers/gitignore/api/intellij 21 | # Edit at https://www.toptal.com/developers/gitignore?templates=intellij 22 | 23 | ### Intellij ### 24 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 25 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 26 | 27 | # User-specific stuff 28 | .idea/**/workspace.xml 29 | .idea/**/tasks.xml 30 | .idea/**/usage.statistics.xml 31 | .idea/**/dictionaries 32 | .idea/**/shelf 33 | 34 | # Generated files 35 | .idea/**/contentModel.xml 36 | 37 | # Sensitive or high-churn files 38 | .idea/**/dataSources/ 39 | .idea/**/dataSources.ids 40 | .idea/**/dataSources.local.xml 41 | .idea/**/sqlDataSources.xml 42 | .idea/**/dynamic.xml 43 | .idea/**/uiDesigner.xml 44 | .idea/**/dbnavigator.xml 45 | 46 | # Gradle 47 | .idea/**/gradle.xml 48 | .idea/**/libraries 49 | 50 | # Gradle and Maven with auto-import 51 | # When using Gradle or Maven with auto-import, you should exclude module files, 52 | # since they will be recreated, and may cause churn. Uncomment if using 53 | # auto-import. 54 | # .idea/artifacts 55 | # .idea/compiler.xml 56 | # .idea/jarRepositories.xml 57 | # .idea/modules.xml 58 | # .idea/*.iml 59 | # .idea/modules 60 | # *.iml 61 | # *.ipr 62 | 63 | # CMake 64 | cmake-build-*/ 65 | 66 | # Mongo Explorer plugin 67 | .idea/**/mongoSettings.xml 68 | 69 | # File-based project format 70 | *.iws 71 | 72 | # IntelliJ 73 | out/ 74 | 75 | # mpeltonen/sbt-idea plugin 76 | .idea_modules/ 77 | 78 | # JIRA plugin 79 | atlassian-ide-plugin.xml 80 | 81 | # Cursive Clojure plugin 82 | .idea/replstate.xml 83 | 84 | # Crashlytics plugin (for Android Studio and IntelliJ) 85 | com_crashlytics_export_strings.xml 86 | crashlytics.properties 87 | crashlytics-build.properties 88 | fabric.properties 89 | 90 | # Editor-based Rest Client 91 | .idea/httpRequests 92 | 93 | # Android studio 3.1+ serialized cache file 94 | .idea/caches/build_file_checksums.ser 95 | 96 | ### Intellij Patch ### 97 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 98 | 99 | # *.iml 100 | # modules.xml 101 | # .idea/misc.xml 102 | # *.ipr 103 | 104 | # Sonarlint plugin 105 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 106 | .idea/**/sonarlint/ 107 | 108 | # SonarQube Plugin 109 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 110 | .idea/**/sonarIssues.xml 111 | 112 | # Markdown Navigator plugin 113 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 114 | .idea/**/markdown-navigator.xml 115 | .idea/**/markdown-navigator-enh.xml 116 | .idea/**/markdown-navigator/ 117 | 118 | # Cache file creation bug 119 | # See https://youtrack.jetbrains.com/issue/JBR-2257 120 | .idea/$CACHE_FILE$ 121 | 122 | # CodeStream plugin 123 | # https://plugins.jetbrains.com/plugin/12206-codestream 124 | .idea/codestream.xml 125 | 126 | # End of https://www.toptal.com/developers/gitignore/api/intellij -------------------------------------------------------------------------------- /java/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /java/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /java/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /java/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /java/java.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 26 | 4.0.0 27 | 28 | com.microsoft.edge 29 | msedge-selenium-tools-java 30 | 3.141.1 31 | jar 32 | Selenium Tools for Microsoft Edge 33 | An updated EdgeDriver implementation for Selenium 3 with newly-added support for Microsoft Edge (Chromium). 34 | https://github.com/microsoft/edge-selenium-tools 35 | 36 | 37 | 38 | Apache-2.0 License 39 | http://www.apache.org/licenses/LICENSE-2.0 40 | repo 41 | 42 | 43 | 44 | 8 45 | 8 46 | UTF-8 47 | 48 | 49 | https://github.com/microsoft/edge-selenium-tools 50 | scm:git:git@github.com:Microsoft/edge-selenium-tools.git 51 | scm:git:git@github.com:Microsoft/edge-selenium-tools.git 52 | HEAD 53 | 54 | 55 | 56 | 57 | microsoft 58 | Microsoft 59 | 60 | 61 | 62 | 63 | GitHub 64 | https://github.com/microsoft/edge-selenium-tools/issues 65 | 66 | 67 | 68 | 69 | ossrh 70 | https://oss.sonatype.org/content/repositories/snapshots 71 | 72 | 73 | ossrh 74 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 75 | 76 | 77 | 78 | 79 | 80 | 81 | org.junit 82 | junit-bom 83 | 5.7.0 84 | pom 85 | import 86 | 87 | 88 | 89 | 90 | 91 | 92 | org.seleniumhq.selenium 93 | selenium-api 94 | 3.141.59 95 | 96 | 97 | org.seleniumhq.selenium 98 | selenium-remote-driver 99 | 3.141.59 100 | 101 | 102 | net.bytebuddy 103 | byte-buddy 104 | 1.8.15 105 | 106 | 107 | org.apache.commons 108 | commons-exec 109 | 1.3 110 | 111 | 112 | com.google.guava 113 | guava 114 | 29.0-jre 115 | 116 | 117 | com.squareup.okhttp3 118 | okhttp 119 | 3.11.0 120 | 121 | 122 | com.squareup.okio 123 | okio 124 | 1.14.0 125 | 126 | 127 | com.google.auto.service 128 | auto-service 129 | 1.0-rc4 130 | true 131 | 132 | 133 | org.junit.jupiter 134 | junit-jupiter 135 | test 136 | 137 | 138 | 139 | 140 | src/main/java 141 | src/test/java 142 | 143 | 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-compiler-plugin 148 | 3.8.0 149 | 150 | 1.8 151 | 1.8 152 | 153 | 154 | 155 | org.apache.maven.plugins 156 | maven-jar-plugin 157 | 3.1.2 158 | 159 | 160 | 161 | true 162 | true 163 | 164 | 165 | 166 | 167 | 168 | org.apache.maven.plugins 169 | maven-javadoc-plugin 170 | 3.1.1 171 | 172 | 8 173 | 174 | 175 | 176 | attach-javadocs 177 | verify 178 | 179 | jar 180 | 181 | 182 | 183 | 184 | 185 | org.apache.maven.plugins 186 | maven-source-plugin 187 | 3.1.0 188 | 189 | 190 | attach-sources 191 | verify 192 | 193 | jar-no-fork 194 | 195 | 196 | 197 | 198 | 199 | org.apache.maven.plugins 200 | maven-surefire-plugin 201 | 3.0.0-M3 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeDriver.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | import com.google.common.collect.ImmutableMap; 24 | 25 | import org.openqa.selenium.Capabilities; 26 | import org.openqa.selenium.WebDriver; 27 | import org.openqa.selenium.WebDriverException; 28 | import org.openqa.selenium.html5.LocalStorage; 29 | import org.openqa.selenium.html5.Location; 30 | import org.openqa.selenium.html5.LocationContext; 31 | import org.openqa.selenium.html5.SessionStorage; 32 | import org.openqa.selenium.html5.WebStorage; 33 | import org.openqa.selenium.interactions.HasTouchScreen; 34 | import org.openqa.selenium.interactions.TouchScreen; 35 | import org.openqa.selenium.mobile.NetworkConnection; 36 | import org.openqa.selenium.remote.FileDetector; 37 | import org.openqa.selenium.remote.RemoteTouchScreen; 38 | import org.openqa.selenium.remote.RemoteWebDriver; 39 | import org.openqa.selenium.remote.html5.RemoteLocationContext; 40 | import org.openqa.selenium.remote.html5.RemoteWebStorage; 41 | import org.openqa.selenium.remote.mobile.RemoteNetworkConnection; 42 | 43 | /** 44 | * A {@link WebDriver} implementation that controls a Edge browser running on the local machine. 45 | * This class is provided as a convenience for easily testing the Edge browser. The control server 46 | * which each instance communicates with will live and die with the instance. 47 | * 48 | * To avoid unnecessarily restarting the EdgeDriver server with each instance, use a 49 | * {@link RemoteWebDriver} coupled with the desired {@link EdgeDriverService}, which is managed 50 | * separately. For example:
{@code
 51 |  *
 52 |  * import static org.junit.Assert.assertEquals;
 53 |  *
 54 |  * import org.junit.*;
 55 |  * import org.junit.runner.RunWith;
 56 |  * import org.junit.runners.JUnit4;
 57 |  * import com.microsoft.edge.seleniumtools.EdgeDriverService;
 58 |  * import org.openqa.selenium.remote.DesiredCapabilities;
 59 |  * import org.openqa.selenium.remote.RemoteWebDriver;
 60 |  *
 61 |  * {@literal @RunWith(JUnit4.class)}
 62 |  * public class EdgeTest extends TestCase {
 63 |  *
 64 |  *   private static EdgeDriverService service;
 65 |  *   private WebDriver driver;
 66 |  *
 67 |  *   {@literal @BeforeClass}
 68 |  *   public static void createAndStartService() {
 69 |  *     service = new EdgeDriverService.Builder()
 70 |  *         .usingDriverExecutable(new File("path/to/my/msedgedriver.exe"))
 71 |  *         .usingAnyFreePort()
 72 |  *         .build();
 73 |  *     service.start();
 74 |  *   }
 75 |  *
 76 |  *   {@literal @AfterClass}
 77 |  *   public static void createAndStopService() {
 78 |  *     service.stop();
 79 |  *   }
 80 |  *
 81 |  *   {@literal @Before}
 82 |  *   public void createDriver() {
 83 |  *     driver = new RemoteWebDriver(service.getUrl(),
 84 |  *         DesiredCapabilities.edge());
 85 |  *   }
 86 |  *
 87 |  *   {@literal @After}
 88 |  *   public void quitDriver() {
 89 |  *     driver.quit();
 90 |  *   }
 91 |  *
 92 |  *   {@literal @Test}
 93 |  *   public void testBingSearch() {
 94 |  *     driver.get("https://www.bing.com");
 95 |  *     WebElement searchBox = driver.findElement(By.name("q"));
 96 |  *     searchBox.sendKeys("webdriver");
 97 |  *     searchBox.quit();
 98 |  *     assertEquals("webdriver - Bing", driver.getTitle());
 99 |  *   }
100 |  * }
101 |  * }
102 | * 103 | * Note that unlike EdgeDriver, RemoteWebDriver doesn't directly implement 104 | * role interfaces such as {@link LocationContext} and {@link WebStorage}. 105 | * Therefore, to access that functionality, it needs to be 106 | * {@link org.openqa.selenium.remote.Augmenter augmented} and then cast 107 | * to the appropriate interface. 108 | * 109 | * @see EdgeDriverService#createDefaultService 110 | */ 111 | 112 | /** 113 | * @deprecated Selenium Tools for Microsoft Edge is deprecated. Please upgrade to Selenium 4 which has built-in support for Microsoft Edge (Chromium): https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/#upgrading-from-selenium-3 114 | */ 115 | @Deprecated 116 | public class EdgeDriver extends RemoteWebDriver 117 | implements LocationContext, WebStorage, HasTouchScreen, NetworkConnection { 118 | 119 | private RemoteLocationContext locationContext; 120 | private RemoteWebStorage webStorage; 121 | private TouchScreen touchScreen; 122 | private RemoteNetworkConnection networkConnection; 123 | 124 | /** 125 | * Creates a new EdgeDriver using the {@link EdgeDriverService#createDefaultService default} 126 | * server configuration. 127 | * 128 | * @see #EdgeDriver(EdgeDriverService, EdgeOptions) 129 | */ 130 | public EdgeDriver() { 131 | this(EdgeDriverService.createDefaultService(), new EdgeOptions()); 132 | } 133 | 134 | /** 135 | * Creates a new EdgeDriver instance. The {@code service} will be started along with the driver, 136 | * and shutdown upon calling {@link #quit()}. 137 | * 138 | * @param service The service to use. 139 | * @see RemoteWebDriver#RemoteWebDriver(org.openqa.selenium.remote.CommandExecutor, Capabilities) 140 | */ 141 | public EdgeDriver(EdgeDriverService service) { 142 | this(service, new EdgeOptions()); 143 | } 144 | 145 | /** 146 | * Creates a new EdgeDriver instance. The {@code capabilities} will be passed to the 147 | * EdgeDriver service. 148 | * 149 | * @param capabilities The capabilities required from the EdgeDriver. 150 | * @see #EdgeDriver(EdgeDriverService, Capabilities) 151 | * @deprecated Use {@link EdgeDriver(EdgeOptions)} instead. 152 | */ 153 | @Deprecated 154 | public EdgeDriver(Capabilities capabilities) { 155 | this(EdgeDriverService.createDefaultService(), capabilities); 156 | } 157 | 158 | /** 159 | * Creates a new EdgeDriver instance with the specified options. 160 | * 161 | * @param options The options to use. 162 | * @see #EdgeDriver(EdgeDriverService, EdgeOptions) 163 | */ 164 | public EdgeDriver(EdgeOptions options) { 165 | this(EdgeDriverService.createDefaultService(), options); 166 | } 167 | 168 | /** 169 | * Creates a new EdgeDriver instance with the specified options. The {@code service} will be 170 | * started along with the driver, and shutdown upon calling {@link #quit()}. 171 | * 172 | * @param service The service to use. 173 | * @param options The options to use. 174 | */ 175 | public EdgeDriver(EdgeDriverService service, EdgeOptions options) { 176 | this(service, (Capabilities) options); 177 | } 178 | 179 | /** 180 | * Creates a new EdgeDriver instance. The {@code service} will be started along with the 181 | * driver, and shutdown upon calling {@link #quit()}. 182 | * 183 | * @param service The service to use. 184 | * @param capabilities The capabilities required from the EdgeDriver. 185 | * @deprecated Use {@link EdgeDriver(EdgeDriverService, EdgeOptions)} instead. 186 | */ 187 | @Deprecated 188 | public EdgeDriver(EdgeDriverService service, Capabilities capabilities) { 189 | super(new EdgeDriverCommandExecutor(service), capabilities); 190 | locationContext = new RemoteLocationContext(getExecuteMethod()); 191 | webStorage = new RemoteWebStorage(getExecuteMethod()); 192 | touchScreen = new RemoteTouchScreen(getExecuteMethod()); 193 | networkConnection = new RemoteNetworkConnection(getExecuteMethod()); 194 | } 195 | 196 | @Override 197 | public void setFileDetector(FileDetector detector) { 198 | throw new WebDriverException( 199 | "Setting the file detector only works on remote webdriver instances obtained " + 200 | "via RemoteWebDriver"); 201 | } 202 | 203 | @Override 204 | public LocalStorage getLocalStorage() { 205 | return webStorage.getLocalStorage(); 206 | } 207 | 208 | @Override 209 | public SessionStorage getSessionStorage() { 210 | return webStorage.getSessionStorage(); 211 | } 212 | 213 | @Override 214 | public Location location() { 215 | return locationContext.location(); 216 | } 217 | 218 | @Override 219 | public void setLocation(Location location) { 220 | locationContext.setLocation(location); 221 | } 222 | 223 | @Override 224 | public TouchScreen getTouch() { 225 | return touchScreen; 226 | } 227 | 228 | @Override 229 | public ConnectionType getNetworkConnection() { 230 | return networkConnection.getNetworkConnection(); 231 | } 232 | 233 | @Override 234 | public ConnectionType setNetworkConnection(ConnectionType type) { 235 | return networkConnection.setNetworkConnection(type); 236 | } 237 | 238 | /** 239 | * Launches Edge app specified by id. 240 | * 241 | * @param id Edge app id. 242 | */ 243 | public void launchApp(String id) { 244 | execute(EdgeDriverCommand.LAUNCH_APP, ImmutableMap.of("id", id)); 245 | } 246 | 247 | } 248 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeDriverCommand.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | /** 24 | * Constants for the EdgeDriver specific command IDs. 25 | */ 26 | final class EdgeDriverCommand { 27 | private EdgeDriverCommand() {} 28 | 29 | static final String LAUNCH_APP = "launchApp"; 30 | static final String GET_NETWORK_CONDITIONS = "getNetworkConditions"; 31 | static final String SET_NETWORK_CONDITIONS = "setNetworkConditions"; 32 | static final String DELETE_NETWORK_CONDITIONS = "deleteNetworkConditions"; 33 | } 34 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeDriverCommandExecutor.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | import com.google.common.collect.ImmutableMap; 24 | 25 | import org.openqa.selenium.remote.CommandInfo; 26 | import org.openqa.selenium.remote.http.HttpMethod; 27 | import org.openqa.selenium.remote.service.DriverCommandExecutor; 28 | import org.openqa.selenium.remote.service.DriverService; 29 | 30 | /** 31 | * {@link DriverCommandExecutor} that understands EdgeDriver specific commands. 32 | * 33 | * @see List of ChromeWebdriver commands 34 | */ 35 | class EdgeDriverCommandExecutor extends DriverCommandExecutor { 36 | 37 | private static final ImmutableMap EDGE_COMMAND_NAME_TO_URL = ImmutableMap.of( 38 | EdgeDriverCommand.LAUNCH_APP, 39 | new CommandInfo("/session/:sessionId/chromium/launch_app", HttpMethod.POST), 40 | EdgeDriverCommand.GET_NETWORK_CONDITIONS, 41 | new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.GET), 42 | EdgeDriverCommand.SET_NETWORK_CONDITIONS, 43 | new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.POST), 44 | EdgeDriverCommand.DELETE_NETWORK_CONDITIONS, 45 | new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.DELETE) 46 | ); 47 | 48 | public EdgeDriverCommandExecutor(DriverService service) { 49 | super(service, EDGE_COMMAND_NAME_TO_URL); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeDriverInfo.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | import com.google.auto.service.AutoService; 24 | 25 | import org.openqa.selenium.Capabilities; 26 | import org.openqa.selenium.ImmutableCapabilities; 27 | import org.openqa.selenium.SessionNotCreatedException; 28 | import org.openqa.selenium.WebDriver; 29 | import org.openqa.selenium.WebDriverException; 30 | import org.openqa.selenium.WebDriverInfo; 31 | import org.openqa.selenium.remote.BrowserType; 32 | import org.openqa.selenium.remote.CapabilityType; 33 | 34 | import java.util.Objects; 35 | import java.util.Optional; 36 | 37 | @AutoService(WebDriverInfo.class) 38 | public class EdgeDriverInfo implements WebDriverInfo { 39 | 40 | @Override 41 | public String getDisplayName() { 42 | return "Edge"; 43 | } 44 | 45 | @Override 46 | public Capabilities getCanonicalCapabilities() { 47 | return new ImmutableCapabilities(CapabilityType.BROWSER_NAME, BrowserType.EDGE); 48 | } 49 | 50 | @Override 51 | public boolean isSupporting(Capabilities capabilities) { 52 | return (BrowserType.EDGE.equals(capabilities.getBrowserName()) 53 | || capabilities.getCapability("ms:edgeOptions") != null 54 | || capabilities.getCapability("edgeOptions") != null) 55 | && 56 | (capabilities.getCapability(EdgeOptions.USE_CHROMIUM) == null 57 | || Objects.equals(capabilities.getCapability(EdgeOptions.USE_CHROMIUM), true)); 58 | } 59 | 60 | @Override 61 | public boolean isAvailable() { 62 | try { 63 | EdgeDriverService.createDefaultService(); 64 | return true; 65 | } catch (IllegalStateException | WebDriverException e) { 66 | return false; 67 | } 68 | } 69 | 70 | @Override 71 | public int getMaximumSimultaneousSessions() { 72 | return Runtime.getRuntime().availableProcessors() + 1; 73 | } 74 | 75 | @Override 76 | public Optional createDriver(Capabilities capabilities) 77 | throws SessionNotCreatedException { 78 | if (!isAvailable() || !isSupporting(capabilities)) { 79 | return Optional.empty(); 80 | } 81 | 82 | WebDriver driver = new EdgeDriver(capabilities); 83 | 84 | return Optional.of(driver); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeDriverService.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | import com.google.auto.service.AutoService; 24 | import com.google.common.collect.ImmutableList; 25 | import com.google.common.collect.ImmutableMap; 26 | 27 | import org.openqa.selenium.Capabilities; 28 | import org.openqa.selenium.WebDriverException; 29 | import org.openqa.selenium.remote.BrowserType; 30 | import org.openqa.selenium.remote.service.DriverService; 31 | 32 | import java.io.File; 33 | import java.io.IOException; 34 | import java.util.Objects; 35 | 36 | /** 37 | * Manages the life and death of a EdgeDriver server. 38 | */ 39 | public class EdgeDriverService extends DriverService { 40 | 41 | /** 42 | * System property that defines the location of the msedgedriver executable that will be used by 43 | * the {@link #createDefaultService() default service}. 44 | */ 45 | public static final String EDGE_DRIVER_EXE_PROPERTY = "webdriver.edge.driver"; 46 | 47 | /** 48 | * System property that defines the location of the log that will be written by 49 | * the {@link #createDefaultService() default service}. 50 | */ 51 | public final static String EDGE_DRIVER_LOG_PROPERTY = "webdriver.edge.logfile"; 52 | 53 | /** 54 | * Boolean system property that defines whether the msedgedriver executable should be started 55 | * with verbose logging. 56 | */ 57 | public static final String EDGE_DRIVER_VERBOSE_LOG_PROPERTY = 58 | "webdriver.edge.verboseLogging"; 59 | 60 | /** 61 | * Boolean system property that defines whether the msedgedriver executable should be started 62 | * in silent mode. 63 | */ 64 | public static final String EDGE_DRIVER_SILENT_OUTPUT_PROPERTY = 65 | "webdriver.edge.silentOutput"; 66 | 67 | /** 68 | * System property that defines comma-separated list of remote IPv4 addresses which are 69 | * allowed to connect to EdgeDriver. 70 | */ 71 | public final static String EDGE_DRIVER_WHITELISTED_IPS_PROPERTY = 72 | "webdriver.edge.whitelistedIps"; 73 | 74 | /** 75 | * @param executable The msedgedriver executable. 76 | * @param port Which port to start the EdgeDriver on. 77 | * @param args The arguments to the launched server. 78 | * @param environment The environment for the launched server. 79 | * @throws IOException If an I/O error occurs. 80 | */ 81 | public EdgeDriverService( 82 | File executable, 83 | int port, 84 | ImmutableList args, 85 | ImmutableMap environment) throws IOException { 86 | super(executable, port, args, environment); 87 | } 88 | 89 | /** 90 | * Configures and returns a new {@link EdgeDriverService} using the default configuration. In 91 | * this configuration, the service will use the msedgedriver executable identified by the 92 | * {@link #EDGE_DRIVER_EXE_PROPERTY} system property. Each service created by this method will 93 | * be configured to use a free port on the current system. 94 | * 95 | * @return A new EdgeDriverService using the default configuration. 96 | */ 97 | public static EdgeDriverService createDefaultService() { 98 | return new Builder().build(); 99 | } 100 | 101 | /** 102 | * Builder used to configure new {@link EdgeDriverService} instances. 103 | */ 104 | @AutoService(DriverService.Builder.class) 105 | public static class Builder extends DriverService.Builder< 106 | EdgeDriverService, EdgeDriverService.Builder> { 107 | 108 | private boolean verbose = Boolean.getBoolean(EDGE_DRIVER_VERBOSE_LOG_PROPERTY); 109 | private boolean silent = Boolean.getBoolean(EDGE_DRIVER_SILENT_OUTPUT_PROPERTY); 110 | private String whitelistedIps = System.getProperty(EDGE_DRIVER_WHITELISTED_IPS_PROPERTY); 111 | 112 | @Override 113 | public int score(Capabilities capabilities) { 114 | int score = 0; 115 | 116 | if (BrowserType.EDGE.equals(capabilities.getBrowserName())) { 117 | score++; 118 | } 119 | 120 | Object useChromium = capabilities.getCapability(EdgeOptions.USE_CHROMIUM); 121 | if (Objects.equals(useChromium, false)) { 122 | score--; 123 | } 124 | 125 | if (capabilities.getCapability(EdgeOptions.CAPABILITY) != null) { 126 | score++; 127 | } 128 | 129 | return score; 130 | } 131 | 132 | /** 133 | * Configures the driver server verbosity. 134 | * 135 | * @param verbose True for verbose output, false otherwise. 136 | * @return A self reference. 137 | */ 138 | public Builder withVerbose(boolean verbose) { 139 | this.verbose = verbose; 140 | return this; 141 | } 142 | 143 | /** 144 | * Configures the driver server for silent output. 145 | * 146 | * @param silent True for silent output, false otherwise. 147 | * @return A self reference. 148 | */ 149 | public Builder withSilent(boolean silent) { 150 | this.silent = silent; 151 | return this; 152 | } 153 | 154 | /** 155 | * Configures the comma-separated list of remote IPv4 addresses which are allowed to connect 156 | * to the driver server. 157 | * 158 | * @param whitelistedIps Comma-separated list of remote IPv4 addresses. 159 | * @return A self reference. 160 | */ 161 | public Builder withWhitelistedIps(String whitelistedIps) { 162 | this.whitelistedIps = whitelistedIps; 163 | return this; 164 | } 165 | 166 | @Override 167 | protected File findDefaultExecutable() { 168 | return findExecutable( 169 | "msedgedriver", EDGE_DRIVER_EXE_PROPERTY, 170 | "https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium", 171 | "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver"); 172 | } 173 | 174 | @Override 175 | protected ImmutableList createArgs() { 176 | if (getLogFile() == null) { 177 | String logFilePath = System.getProperty(EDGE_DRIVER_LOG_PROPERTY); 178 | if (logFilePath != null) { 179 | withLogFile(new File(logFilePath)); 180 | } 181 | } 182 | 183 | ImmutableList.Builder argsBuilder = ImmutableList.builder(); 184 | argsBuilder.add(String.format("--port=%d", getPort())); 185 | if (getLogFile() != null) { 186 | argsBuilder.add(String.format("--log-path=%s", getLogFile().getAbsolutePath())); 187 | } 188 | if (verbose) { 189 | argsBuilder.add("--verbose"); 190 | } 191 | if (silent) { 192 | argsBuilder.add("--silent"); 193 | } 194 | if (whitelistedIps != null) { 195 | argsBuilder.add(String.format("--whitelisted-ips=%s", whitelistedIps)); 196 | } 197 | 198 | return argsBuilder.build(); 199 | } 200 | 201 | @Override 202 | protected EdgeDriverService createDriverService( 203 | File exe, 204 | int port, 205 | ImmutableList args, 206 | ImmutableMap environment) { 207 | try { 208 | return new EdgeDriverService(exe, port, args, environment); 209 | } catch (IOException e) { 210 | throw new WebDriverException(e); 211 | } 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /java/src/main/java/com/microsoft/edge/seleniumtools/EdgeOptions.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright Microsoft 2020 2 | // Licensed under the Apache License, Version 2.0 3 | // 4 | // Licensed to the Software Freedom Conservancy (SFC) under one 5 | // or more contributor license agreements. See the NOTICE file 6 | // distributed with this work for additional information 7 | // regarding copyright ownership. The SFC licenses this file 8 | // to you under the Apache License, Version 2.0 (the 9 | // "License"); you may not use this file except in compliance 10 | // with the License. You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, 15 | // software distributed under the License is distributed on an 16 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, either express or implied. See the License for the 18 | // specific language governing permissions and limitations 19 | // under the License. 20 | 21 | package com.microsoft.edge.seleniumtools; 22 | 23 | import static com.google.common.base.Preconditions.checkArgument; 24 | import static com.google.common.base.Preconditions.checkNotNull; 25 | import static org.openqa.selenium.remote.CapabilityType.ACCEPT_INSECURE_CERTS; 26 | import static org.openqa.selenium.remote.CapabilityType.PAGE_LOAD_STRATEGY; 27 | import static org.openqa.selenium.remote.CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR; 28 | import static org.openqa.selenium.remote.CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR; 29 | 30 | import com.google.common.collect.ImmutableList; 31 | import com.google.common.io.Files; 32 | 33 | import org.openqa.selenium.Capabilities; 34 | import org.openqa.selenium.MutableCapabilities; 35 | import org.openqa.selenium.PageLoadStrategy; 36 | import org.openqa.selenium.Proxy; 37 | import org.openqa.selenium.SessionNotCreatedException; 38 | import org.openqa.selenium.UnexpectedAlertBehaviour; 39 | import org.openqa.selenium.remote.BrowserType; 40 | import org.openqa.selenium.remote.CapabilityType; 41 | 42 | import java.io.File; 43 | import java.io.IOException; 44 | import java.util.ArrayList; 45 | import java.util.Base64; 46 | import java.util.Collections; 47 | import java.util.HashMap; 48 | import java.util.List; 49 | import java.util.Map; 50 | import java.util.Objects; 51 | import java.util.TreeMap; 52 | import java.util.stream.Stream; 53 | 54 | /** 55 | * Class to manage options specific to {@link EdgeDriver}. 56 | * 57 | *

Example usage: 58 | *


 59 |  * EdgeOptions options = new EdgeOptions()
 60 |  * options.addExtensions(new File("/path/to/extension.crx"))
 61 |  * options.setBinary(new File("/path/to/msedge"));
 62 |  *
 63 |  * // For use with EdgeDriver:
 64 |  * EdgeDriver driver = new EdgeDriver(options);
 65 |  *
 66 |  * // For use with RemoteWebDriver:
 67 |  * RemoteWebDriver driver = new RemoteWebDriver(
 68 |  *     new URL("http://localhost:4444/wd/hub"),
 69 |  *     new EdgeOptions());
 70 |  * 
71 | * 72 | * @since Since msedgedriver v17.0.963.0 73 | */ 74 | public class EdgeOptions extends MutableCapabilities { 75 | 76 | /** 77 | * Key used to store a set of EdgeOptions in a {@link Capabilities} 78 | * object. 79 | */ 80 | public static final String CAPABILITY = "ms:edgeOptions"; 81 | public static final String USE_CHROMIUM = "ms:edgeChromium"; 82 | 83 | private static final String WEBVIEW_BROWSER_NAME = "webview2"; 84 | 85 | private String binary; 86 | private List args = new ArrayList<>(); 87 | private List extensionFiles = new ArrayList<>(); 88 | private List extensions = new ArrayList<>(); 89 | private Map experimentalOptions = new HashMap<>(); 90 | 91 | public EdgeOptions() { 92 | setCapability(CapabilityType.BROWSER_NAME, BrowserType.EDGE); 93 | setCapability(USE_CHROMIUM, true); 94 | } 95 | 96 | @Override 97 | public EdgeOptions merge(Capabilities extraCapabilities) { 98 | super.merge(extraCapabilities); 99 | return this; 100 | } 101 | 102 | /** 103 | * Sets whether to launch an Edge (Chromium) WebView executable instead of 104 | * launching the Edge browser. 105 | * 106 | * @param useWebView Whether to launch a WebView executable. 107 | */ 108 | public EdgeOptions setUseWebView(boolean useWebView) { 109 | setCapability(CapabilityType.BROWSER_NAME, useWebView ? WEBVIEW_BROWSER_NAME : BrowserType.EDGE); 110 | return this; 111 | } 112 | 113 | /** 114 | * Sets the path to the Edge executable. This path should exist on the 115 | * machine which will launch Edge. The path should either be absolute or 116 | * relative to the location of running EdgeDriver server. 117 | * 118 | * @param path Path to Edge executable. 119 | */ 120 | public EdgeOptions setBinary(File path) { 121 | binary = checkNotNull(path).getPath(); 122 | return this; 123 | } 124 | 125 | /** 126 | * Sets the path to the Edge executable. This path should exist on the 127 | * machine which will launch Edge. The path should either be absolute or 128 | * relative to the location of running EdgeDriver server. 129 | * 130 | * @param path Path to Edge executable. 131 | */ 132 | public EdgeOptions setBinary(String path) { 133 | binary = checkNotNull(path); 134 | return this; 135 | } 136 | 137 | /** 138 | * @param arguments The arguments to use when starting Edge. 139 | * @see #addArguments(java.util.List) 140 | */ 141 | public EdgeOptions addArguments(String... arguments) { 142 | addArguments(ImmutableList.copyOf(arguments)); 143 | return this; 144 | } 145 | 146 | /** 147 | * Adds additional command line arguments to be used when starting Edge. 148 | * For example: 149 | *

150 |      *   options.setArguments(
151 |      *       "load-extension=/path/to/unpacked_extension",
152 |      *       "allow-outdated-plugins");
153 |      * 
154 | * 155 | *

Each argument may contain an option "--" prefix: "--foo" or "foo". 156 | * Arguments with an associated value should be delimitted with an "=": 157 | * "foo=bar". 158 | * 159 | * @param arguments The arguments to use when starting Edge. 160 | */ 161 | public EdgeOptions addArguments(List arguments) { 162 | args.addAll(arguments); 163 | return this; 164 | } 165 | 166 | /** 167 | * @param paths Paths to the extensions to install. 168 | * @see #addExtensions(java.util.List) 169 | */ 170 | public EdgeOptions addExtensions(File... paths) { 171 | addExtensions(ImmutableList.copyOf(paths)); 172 | return this; 173 | } 174 | 175 | /** 176 | * Adds a new Edge extension to install on browser startup. Each path should 177 | * specify a packed Edge extension (CRX file). 178 | * 179 | * @param paths Paths to the extensions to install. 180 | */ 181 | public EdgeOptions addExtensions(List paths) { 182 | for (File path : paths) { 183 | checkNotNull(path); 184 | checkArgument(path.exists(), "%s does not exist", path.getAbsolutePath()); 185 | checkArgument(!path.isDirectory(), "%s is a directory", 186 | path.getAbsolutePath()); 187 | } 188 | extensionFiles.addAll(paths); 189 | return this; 190 | } 191 | 192 | /** 193 | * @param encoded Base64 encoded data of the extensions to install. 194 | * @see #addEncodedExtensions(java.util.List) 195 | */ 196 | public EdgeOptions addEncodedExtensions(String... encoded) { 197 | addEncodedExtensions(ImmutableList.copyOf(encoded)); 198 | return this; 199 | } 200 | 201 | /** 202 | * Adds a new Edge extension to install on browser startup. Each string data should 203 | * specify a Base64 encoded string of packed Edge extension (CRX file). 204 | * 205 | * @param encoded Base64 encoded data of the extensions to install. 206 | */ 207 | public EdgeOptions addEncodedExtensions(List encoded) { 208 | for (String extension : encoded) { 209 | checkNotNull(extension); 210 | } 211 | extensions.addAll(encoded); 212 | return this; 213 | } 214 | 215 | /** 216 | * Sets an experimental option. Useful for new EdgeDriver options not yet 217 | * exposed through the {@link EdgeOptions} API. 218 | * 219 | * @param name Name of the experimental option. 220 | * @param value Value of the experimental option, which must be convertible 221 | * to JSON. 222 | */ 223 | public EdgeOptions setExperimentalOption(String name, Object value) { 224 | experimentalOptions.put(checkNotNull(name), value); 225 | return this; 226 | } 227 | 228 | /** 229 | * Returns the value of an experimental option. 230 | * 231 | * @param name The option name. 232 | * @return The option value, or {@code null} if not set. 233 | * @deprecated Getters are not needed in browser Options classes. 234 | */ 235 | @Deprecated 236 | public Object getExperimentalOption(String name) { 237 | return experimentalOptions.get(checkNotNull(name)); 238 | } 239 | 240 | public EdgeOptions setPageLoadStrategy(PageLoadStrategy strategy) { 241 | setCapability(PAGE_LOAD_STRATEGY, strategy); 242 | return this; 243 | } 244 | 245 | public EdgeOptions setUnhandledPromptBehaviour(UnexpectedAlertBehaviour behaviour) { 246 | setCapability(UNHANDLED_PROMPT_BEHAVIOUR, behaviour); 247 | setCapability(UNEXPECTED_ALERT_BEHAVIOUR, behaviour); 248 | return this; 249 | } 250 | 251 | /** 252 | * Returns EdgeOptions with the capability ACCEPT_INSECURE_CERTS set. 253 | * @param acceptInsecureCerts 254 | * @return EdgeOptions 255 | */ 256 | public EdgeOptions setAcceptInsecureCerts(boolean acceptInsecureCerts) { 257 | setCapability(ACCEPT_INSECURE_CERTS, acceptInsecureCerts); 258 | return this; 259 | } 260 | 261 | public EdgeOptions setHeadless(boolean headless) { 262 | args.remove("--headless"); 263 | if (headless) { 264 | args.add("--headless"); 265 | args.add("--disable-gpu"); 266 | } 267 | return this; 268 | } 269 | 270 | public EdgeOptions setProxy(Proxy proxy) { 271 | setCapability(CapabilityType.PROXY, proxy); 272 | return this; 273 | } 274 | 275 | @Override 276 | protected int amendHashCode() { 277 | return Objects.hash( 278 | args, 279 | binary, 280 | experimentalOptions, 281 | extensionFiles, 282 | extensions); 283 | } 284 | 285 | @Override 286 | public Map asMap() { 287 | Map toReturn = new TreeMap<>(super.asMap()); 288 | 289 | Map options = new TreeMap<>(); 290 | experimentalOptions.forEach(options::put); 291 | 292 | if (binary != null) { 293 | options.put("binary", binary); 294 | } 295 | 296 | options.put("args", ImmutableList.copyOf(args)); 297 | 298 | options.put( 299 | "extensions", 300 | Stream.concat( 301 | extensionFiles.stream() 302 | .map(file -> { 303 | try { 304 | return Base64.getEncoder().encodeToString(Files.toByteArray(file)); 305 | } catch (IOException e) { 306 | throw new SessionNotCreatedException(e.getMessage(), e); 307 | } 308 | }), 309 | extensions.stream() 310 | ).collect(ImmutableList.toImmutableList())); 311 | 312 | toReturn.put(CAPABILITY, options); 313 | toReturn.put(USE_CHROMIUM, true); 314 | 315 | return Collections.unmodifiableMap(toReturn); 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /java/src/test/java/com/microsoft/edge/seleniumtools/EdgeDriverTest.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.edge.seleniumtools; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class EdgeDriverTest { 8 | 9 | @Test 10 | void testDriver() { 11 | EdgeDriver driver = new EdgeDriver(); 12 | try { 13 | assertEquals("msedge", driver.getCapabilities().getBrowserName()); 14 | } finally { 15 | driver.quit(); 16 | } 17 | } 18 | 19 | @Test 20 | void testDefaultOptions() { 21 | EdgeOptions options = new EdgeOptions(); 22 | assertEquals("MicrosoftEdge", options.getBrowserName()); 23 | assertTrue((Boolean)options.getCapability(EdgeOptions.USE_CHROMIUM)); 24 | } 25 | 26 | @Test 27 | void testUseWebView() { 28 | EdgeOptions options = new EdgeOptions(); 29 | options.setUseWebView(true); 30 | assertEquals("webview2", options.getBrowserName()); 31 | assertTrue((Boolean)options.getCapability(EdgeOptions.USE_CHROMIUM)); 32 | } 33 | } -------------------------------------------------------------------------------- /js/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /js/README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED: Selenium Tools for Microsoft Edge 2 | 3 | 4 | :warning: **This project is no longer maintained. Please uninstall Selenium Tools for Microsoft Edge and upgrade to [Selenium 4](https://www.selenium.dev/) which has built-in support for Microsoft Edge (Chromium). For help upgrading your Selenium 3 browser tests to Selenium 4, see Selenium's guide [here](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/).** :warning: 5 | 6 | This repository will remain available as an example, and for users that have not yet had a chance to upgrade. However, there will be no further activity on issues or pull requests. The [@EdgeDevTools](https://twitter.com/EdgeDevTools) team will continue to work with the Selenium project to contribute future Microsoft Edge Driver features and bug fixes directly to Selenium 4. 7 | 8 | * * * 9 | 10 | [![Build Status](https://dev.azure.com/ms/edge-selenium-tools/_apis/build/status/microsoft.edge-selenium-tools?branchName=master)](https://dev.azure.com/ms/edge-selenium-tools/_build/latest?definitionId=345&branchName=master) 11 | 12 | Selenium Tools for Microsoft Edge extends [Selenium 3](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-3.141.59) with a unified driver to help you write automated tests for both the Microsoft Edge (EdgeHTML) and new Microsoft Edge (Chromium) browsers. 13 | 14 | The libraries included in this project are fully compatible with Selenium's built-in Edge libraries, and run Microsoft Edge (EdgeHTML) by default so you can use our project as a seamless drop-in replacement. In addition to being compatible with your existing Selenium tests, Selenium Tools for Microsoft Edge gives you the ability to drive the new Microsoft Edge (Chromium) browser and unlock all of the latest functionality! 15 | 16 | The classes in this package are based on the existing ``Edge`` and ``Chrome`` driver classes included in the [Selenium](https://github.com/SeleniumHQ/selenium) project. 17 | 18 | ## Before you Begin 19 | 20 | Selenium Tools for Microsoft Edge was created as a compatiblity solution for developers who have existing Selenium 3 browser tests and want to add coverage for the latest Microsoft Edge (Chromium) browser. The [Microsoft Edge Developer Tools Team](https://twitter.com/EdgeDevTools) recommends using Selenium 4 instead because Selenium 4 has built-in support for Microsoft Edge (Chromium). If you are able to upgrade your existing tests, or write new tests using Selenium 4, then there is no need to use this package as Selenium should already have everything you need built in! 21 | 22 | See Selenium's upgrade [guide](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/) for help with upgrading from Selenium 3 to Selenium 4. If you are unable to upgrade due to a compatibility issues, please consider opening an issue in the official Selenium GitHub repo [here](https://github.com/SeleniumHQ/selenium/issues). If you have determined that you cannot upgrade from Selenium 3 at this time, and would still like to add test coverage for Microsoft Edge (Chromium) to your project, see the steps in the section below. 23 | 24 | ## Getting Started 25 | 26 | ### Downloading Driver Executables 27 | 28 | You will need the correct [WebDriver executable][webdriver-download] for the version of Microsoft Edge you want to drive. The executables are not included with this package. WebDriver executables for all supported versions of Microsoft Edge are available for download [here][webdriver-download]. For more information, and instructions on downloading the correct driver for your browser, see the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs]. 29 | 30 | ### Installation 31 | 32 | Selenium Tools for Microsoft Edge depends on the official Selenium 3 package to run. You will need to ensure that both Selenium 3 and the Tools and included in your project. 33 | 34 | ``` 35 | npm install @microsoft/edge-selenium-tools 36 | ``` 37 | 38 | ## Example Code 39 | 40 | See the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs] for lots more information on using Microsoft Edge (Chromium) with WebDriver. 41 | 42 | ```js 43 | const edge = require("@microsoft/edge-selenium-tools"); 44 | 45 | // Launch Microsoft Edge (EdgeHTML) 46 | let driver = edge.Driver.createSession(); 47 | 48 | // Launch Microsoft Edge (Chromium) 49 | let options = new edge.Options().setEdgeChromium(true); 50 | let driver = edge.Driver.createSession(options); 51 | ``` 52 | 53 | ## Contributing 54 | 55 | We are glad you are interested in automating the latest Microsoft Edge browser and improving the automation experience for the rest of the community! 56 | 57 | Before you begin, please read & follow our [Contributor's Guide](CONTRIBUTING.md). Consider also contributing your feature or bug fix directly to [Selenium](https://github.com/SeleniumHQ/selenium) so that it will be included in future Selenium releases. 58 | 59 | ## Code of Conduct 60 | 61 | This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code]. 62 | For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments. 63 | 64 | [webdriver-download]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 65 | [webdriver-chromium-docs]: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium 66 | [conduct-code]: https://opensource.microsoft.com/codeofconduct/ 67 | [conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ 68 | [conduct-email]: mailto:opencode@microsoft.com 69 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microsoft/edge-selenium-tools", 3 | "version": "3.6.2", 4 | "description": "An updated EdgeDriver implementation for Selenium 3 with newly-added support for Microsoft Edge (Chromium).", 5 | "keywords": [ 6 | "automation", 7 | "selenium", 8 | "testing", 9 | "webdriver", 10 | "webdriverjs", 11 | "microsoft", 12 | "chromium", 13 | "edge" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/microsoft/edge-selenium-tools" 18 | }, 19 | "author": "Microsoft Corporation", 20 | "license": "Apache-2.0", 21 | "main": "./lib/edge.js", 22 | "directories": { 23 | "test": "test" 24 | }, 25 | "scripts": { 26 | "test": "mocha" 27 | }, 28 | "files": [ 29 | "lib/**/*.js", 30 | "README.md", 31 | "LICENSE" 32 | ], 33 | "peerDependencies": { 34 | "selenium-webdriver": "3.6.0" 35 | }, 36 | "devDependencies": { 37 | "mocha": "^7.1.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /js/test/edge_driver_test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Microsoft 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | const assert = require('assert'); 15 | const edge = require("../lib/edge"); 16 | 17 | describe('JS selenium binding tests', function () { 18 | this.timeout(0); 19 | 20 | it.skip('test default', async function () { 21 | let driver = await edge.Driver.createSession(); 22 | 23 | let cap = await driver.getCapabilities(); 24 | await assert.equal(cap.get('browserName'), 'MicrosoftEdge'); 25 | 26 | await driver.quit(); 27 | }); 28 | 29 | it.skip('test legacy edge', async function () { 30 | let options = await new edge.Options().setEdgeChromium(false); 31 | let driver = await edge.Driver.createSession(options); 32 | 33 | let cap = await driver.getCapabilities(); 34 | await assert.equal(cap.get('browserName'), 'MicrosoftEdge'); 35 | 36 | await driver.quit(); 37 | }); 38 | 39 | it('test chromium edge', async function () { 40 | let options = await new edge.Options().setEdgeChromium(true); 41 | let driver = await edge.Driver.createSession(options); 42 | 43 | let cap = await driver.getCapabilities(); 44 | await assert.equal(cap.get('browserName'), 'msedge'); 45 | 46 | await driver.quit(); 47 | }); 48 | 49 | it('test legacy options to capabilities', async function () { 50 | let options = await new edge.Options(); 51 | let cap = await options.toCapabilities(); 52 | await assert.equal(cap.get('browserName'), 'MicrosoftEdge'); 53 | await assert.equal(cap.has('ms:edgeOptions'), false); 54 | await assert.equal(cap.has('ms:edgeChromium'), true); 55 | await assert.equal(cap.get('ms:edgeChromium'), false); 56 | }); 57 | 58 | it('test chromium options to capabilities', async function () { 59 | let options = await new edge 60 | .Options() 61 | .setEdgeChromium(true); 62 | let cap = await options.toCapabilities(); 63 | await assert.equal(cap.get('browserName'), 'MicrosoftEdge'); 64 | await assert.equal(cap.has('ms:edgeOptions'), true); 65 | await assert.equal(cap.get('ms:edgeOptions').getEdgeChromium(), true); 66 | await assert.equal(cap.has('ms:edgeChromium'), true); 67 | await assert.equal(cap.get('ms:edgeChromium'), true); 68 | }); 69 | 70 | it('test webview options', function() { 71 | let options = new edge.Options(); 72 | options.setEdgeChromium(true); 73 | options.setUseWebView(true); 74 | let cap = options.toCapabilities(); 75 | assert.equal(cap.get('browserName'), 'webview2'); 76 | }); 77 | }); 78 | 79 | -------------------------------------------------------------------------------- /py/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /py/README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED: Selenium Tools for Microsoft Edge 2 | 3 | 4 | :warning: **This project is no longer maintained. Please uninstall Selenium Tools for Microsoft Edge and upgrade to [Selenium 4](https://www.selenium.dev/) which has built-in support for Microsoft Edge (Chromium). For help upgrading your Selenium 3 browser tests to Selenium 4, see Selenium's guide [here](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/).** :warning: 5 | 6 | This repository will remain available as an example, and for users that have not yet had a chance to upgrade. However, there will be no further activity on issues or pull requests. The [@EdgeDevTools](https://twitter.com/EdgeDevTools) team will continue to work with the Selenium project to contribute future Microsoft Edge Driver features and bug fixes directly to Selenium 4. 7 | 8 | * * * 9 | 10 | [![Build Status](https://dev.azure.com/ms/edge-selenium-tools/_apis/build/status/microsoft.edge-selenium-tools?branchName=master)](https://dev.azure.com/ms/edge-selenium-tools/_build/latest?definitionId=345&branchName=master) 11 | 12 | Selenium Tools for Microsoft Edge extends [Selenium 3](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-3.141.59) with a unified driver to help you write automated tests for both the Microsoft Edge (EdgeHTML) and new Microsoft Edge (Chromium) browsers. 13 | 14 | The libraries included in this project are fully compatible with Selenium's built-in Edge libraries, and run Microsoft Edge (EdgeHTML) by default so you can use our project as a seamless drop-in replacement. In addition to being compatible with your existing Selenium tests, Selenium Tools for Microsoft Edge gives you the ability to drive the new Microsoft Edge (Chromium) browser and unlock all of the latest functionality! 15 | 16 | The classes in this package are based on the existing ``Edge`` and ``Chrome`` driver classes included in the [Selenium](https://github.com/SeleniumHQ/selenium) project. 17 | 18 | ## Before you Begin 19 | 20 | Selenium Tools for Microsoft Edge was created as a compatiblity solution for developers who have existing Selenium 3 browser tests and want to add coverage for the latest Microsoft Edge (Chromium) browser. The [Microsoft Edge Developer Tools Team](https://twitter.com/EdgeDevTools) recommends using Selenium 4 instead because Selenium 4 has built-in support for Microsoft Edge (Chromium). If you are able to upgrade your existing tests, or write new tests using Selenium 4, then there is no need to use this package as Selenium should already have everything you need built in! 21 | 22 | See Selenium's upgrade [guide](https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/) for help with upgrading from Selenium 3 to Selenium 4. If you are unable to upgrade due to a compatibility issues, please consider opening an issue in the official Selenium GitHub repo [here](https://github.com/SeleniumHQ/selenium/issues). If you have determined that you cannot upgrade from Selenium 3 at this time, and would still like to add test coverage for Microsoft Edge (Chromium) to your project, see the steps in the section below. 23 | 24 | ## Getting Started 25 | 26 | ### Downloading Driver Executables 27 | 28 | You will need the correct [WebDriver executable][webdriver-download] for the version of Microsoft Edge you want to drive. The executables are not included with this package. WebDriver executables for all supported versions of Microsoft Edge are available for download [here][webdriver-download]. For more information, and instructions on downloading the correct driver for your browser, see the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs]. 29 | 30 | ### Installation 31 | 32 | Selenium Tools for Microsoft Edge depends on the official Selenium 3 package to run. You will need to ensure that both Selenium 3 and the Tools and included in your project. 33 | 34 | Use pip to install the [msedge-selenium-tools](https://pypi.org/project/msedge-selenium-tools/) and [selenium](https://pypi.org/project/selenium/3.141.0/) packages: 35 | 36 | ``` 37 | pip install msedge-selenium-tools selenium==3.141 38 | ``` 39 | 40 | ## Example Code 41 | 42 | See the [Microsoft Edge WebDriver documentation][webdriver-chromium-docs] for lots more information on using Microsoft Edge (Chromium) with WebDriver. 43 | 44 | ```python 45 | from msedge.selenium_tools import Edge, EdgeOptions 46 | 47 | # Launch Microsoft Edge (EdgeHTML) 48 | driver = Edge() 49 | 50 | # Launch Microsoft Edge (Chromium) 51 | options = EdgeOptions() 52 | options.use_chromium = True 53 | driver = Edge(options = options) 54 | ``` 55 | 56 | ## Contributing 57 | 58 | We are glad you are interested in automating the latest Microsoft Edge browser and improving the automation experience for the rest of the community! 59 | 60 | Before you begin, please read & follow our [Contributor's Guide](CONTRIBUTING.md). Consider also contributing your feature or bug fix directly to [Selenium](https://github.com/SeleniumHQ/selenium) so that it will be included in future Selenium releases. 61 | 62 | ## Code of Conduct 63 | 64 | This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code]. 65 | For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments. 66 | 67 | [webdriver-download]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 68 | [webdriver-chromium-docs]: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium 69 | [conduct-code]: https://opensource.microsoft.com/codeofconduct/ 70 | [conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ 71 | [conduct-email]: mailto:opencode@microsoft.com 72 | -------------------------------------------------------------------------------- /py/msedge/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/edge-selenium-tools/59b98594e726b5181e11be392baa0dabf2a048c7/py/msedge/__init__.py -------------------------------------------------------------------------------- /py/msedge/selenium_tools/__init__.py: -------------------------------------------------------------------------------- 1 | # Portions Copyright Microsoft 2020 2 | # Licensed under the Apache License, Version 2.0 3 | # 4 | # Licensed to the Software Freedom Conservancy (SFC) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The SFC licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | 21 | from .webdriver import WebDriver as Edge 22 | from .service import Service as EdgeService 23 | from .options import Options as EdgeOptions -------------------------------------------------------------------------------- /py/msedge/selenium_tools/options.py: -------------------------------------------------------------------------------- 1 | # Portions Copyright Microsoft 2020 2 | # Licensed under the Apache License, Version 2.0 3 | # 4 | # Licensed to the Software Freedom Conservancy (SFC) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The SFC licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | 21 | import base64 22 | import os 23 | import platform 24 | import warnings 25 | 26 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 27 | 28 | 29 | class Options(object): 30 | KEY = "ms:edgeOptions" 31 | 32 | def __init__(self): 33 | self._page_load_strategy = "normal" 34 | self._binary_location = '' 35 | self._arguments = [] 36 | self._extension_files = [] 37 | self._extensions = [] 38 | self._experimental_options = {} 39 | self._debugger_address = None 40 | self._caps = DesiredCapabilities.EDGE.copy() 41 | self._use_chromium = False 42 | self._use_webview = False 43 | 44 | @property 45 | def use_chromium(self): 46 | return self._use_chromium 47 | 48 | @use_chromium.setter 49 | def use_chromium(self, value): 50 | self._use_chromium = bool(value) 51 | 52 | @property 53 | def use_webview(self): 54 | return self._use_webview 55 | 56 | @use_webview.setter 57 | def use_webview(self, value): 58 | self._use_webview = bool(value) 59 | 60 | @property 61 | def page_load_strategy(self): 62 | return self._page_load_strategy 63 | 64 | @page_load_strategy.setter 65 | def page_load_strategy(self, value): 66 | if value not in ['normal', 'eager', 'none']: 67 | raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.") 68 | self._page_load_strategy = value 69 | 70 | @property 71 | def capabilities(self): 72 | return self._caps 73 | 74 | def set_capability(self, name, value): 75 | """Sets a capability.""" 76 | self._caps[name] = value 77 | 78 | def to_capabilities(self): 79 | """ 80 | Creates a capabilities with all the options that have been set and 81 | 82 | returns a dictionary with everything 83 | """ 84 | if self.use_chromium: 85 | caps = self._caps 86 | if self._use_webview: 87 | caps['browserName'] = 'webview2' 88 | edge_options = self.experimental_options.copy() 89 | edge_options["extensions"] = self.extensions 90 | if self.binary_location: 91 | edge_options["binary"] = self.binary_location 92 | edge_options["args"] = self.arguments 93 | if self.debugger_address: 94 | edge_options["debuggerAddress"] = self.debugger_address 95 | 96 | caps[self.KEY] = edge_options 97 | else: 98 | caps = self._caps 99 | caps['pageLoadStrategy'] = self._page_load_strategy 100 | caps['ms:edgeChromium'] = self.use_chromium 101 | return caps 102 | 103 | @property 104 | def binary_location(self): 105 | """ 106 | Returns the location of the binary otherwise an empty string 107 | """ 108 | return self._binary_location 109 | 110 | @binary_location.setter 111 | def binary_location(self, value): 112 | """ 113 | Allows you to set where the edge binary lives 114 | 115 | :Args: 116 | - value: path to the edge binary 117 | """ 118 | self._binary_location = value 119 | 120 | @property 121 | def debugger_address(self): 122 | """ 123 | Returns the address of the remote devtools instance 124 | """ 125 | return self._debugger_address 126 | 127 | @debugger_address.setter 128 | def debugger_address(self, value): 129 | """ 130 | Allows you to set the address of the remote devtools instance 131 | that the EdgeDriver instance will try to connect to during an 132 | active wait. 133 | 134 | :Args: 135 | - value: address of remote devtools instance if any (hostname[:port]) 136 | """ 137 | self._debugger_address = value 138 | 139 | @property 140 | def arguments(self): 141 | """ 142 | Returns a list of arguments needed for the browser 143 | """ 144 | return self._arguments 145 | 146 | def add_argument(self, argument): 147 | """ 148 | Adds an argument to the list 149 | 150 | :Args: 151 | - Sets the arguments 152 | """ 153 | if argument: 154 | self._arguments.append(argument) 155 | else: 156 | raise ValueError("argument can not be null") 157 | 158 | @property 159 | def extensions(self): 160 | """ 161 | Returns a list of encoded extensions that will be loaded into edge 162 | 163 | """ 164 | encoded_extensions = [] 165 | for ext in self._extension_files: 166 | file_ = open(ext, 'rb') 167 | # Should not use base64.encodestring() which inserts newlines every 168 | # 76 characters (per RFC 1521). Edgedriver has to remove those 169 | # unnecessary newlines before decoding, causing performance hit. 170 | encoded_extensions.append(base64.b64encode(file_.read()).decode('UTF-8')) 171 | 172 | file_.close() 173 | return encoded_extensions + self._extensions 174 | 175 | def add_extension(self, extension): 176 | """ 177 | Adds the path to the extension to a list that will be used to extract it 178 | to the EdgeDriver 179 | 180 | :Args: 181 | - extension: path to the \*.crx file 182 | """ 183 | if extension: 184 | extension_to_add = os.path.abspath(os.path.expanduser(extension)) 185 | if os.path.exists(extension_to_add): 186 | self._extension_files.append(extension_to_add) 187 | else: 188 | raise IOError("Path to the extension doesn't exist") 189 | else: 190 | raise ValueError("argument can not be null") 191 | 192 | def add_encoded_extension(self, extension): 193 | """ 194 | Adds Base64 encoded string with extension data to a list that will be used to extract it 195 | to the EdgeDriver 196 | 197 | :Args: 198 | - extension: Base64 encoded string with extension data 199 | """ 200 | if extension: 201 | self._extensions.append(extension) 202 | else: 203 | raise ValueError("argument can not be null") 204 | 205 | @property 206 | def experimental_options(self): 207 | """ 208 | Returns a dictionary of experimental options for edge. 209 | """ 210 | return self._experimental_options 211 | 212 | def add_experimental_option(self, name, value): 213 | """ 214 | Adds an experimental option which is passed to edge. 215 | 216 | Args: 217 | name: The experimental option name. 218 | value: The option value. 219 | """ 220 | self._experimental_options[name] = value 221 | 222 | @property 223 | def headless(self): 224 | """ 225 | Returns whether or not the headless argument is set 226 | """ 227 | return '--headless' in self._arguments 228 | 229 | @headless.setter 230 | def headless(self, value): 231 | """ 232 | Sets the headless argument 233 | 234 | Args: 235 | value: boolean value indicating to set the headless option 236 | """ 237 | args = {'--headless'} 238 | if platform.system().lower() == 'windows': 239 | args.add('--disable-gpu') 240 | if value is True: 241 | self._arguments.extend(args) 242 | else: 243 | self._arguments = list(set(self._arguments) - args) 244 | 245 | def set_headless(self, headless=True): 246 | """ Deprecated, options.headless = True """ 247 | warnings.warn('use setter for headless property instead of set_headless', 248 | DeprecationWarning, stacklevel=2) 249 | self.headless = headless -------------------------------------------------------------------------------- /py/msedge/selenium_tools/remote_connection.py: -------------------------------------------------------------------------------- 1 | # Portions Copyright Microsoft 2020 2 | # Licensed under the Apache License, Version 2.0 3 | # 4 | # Licensed to the Software Freedom Conservancy (SFC) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The SFC licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | 21 | from selenium.webdriver.remote.remote_connection import RemoteConnection 22 | 23 | 24 | class EdgeRemoteConnection(RemoteConnection): 25 | 26 | def __init__(self, remote_server_addr, keep_alive=True): 27 | RemoteConnection.__init__(self, remote_server_addr, keep_alive) 28 | self._commands["launchApp"] = ('POST', '/session/$sessionId/chromium/launch_app') 29 | self._commands["setNetworkConditions"] = ('POST', '/session/$sessionId/chromium/network_conditions') 30 | self._commands["getNetworkConditions"] = ('GET', '/session/$sessionId/chromium/network_conditions') 31 | self._commands['executeCdpCommand'] = ('POST', '/session/$sessionId/ms/cdp/execute') 32 | -------------------------------------------------------------------------------- /py/msedge/selenium_tools/service.py: -------------------------------------------------------------------------------- 1 | # Portions Copyright Microsoft 2020 2 | # Licensed under the Apache License, Version 2.0 3 | # 4 | # Licensed to the Software Freedom Conservancy (SFC) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The SFC licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | 21 | from selenium.webdriver.common import service 22 | 23 | 24 | class Service(service.Service): 25 | 26 | def __init__(self, executable_path, port=0, verbose=False, log_path=None, 27 | service_args=None, env=None): 28 | """ 29 | Creates a new instance of the EdgeDriver service. 30 | 31 | EdgeDriver provides an interface for Microsoft WebDriver to use 32 | with Microsoft Edge. 33 | 34 | :param executable_path: Path to the Microsoft WebDriver binary. 35 | :param port: Run the remote service on a specified port. 36 | Defaults to 0, which binds to a random open port of the 37 | system's choosing. 38 | :verbose: Whether to make the webdriver more verbose (passes the 39 | --verbose option to the binary). Defaults to False. 40 | :param log_path: Optional path for the webdriver binary to log to. 41 | Defaults to None which disables logging. 42 | :param service_args : List of args to pass to the edgedriver service 43 | 44 | """ 45 | self.service_args = service_args or [] 46 | if verbose: 47 | self.service_args.append("--verbose") 48 | 49 | params = { 50 | "executable": executable_path, 51 | "port": port, 52 | "env": env, 53 | "start_error_message": "Please download from http://go.microsoft.com/fwlink/?LinkId=619687" 54 | } 55 | 56 | if log_path: 57 | params["log_file"] = open(log_path, "a+") 58 | 59 | service.Service.__init__(self, **params) 60 | 61 | def command_line_args(self): 62 | return ["--port=%d" % self.port] + self.service_args 63 | -------------------------------------------------------------------------------- /py/msedge/selenium_tools/webdriver.py: -------------------------------------------------------------------------------- 1 | # Portions Copyright Microsoft 2020 2 | # Licensed under the Apache License, Version 2.0 3 | # 4 | # Licensed to the Software Freedom Conservancy (SFC) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The SFC licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | import warnings 21 | 22 | from selenium.webdriver.common import utils 23 | from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver 24 | from selenium.webdriver.remote.remote_connection import RemoteConnection 25 | from .remote_connection import EdgeRemoteConnection 26 | from .service import Service 27 | from .options import Options 28 | 29 | 30 | class WebDriver(RemoteWebDriver): 31 | 32 | def __init__(self, executable_path='', 33 | capabilities=None, port=0, verbose=False, service_log_path=None, 34 | log_path=None, keep_alive=None, 35 | desired_capabilities=None, service_args=None, options=None): 36 | """ 37 | Creates a new instance of the edge driver. 38 | 39 | Starts the service and then creates new instance of edge driver. 40 | 41 | :Args: 42 | - executable_path - path to the executable. If the default is used it assumes the executable is in the $PATH 43 | - capabilities - Dictionary object with non-browser specific 44 | capabilities only, such as "proxy" or "loggingPref". 45 | - port - port you would like the service to run, if left as 0, a free port will be found. 46 | - verbose - whether to set verbose logging in the service 47 | - service_log_path - Where to log information from the driver. 48 | - log_path: Deprecated argument for service_log_path 49 | - keep_alive - Whether to configure EdgeRemoteConnection to use HTTP keep-alive. 50 | - desired_capabilities - Dictionary object with non-browser specific 51 | capabilities only, such as "proxy" or "loggingPref". 52 | - service_args - List of args to pass to the driver service 53 | - options - this takes an instance of EdgeOptions 54 | 55 | """ 56 | 57 | warnings.warn( 58 | "Selenium Tools for Microsoft Edge is deprecated. Please upgrade to Selenium 4 which has built-in support for Microsoft Edge (Chromium): https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/#upgrading-from-selenium-3", 59 | DeprecationWarning, stacklevel=2) 60 | 61 | use_chromium = False 62 | if (options and options.use_chromium) or \ 63 | (desired_capabilities and 'ms:edgeChromium' in desired_capabilities \ 64 | and desired_capabilities['ms:edgeChromium']): 65 | use_chromium = True 66 | 67 | if keep_alive is None: 68 | if use_chromium: 69 | keep_alive = True 70 | else: 71 | keep_alive = False 72 | 73 | if executable_path is '': 74 | executable_path = 'msedgedriver' if use_chromium else 'MicrosoftWebDriver.exe' 75 | 76 | # Note that legacy edge uses capabilities while chrome edge 77 | # uses desired_capabilities as argument 78 | if not use_chromium and capabilities is not None: 79 | desired_capabilities = capabilities 80 | 81 | if options is None: 82 | # desired_capabilities stays as passed in 83 | if desired_capabilities is None: 84 | desired_capabilities = self.create_options().to_capabilities() 85 | else: 86 | if desired_capabilities is None: 87 | desired_capabilities = options.to_capabilities() 88 | else: 89 | desired_capabilities.update(options.to_capabilities()) 90 | 91 | if log_path: 92 | warnings.warn('use service_log_path instead of log_path', 93 | DeprecationWarning, stacklevel=2) 94 | service_log_path = log_path 95 | 96 | self.port = port 97 | 98 | self.service = Service( 99 | executable_path, 100 | port=self.port, 101 | verbose=verbose, 102 | service_args=service_args, 103 | log_path=service_log_path) 104 | self.service.start() 105 | 106 | try: 107 | RemoteWebDriver.__init__( 108 | self, 109 | command_executor = EdgeRemoteConnection( 110 | remote_server_addr=self.service.service_url, 111 | keep_alive=keep_alive), 112 | desired_capabilities=desired_capabilities) 113 | except Exception: 114 | self.quit() 115 | raise 116 | self._is_remote = False 117 | 118 | def launch_app(self, id): 119 | """Launches Edge app specified by id.""" 120 | return self.execute("launchApp", {'id': id}) 121 | 122 | def get_network_conditions(self): 123 | """ 124 | Gets Edge network emulation settings. 125 | 126 | :Returns: 127 | A dict. For example: 128 | 129 | {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2, 130 | 'offline': False} 131 | 132 | """ 133 | return self.execute("getNetworkConditions")['value'] 134 | 135 | def set_network_conditions(self, **network_conditions): 136 | """ 137 | Sets Edge network emulation settings. 138 | 139 | :Args: 140 | - network_conditions: A dict with conditions specification. 141 | 142 | :Usage: 143 | driver.set_network_conditions( 144 | offline=False, 145 | latency=5, # additional latency (ms) 146 | download_throughput=500 * 1024, # maximal throughput 147 | upload_throughput=500 * 1024) # maximal throughput 148 | 149 | Note: 'throughput' can be used to set both (for download and upload). 150 | """ 151 | self.execute("setNetworkConditions", { 152 | 'network_conditions': network_conditions 153 | }) 154 | 155 | def execute_cdp_cmd(self, cmd, cmd_args): 156 | """ 157 | Execute Edge Devtools Protocol command and get returned result 158 | 159 | The command and command args should follow Edge devtools protocol domains/commands, refer to link 160 | https://chromedevtools.github.io/devtools-protocol/ 161 | 162 | :Args: 163 | - cmd: A str, command name 164 | - cmd_args: A dict, command args. empty dict {} if there is no command args 165 | 166 | :Usage: 167 | driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}) 168 | 169 | :Returns: 170 | A dict, empty dict {} if there is no result to return. 171 | For example to getResponseBody: 172 | 173 | {'base64Encoded': False, 'body': 'response body string'} 174 | 175 | """ 176 | return self.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value'] 177 | 178 | def quit(self): 179 | """ 180 | Closes the browser and shuts down the EdgeDriver executable 181 | that is started when starting the EdgeDriver 182 | """ 183 | try: 184 | RemoteWebDriver.quit(self) 185 | except Exception: 186 | # We don't care about the message because something probably has gone wrong 187 | pass 188 | finally: 189 | self.service.stop() 190 | 191 | def create_options(self): 192 | return Options() 193 | -------------------------------------------------------------------------------- /py/setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Microsoft 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from os.path import dirname, join, abspath 16 | from setuptools import setup 17 | 18 | with open(join(abspath(dirname(__file__)), 'README.md'), 'r') as fh: 19 | long_description = fh.read() 20 | 21 | setup( 22 | name = 'msedge-selenium-tools', 23 | version = '3.141.4', 24 | description = 'An updated EdgeDriver implementation for Selenium 3 with newly-added support for Microsoft Edge (Chromium).', 25 | long_description = long_description, 26 | long_description_content_type = 'text/markdown', 27 | url = 'https://github.com/microsoft/edge-selenium-tools', 28 | author = 'Microsoft Corporation', 29 | author_email = 'EdgeDevToolsOSS@microsoft.com', 30 | license = 'Apache 2.0', 31 | packages = [ 32 | 'msedge', 33 | 'msedge.selenium_tools' 34 | ], 35 | install_requires = [ 36 | 'selenium==3.141' 37 | ], 38 | classifiers = [ 39 | 'Development Status :: 5 - Production/Stable', 40 | 'Intended Audience :: Developers', 41 | 'License :: OSI Approved :: Apache Software License', 42 | 'Operating System :: POSIX', 43 | 'Operating System :: Microsoft :: Windows', 44 | 'Operating System :: MacOS :: MacOS X', 45 | 'Topic :: Software Development :: Testing', 46 | 'Topic :: Software Development :: Libraries', 47 | 'Programming Language :: Python', 48 | 'Programming Language :: Python :: 2.7', 49 | 'Programming Language :: Python :: 3.4', 50 | 'Programming Language :: Python :: 3.5', 51 | 'Programming Language :: Python :: 3.6' 52 | ], 53 | zip_safe = False 54 | ) -------------------------------------------------------------------------------- /py/tests/edge_driver_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Microsoft 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import unittest 16 | import sys 17 | import os 18 | 19 | sys.path.insert(1, os.path.join(sys.path[0], '..')) 20 | from msedge.selenium_tools import Edge, EdgeOptions, EdgeService 21 | 22 | class EdgeDriverTest(unittest.TestCase): 23 | 24 | @unittest.skip(reason="Edge Legacy is not available on Azure hosted environment.") 25 | def test_default(self): 26 | try: 27 | driver = Edge() 28 | cap = driver.capabilities 29 | self.assertEqual('MicrosoftEdge', cap['browserName'], 'Driver launches Edge Legacy.') 30 | except: 31 | self.assertTrue(False, 'Test default options failed.') 32 | else: 33 | driver.quit() 34 | 35 | @unittest.skip(reason="Edge Legacy is not available on Azure hosted environment.") 36 | def test_legacy_options(self): 37 | try: 38 | options = EdgeOptions() 39 | options.use_chromium = False 40 | driver = Edge(options = options) 41 | cap = driver.capabilities 42 | self.assertEqual('MicrosoftEdge', cap['browserName'], 'Driver launches Edge Legacy.') 43 | except: 44 | self.assertTrue(False, 'Test legacy options failed.') 45 | else: 46 | driver.quit() 47 | 48 | def test_chromium_options(self): 49 | try: 50 | options = EdgeOptions() 51 | options.use_chromium = True 52 | driver = Edge(options = options) 53 | cap = driver.capabilities 54 | self.assertEqual('msedge', cap['browserName'], 'Driver launches Edge Chromium.') 55 | 56 | result = driver.execute_cdp_cmd('Browser.getVersion', {}) 57 | self.assertTrue('userAgent' in result, 'Driver can send Chromium-specific commands.') 58 | except: 59 | self.assertTrue(False, 'Test chromium options failed.') 60 | else: 61 | driver.quit() 62 | 63 | def test_chromium_driver_with_chromium_options(self): 64 | options = EdgeOptions() 65 | options.use_chromium = True 66 | try: 67 | driver = Edge('msedgedriver.exe', options=options) 68 | except: 69 | self.assertTrue(False, 'Test chromium driver with chromium options failed.') 70 | else: 71 | driver.quit() 72 | 73 | @unittest.skip(reason="Edge Legacy is not available on Azure hosted environment.") 74 | def test_legacy_driver_with_legacy_options(self): 75 | options = EdgeOptions() 76 | try: 77 | driver = Edge('MicrosoftWebDriver.exe', options=options) 78 | except Exception as e: 79 | self.assertTrue(False, 'Test legacy driver with legacy options failed.') 80 | else: 81 | driver.quit() 82 | 83 | def test_chromium_options_to_capabilities(self): 84 | options = EdgeOptions() 85 | options.use_chromium = True 86 | options._page_load_strategy = 'eager' # common 87 | options._debugger_address = 'localhost:9222' # chromium only 88 | 89 | cap = options.to_capabilities() 90 | self.assertEqual('MicrosoftEdge', cap['browserName']) 91 | self.assertIn('ms:edgeOptions', cap) 92 | self.assertTrue(cap['ms:edgeChromium']) 93 | 94 | edge_options_dict = cap['ms:edgeOptions'] 95 | self.assertIsNotNone(edge_options_dict) 96 | self.assertEqual('localhost:9222', edge_options_dict['debuggerAddress']) 97 | 98 | def test_legacy_options_to_capabilities(self): 99 | options = EdgeOptions() 100 | options._page_load_strategy = 'eager' # common 101 | options._debugger_address = 'localhost:9222' # chromium only 102 | 103 | cap = options.to_capabilities() 104 | self.assertEqual('MicrosoftEdge', cap['browserName']) 105 | self.assertEqual('eager', cap['pageLoadStrategy']) 106 | self.assertFalse('ms:edgeOptions' in cap) 107 | self.assertFalse(cap['ms:edgeChromium']) 108 | 109 | def test_webview_options_to_capabilities(self): 110 | options = EdgeOptions() 111 | options.use_chromium = True 112 | options.use_webview = True 113 | 114 | cap = options.to_capabilities() 115 | self.assertEqual('webview2', cap['browserName']) 116 | 117 | if __name__=='__main__': 118 | unittest.main() --------------------------------------------------------------------------------