all repos — caroster @ 1eff8c695a32beae4a1bd07c45c45ec05f27a0f4

[Octree] Group carpool to your event https://caroster.io

backend/e2e/bin/webdriver.ps1 (view raw)

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