forked from blueimp/wdio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
webdriver.ps1
300 lines (274 loc) · 9.5 KB
/
webdriver.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
<#
Installs and starts Webdriver servers for IE and Microsoft Edge on Windows 10.
Installs and starts NGINX as reverse proxy for remote Webdriver connections.
Installs and starts MJPEGServer and FFmpeg for screen recordings.
Edits registry properties to configure IE and Microsoft Edge.
Copyright 2019, Sebastian Tschan
https://blueimp.net
Licensed under the MIT license:
https://opensource.org/licenses/MIT
Resources:
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver
https://nginx.org/en/docs/windows.html
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSUseShouldProcessForStateChangingFunctions', ''
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingPositionalParameters', ''
)]
param()
$ErrorActionPreference = 'Stop' # Stop if a cmdlet fails
$ffmpegOptions = @{
fps = '15'
quality = '2' # Value between 2 (best) and 31 (worst)
}
$versions = @{
nginx = '1.15.9'
IEDriver = '3.141.5'
ffmpeg = '4.1.1'
MJPEGServer = '1.2.0'
}
$downloads = @{
nginx = 'https://nginx.org/download/nginx-{0}.zip' -f $versions.nginx
# Using the 32bit IEDriverServer (64bit version has performance issues).
# The download URL contains the version number twice.
# Once as directory with the major.minor version and once in the file name
# with the full version string:
IEDriver = ('https://selenium-release.storage.googleapis.com/' +
'{0}/IEDriverServer_Win32_{1}.zip') `
-f ($versions.IEDriver.split('.')[0..1] -join '.'),$versions.IEDriver
ffmpeg = ('https://ffmpeg.zeranoe.com/builds/win64/static/' +
'ffmpeg-{0}-win64-static.zip') -f $versions.ffmpeg
MJPEGServer = ('https://github.com/blueimp/mjpeg-server/releases/download/' +
'v{0}/mjpeg-server-windows-amd64.zip') -f $versions.MJPEGServer
}
$ffmpegCommand = ('ffmpeg' +
' -loglevel error' +
' -probesize 32' +
' -fpsprobesize 0' +
' -analyzeduration 0' +
' -fflags nobuffer' +
' -f gdigrab' +
' -r {0}' +
' -i desktop' +
' -f mpjpeg' +
' -q {1}' +
' -') -f $ffmpegOptions.fps,$ffmpegOptions.quality
# NGINX configuration as reverse proxy for Edge WebDriver and IEDriverServer:
$nginxConfig = '
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 4444;
location / {
proxy_pass http://localhost:17556;
}
}
server {
listen 4445;
location / {
proxy_pass http://localhost:5555;
}
}
}
'
# Relative install paths to add to the PATH environment variable:
$installPaths = @('bin', 'nginx', 'ffmpeg\bin')
# Runs the given command with Administrator privileges:
function Invoke-AdminCommand {
param([String]$command, [String]$params, [String]$reason)
Clear-Host
'Requesting Administrator privileges {0}...' -f $reason
Start-Process $command $params -Verb RunAs -Wait
}
# Runs the given Powershell command with Administrator privileges:
function Invoke-PowershellAdminCommand {
param([String]$command, [String]$reason)
$params = "-ExecutionPolicy ByPass -command $($command -replace '"','\"')"
Invoke-AdminCommand powershell $params $reason
}
# Sets a registry DWord property.
# Also creates the parent path if it does not exist:
function Set-RegistryDWord {
param([String]$path, [String]$name, [int]$value)
$prop = Get-ItemProperty $path $name -ErrorAction SilentlyContinue
if (!$prop) {
if (!(Test-Path $path)) {
# -Force option is required if the parent path does not exist:
New-Item $path -Force
}
New-ItemProperty $path $name -PropertyType DWord -Value $value
} elseif ($prop.$name -ne $value) {
Set-ItemProperty $path -Name $name $value
}
}
# Edits HKEY_CURRENT_USER (HKCU) registry:
function Edit-CurrentUserRegistry {
# Set the same Protected Mode for all Internet Zones by copying the property
# from zone 4 (Restricted Sites) of the default settings (HKLM) to zones 1-4
# of the user settings (HKCU):
#
# Zone | Setting
# ---- | ---------------------
# 0 | My Computer
# 1 | Local Intranet Zone
# 2 | Trusted sites Zone
# 3 | Internet Zone
# 4 | Restricted Sites Zone
#
$path = '\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones'
# 2500 is the property key for the Protected Mode setting:
$name = '2500'
foreach ($zone in @(1, 2, 3, 4)) {
Copy-ItemProperty "HKLM:$path\4" -Name $name "HKCU:$path\$zone"
}
# Enable the driver to maintain a connection to the instance of Internet
# Explorer it creates:
$path = 'HKCU:\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main' +
'\FeatureControl\FEATURE_BFCACHE'
Set-RegistryDWord $path iexplore.exe 0
# Path to IE user settings:
$path = 'HKCU:\Software\Microsoft\Internet Explorer'
# Disable IE Compatibility View for Intranet Sites:
Set-RegistryDWord "$path\BrowserEmulation" IntranetCompatibilityMode 0
# Disable "Preserve Favorites website data":
Set-RegistryDWord "$path\Privacy" UseAllowList 0
# Clear IE browsing history on exit:
Set-RegistryDWord "$path\Privacy" ClearBrowsingHistoryOnExit 1
# Disable the IE first run page:
Set-RegistryDWord "$path\Main" DisableFirstRunCustomize 1
# Path to Microsoft Edge user settings:
$path = 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows' +
'\CurrentVersion\AppContainer\Storage' +
'\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge'
# Clear Microsoft Edge browsing history on exit:
Set-RegistryDWord "$path\Privacy" ClearBrowsingHistoryOnExit 1
# Disable the Microsoft Edge first run page:
Set-RegistryDWord "$path\Main" PreventFirstRunPage 1
}
# Overwrites the Windows hosts file with the file windows.hosts, if available:
function Update-HostsFile {
$newHostsFile = "$(Get-Location)\windows.hosts"
if (Test-Path $newHostsFile) {
$hostsFile = "$env:windir\System32\drivers\etc\hosts"
if ((Get-FileHash $hostsFile).hash -ne (Get-FileHash $newHostsFile).hash) {
$command = 'Copy-Item "{0}" "{1}"' -f $newHostsFile,$hostsFile
Invoke-PowershellAdminCommand $command 'to overwrite the hosts file'
}
}
}
# Downloads and extracts a ZIP file provided as URL:
function Invoke-ZipDownload {
param([String]$url)
$filename = [IO.Path]::GetRandomFileName() + '.zip'
Invoke-WebRequest $url -OutFile $filename
Expand-Archive $filename .
Remove-Item $filename
}
# Returns the Windows build number:
function Get-WindowsBuildNumber {
(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' `
'CurrentBuild').CurrentBuild
}
# Installs MicrosoftWebDriver via "Windows Feature on Demand":
function Install-MicrosoftWebDriver {
# Windows versions before build 17763 do not have MicrosoftWebDriver as
# "Windows Feature on Demand" and only support older Edge versions.
# See https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
if ((Get-WindowsBuildNumber) -lt 17763) { return }
if (!(Get-Command MicrosoftWebDriver -ErrorAction SilentlyContinue)) {
$capabilityName = 'Microsoft.WebDriver~~~~0.0.1.0'
Invoke-AdminCommand DISM `
"/Online /Add-Capability /CapabilityName:$capabilityName" `
'for WebDriver installation'
}
}
# Installs IEDriverServer:
function Install-IEDriverServer {
if (!(Test-Path bin\IEDriverServer.exe)) {
New-Item bin -ItemType Directory -Force
Clear-Host
'Installing IEDriverServer ...'
Invoke-ZipDownload $downloads.IEDriver
Move-Item IEDriverServer.exe bin
}
}
# Installs and configures nginx:
function Install-NGINX {
if (!(Test-Path nginx)) {
Clear-Host
'Installing nginx ...'
Invoke-ZipDownload $downloads.nginx
Move-Item nginx-* nginx
$nginxConfig | Out-File nginx\conf\nginx.conf ASCII
}
}
# Installs ffmpeg:
function Install-FFmpeg {
if (!(Test-Path ffmpeg)) {
Clear-Host
'Installing ffmpeg ...'
Invoke-ZipDownload $downloads.ffmpeg
Move-Item ffmpeg-* ffmpeg
}
}
# Installs MJPEGServer:
function Install-MJPEGServer {
if (!(Test-Path bin\MJPEGServer.exe)) {
New-Item bin -ItemType Directory -Force
Clear-Host
'Installing MJPEGServer ...'
Invoke-ZipDownload $downloads.MJPEGServer
Move-Item MJPEGServer.exe bin
}
}
# Updates the PATH environment variable with the installed program paths:
function Update-Path {
$currentPath = $(Get-Location)
$originalEnvPath = $env:Path
$pathComponents = $originalEnvPath.TrimEnd(';') -split ';'
foreach ($path in $installPaths) {
if ($pathComponents -notcontains "$currentPath\$path") {
$pathComponents += "$currentPath\$path"
}
}
$env:Path = ($pathComponents -join ';') + ';'
if ($env:Path -ne $originalEnvPath) {
[Environment]::SetEnvironmentVariable(
'Path',
$env:Path,
[System.EnvironmentVariableTarget]::User
)
}
}
# Starts nginx, IEDriverServer and MicrosoftWebDriver (if installed).
# Waits for IEDriverServer to close, then sends nginx the stop signal:
function Start-Service {
Clear-Host
'========================================================'
'IMPORTANT: Do not close this window manually.'
'It will close automatically when MJPEGServer is stopped.'
'========================================================'
'Starting servers ...'
if (Get-Command MicrosoftWebDriver -ErrorAction SilentlyContinue) {
Start-Process MicrosoftWebDriver
}
Start-Process IEDriverServer
Start-Process nginx -WorkingDirectory nginx
Start-Process MJPEGServer $ffmpegCommand -Wait
Start-Process nginx '-s stop' -WorkingDirectory nginx
}
Edit-CurrentUserRegistry
Update-HostsFile
Install-MicrosoftWebDriver
Install-IEDriverServer
Install-NGINX
Install-FFmpeg
Install-MJPEGServer
Update-Path
Start-Service