Functions/Invoke-UIAutomationScript.ps1

<#
.SYNOPSIS
    This function invokes a UI automation script.
.DESCRIPTION
    This function invokes a UI automation script.
#>

function Invoke-UIAutomationScript {
    [CmdletBinding(PositionalBinding=$false)]
    [OutputType([String])]
    param (
        # The string containing the script.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$script,

        # The name of the script.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$name,

        # The path to the folder containing the Node package used to execute the script.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({ Test-Path -Path $_ })]
        [String]$nodePackagePath
    )

    # Retrieve the original location
    $originalLocation = Get-Location

    # Invoke the script
    try {
        # Change location to the Node package
        Set-Location -Path $nodePackagePath

        # Write the script to the file
        $script | Out-File -FilePath "$($name).js" -Encoding "utf8"

        # Call the script
        $output = (Invoke-Expression -Command "node $($name).js *>&1") | Out-String
        $exitCode = $LastExitCode

        # Process the output
        # Error result
        if ($exitCode -ne 0) {
            $success = $false
            # Check output
            if (![String]::IsNullOrWhiteSpace($output)) {
                # Check for timeout error
                if ($output -match "timeout [\w]* exceeded") {
                    # Timeout is due to selector
                    if ($output -match 'Error: waiting for selector "(.*?)" failed') {
                        $result = "Timeout on selector '$($Matches[1])'."
                    }

                    # Timeout is due to some other source
                    else {
                        $result = $output
                    }
                }

                # Some other error
                else {
                    $result = $output
                }
            }
        }

        # Success result
        else {
            $success = $true
            $result = $output
        }

        # Return the result
        return [PSCustomObject]@{
            Success = $success
            Result  = $result
        }
    }
    catch {
        $result = "Exception occurred on line $($_.InvocationInfo.ScriptLineNumber): `r`n$($_.Exception.Message)"
        Write-Error $result

        # Return the result
        return [PSCustomObject]@{
            Success = $false
            Result  = $result
        }
    }
    finally {
        # Set the location back to the original location
        Set-Location -Path $originalLocation
    }
}