#!/bin/bash $null = New-Module { . "$PSScriptRoot/System.ps1"; <# .SYNOPSIS Imports the resources for using browser automation. #> function Import-BrowserAutomation { if (-not ("OpenQA.Selenium.Firefox.FirefoxDriver" -as [type])) { $packageRoot = Split-Path -Parent (Get-Package Selenium.WebDriver).Source; $file = Join-Path $packageRoot "lib/netstandard2.0/WebDriver.dll"; $env:SE_MANAGER_PATH = Join-Path $packageRoot "manager" ($IsWindows ? "windows" : "linux") "selenium-manager$($IsWindows ? ".exe" : '')"; $null = [System.Reflection.Assembly]::LoadFile($file); } } <# .SYNOPSIS Runs an action involving browser automation. .PARAMETER Action The action to execute. #> function Start-BrowserAutomation { param( [scriptblock] $Action ) Import-BrowserAutomation; & $Action; } <# .SYNOPSIS Downloads a file from the specified url using browser automation. .PARAMETER URL The url to download the file from. .PARAMETER Action The action to execute in the browser for initiating the download. .PARAMETER OutDir The directory to download the file to. #> function Start-CustomBrowserDownload { param( [string] $URL, [scriptblock] $Action, [string] $OutDir ) $downloadAction = $Action; Start-BrowserAutomation { if (-not $OutDir) { $OutDir = "."; } $dir = New-TemporaryDirectory; Write-Host "Downloading ``$URL`` using browser automation…"; $options = [OpenQA.Selenium.Firefox.FirefoxOptions]::new(); $options.SetPreference("browser.download.folderList", 2); $options.SetPreference("browser.download.dir", "$dir"); $downloadChecker = { $files = Get-ChildItem $dir; if ((@($files)).Count -eq 1) { $file = $files[0]; try { $stream = [System.IO.File]::Open($file.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None); if ($stream) { $stream.Close(); } } catch { return $true; } return $false; } else { return $true; } }; $browser = [OpenQA.Selenium.Firefox.FirefoxDriver]::new($options); $browser.Navigate().GoToUrl($URL); while (-not ($browser.ExecuteScript("return document.readyState;") -eq "complete")) { Start-Sleep 0.1; } try { $null = & $downloadAction -Browser $browser; while (& $downloadChecker) { Write-Host "Waiting for the download to finish…"; Start-Sleep 1; } $file = Get-ChildItem $dir; $result = Move-Item $file $OutDir -PassThru; $browser.Quit(); Remove-Item -Recurse $dir; $result; } catch { Write-Error $_; } } } <# .SYNOPSIS Downloads a file from the specified url using browser automation. .PARAMETER URL The url to download the file from. .PARAMETER ButtonSelector The jQuery selector for finding the download button. .PARAMETER OutDir The directory to download the file to. .PARAMETER Timeout The number of seconds to wait before clicking the download button. #> function Start-BrowserDownload { param( [string] $URL, $ButtonSelector, [string] $OutDir = $null, [double] $Timeout = 0 ) Start-CustomBrowserDownload @PSBoundParameters -Action { param( [OpenQA.Selenium.Firefox.FirefoxDriver] $Browser ) if ($ButtonSelector -is [string]) { $selector = [OpenQA.Selenium.By]::CssSelector($ButtonSelector); } else { $selector = $ButtonSelector; } [OpenQA.Selenium.IWebElement] $element = $null; for ($i = 0; $i -lt 5; $i++) { $element = $Browser.FindElement($selector); if ($element) { break; } else { Start-Sleep 1; } } if ($Timeout -gt 0) { Start-Sleep $Timeout; } if ($element) { $Browser.FindElement($selector).Click(); } else { Write-Error "Unable to find download button!"; } }; } };