init commit
This commit is contained in:
113
Initialize-PPT.ps1
Normal file
113
Initialize-PPT.ps1
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
function Initialize-PPT {
|
||||||
|
[CmdLetBinding()]
|
||||||
|
Param (
|
||||||
|
$Path = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
$PSScriptRoo = "C:\Users\DC21520\OneDrive - Defense Information Systems Agency\Documents\WindowsPowerShell\Modules\posh-PowerPlatformToolkit"
|
||||||
|
|
||||||
|
$Path = @{
|
||||||
|
qualifier = (Split-Path -Path $Path -Qualifier)
|
||||||
|
parent = (Split-Path -Path $Path)
|
||||||
|
leaf = (Split-Path -Path $Path -Leaf)
|
||||||
|
path = $Path
|
||||||
|
pathBuild = (Join-Path -Path $Path -ChildPath 'Build')
|
||||||
|
pathConfig = (Join-Path -Path $Path -ChildPath 'Build\config.json')
|
||||||
|
sourcePath = (Join-Path -Path $PSScriptRoot -ChildPath 'source')
|
||||||
|
sourceConfig = (Join-Path -Path $PSScriptRoot -ChildPath 'source\config.ps1')
|
||||||
|
sourceIgnore = (Join-Path -Path $PSScriptRoot -ChildPath 'source\.gitignore')
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nInitializing Power Platform Toolkit in:" -ForegroundColor Cyan
|
||||||
|
Write-Host "$($Path.path)" -BackgroundColor DarkCyan -ForegroundColor Black
|
||||||
|
|
||||||
|
do {
|
||||||
|
$initContinue = Read-Host "`nDo you want to continue (y/n) "
|
||||||
|
$initContinue = $initContinue.ToLower()
|
||||||
|
} while ($initContinue -notmatch 'y|n')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
switch ($initContinue) {
|
||||||
|
|
||||||
|
'y' { Write-Host "Initializing Power Platform Toolkit..." -ForegroundColor Cyan; $initContinue = $null }
|
||||||
|
'n' { Write-Host "Seems like you need to give this a little more thought... I can wait." -ForegroundColor Yellow; $initContinue = $null; return }
|
||||||
|
default { Write-Warning "Unexpected error"; $initContinue = $null; return }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Test-Path -Path $Path.pathConfig) {
|
||||||
|
|
||||||
|
Write-Host "`nPower Platform Toolkit was already initialized for this directory!" -ForegroundColor Yellow
|
||||||
|
Write-Host "Initializing again will overwrite your current configuration." -BackgroundColor DarkYellow -ForegroundColor Black
|
||||||
|
|
||||||
|
do {
|
||||||
|
$initContinue = Read-Host "`nDo you want to continue (y/n) "
|
||||||
|
$initContinue = $initContinue.ToLower()
|
||||||
|
} while ($initContinue -notmatch 'y|n')
|
||||||
|
|
||||||
|
switch ($initContinue) {
|
||||||
|
|
||||||
|
'y' { Write-Host "Initializing Power Platform Toolkit..." -ForegroundColor Cyan; $initContinue = $null }
|
||||||
|
'n' { Write-Host "Seems like you need to give this a little more thought... I can wait." -ForegroundColor Yellow; $initContinue = $null; return }
|
||||||
|
default { Write-Warning -Message "Unexpected error"; $initContinue = $null; return }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
New-Item -Path $Path.PathBuild -ItemType Directory -Verbose -Force -ErrorAction Stop > $null
|
||||||
|
New-Item -Path $Path.pathConfig -ItemType File -Verbose -Force -ErrorAction Stop > $null
|
||||||
|
Copy-Item -Path $Path.sourceIgnore -Destination $Path.path -Verbose -Force -ErrorAction Stop > $null
|
||||||
|
Copy-Item -Path "$($Path.sourcePath)\README.md" -Destination $Path.path -Verbose -Force -ErrorAction Stop > $null
|
||||||
|
. $Path.sourceConfig | ConvertTo-Json -Verbose > $Path.pathConfig
|
||||||
|
|
||||||
|
} catch [System.Exception] {
|
||||||
|
|
||||||
|
Write-Warning -Message "$($_.Exception.Message)"
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# FEATURE DEVELOPMENT ON LATER RELEASE
|
||||||
|
<#
|
||||||
|
do {
|
||||||
|
|
||||||
|
Write-Host "`nGit Repository Parent Group Options" -BackgroundColor DarkCyan -ForegroundColor Black
|
||||||
|
Write-Host "Select the Parent Group for " -NoNewline -ForegroundColor Cyan; Write-Host "$($Path.leaf)" -ForegroundColor Green
|
||||||
|
for ($i = 0; $i -lt $pptConfig.gitParentGroup.Count; $i++) {
|
||||||
|
Write-Host "[$($i + 1)] $($Global:pptConfig.gitParentGroup[$i])"
|
||||||
|
}
|
||||||
|
$parentGroup = Read-Host "Group "
|
||||||
|
|
||||||
|
} while ($parentGroup -notin (1..$pptConfig.gitParentGroup.Count))
|
||||||
|
do {
|
||||||
|
|
||||||
|
Write-Host "`nGit Repository Child Group Options" -BackgroundColor DarkCyan -ForegroundColor Black
|
||||||
|
Write-Host "Select the Child Group for " -NoNewline -ForegroundColor Cyan; Write-Host "$($Path.leaf)" -ForegroundColor Green
|
||||||
|
for ($i = 0; $i -lt $pptConfig.gitChildGroup.Count; $i++) {
|
||||||
|
Write-Host "[$($i + 1)] $($Global:pptConfig.gitChildGroup[$i])"
|
||||||
|
}
|
||||||
|
$childGroup = Read-Host "Group "
|
||||||
|
|
||||||
|
} while ($childGroup -notin (1..$pptConfig.gitChildGroup.Count))
|
||||||
|
#>
|
||||||
|
# FEATURE DEVELOPMENT ON LATER RELEASE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# EXPORT ALIAS
|
||||||
|
New-Alias -Name init -Value Initialize-PPT -Description 'posh-PowerPlatformToolkit - Initialize-PPT alias' -Force
|
||||||
52
New-PPTAuth.ps1
Normal file
52
New-PPTAuth.ps1
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
function New-PPTAuth {
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-host "Creating authentication profile" -ForegroundColor Cyan
|
||||||
|
#Start-Process -FilePath $Global:pptConfig.pacPath
|
||||||
|
& $Global:pptConfig.pacPath auth clear | ForEach-Object {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-host "$_" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
$isAuth = $false
|
||||||
|
& $Global:pptConfig.pacPath auth create --cloud UsGovDod --deviceCode | ForEach-Object {
|
||||||
|
if ($_ -match 'To sign in, use a web browser to open the page') {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-host "$_" -ForegroundColor Cyan
|
||||||
|
Set-Clipboard -Value "$(($_ -split "To sign in, use a web browser to open the page | and enter the code | to authenticate.")[2])"
|
||||||
|
Start-Process microsoft-edge:https://microsoft.com/deviceloginus -OutVariable procout
|
||||||
|
} else {
|
||||||
|
if ($_ -match 'authenticated successfully') {
|
||||||
|
$isAuth = $true
|
||||||
|
}
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-host "$_" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
if($isAuth) {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-host "Authentication complete" -ForegroundColor Cyan
|
||||||
|
return $true
|
||||||
|
} else {
|
||||||
|
Write-Host "[ Error ] " -ForegroundColor Yellow -nonewline
|
||||||
|
Write-Host "No profiles were found on this computer" -ForegroundColor Yellow
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Alias -Name auth -Value New-PPTAuth -Description 'posh-PowerPlatformToolkit - New-PPTAuth alias' -Force
|
||||||
79
New-PPTSettings.ps1
Normal file
79
New-PPTSettings.ps1
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
function New-PPTSettings {
|
||||||
|
[CmdLetBinding()]
|
||||||
|
Param (
|
||||||
|
$Path = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
$Path = @{
|
||||||
|
qualifier = (Split-Path -Path $Path -Qualifier)
|
||||||
|
parent = (Split-Path -Path $Path)
|
||||||
|
leaf = (Split-Path -Path $Path -Leaf)
|
||||||
|
path = $Path
|
||||||
|
pathBuild = (Join-Path -Path $Path -ChildPath 'Build')
|
||||||
|
pathConfig = (Join-Path -Path $Path -ChildPath 'Build\config.json')
|
||||||
|
sourcePath = (Join-Path -Path $PSScriptRoot -ChildPath 'source')
|
||||||
|
sourceConfig = (Join-Path -Path $PSScriptRoot -ChildPath 'source\config.ps1')
|
||||||
|
sourceIgnore = (Join-Path -Path $PSScriptRoot -ChildPath 'source\.gitignore')
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = (Get-Content $Path.pathConfig | ConvertFrom-Json)
|
||||||
|
|
||||||
|
If((Get-ChildItem -Path $Path.path -Name *.zip).Count -ge 1) {
|
||||||
|
$index = 1
|
||||||
|
$solutions = Get-ChildItem -Path $Path.path -Name *.zip | Get-Item | ForEach-Object {
|
||||||
|
@{
|
||||||
|
$index++ = @{
|
||||||
|
id = $index - 1
|
||||||
|
name = "$($_.Name)"
|
||||||
|
fullname = $_.FullName
|
||||||
|
directory = $_.Directory
|
||||||
|
basename = $_.BaseName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`tPACKAGES AVAILABLE IN CURRENT PROJECT`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
$solutions | %{"[ {0} ] {1}" -f $_.Values.id,$_.Values.basename}
|
||||||
|
$solutionsId = Read-Host -Prompt "`nSelect Solution Package ($((1..$solutions.Values.id.Count) -join ','))"
|
||||||
|
} while ($solutionsId -notin (1..$solutions.Values.id.Count))
|
||||||
|
$solutionSelectd = ($solutions | ?{$_.Values.id -eq $solutionsId})
|
||||||
|
|
||||||
|
$Path.leaf = $solutionSelectd.Values.basename
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($env in $config.env) {
|
||||||
|
|
||||||
|
$settingsFile = "$($env.name.ToUpper()).$($env.env_id).$($Path.leaf).json"
|
||||||
|
$IsSolutionPresent = Test-Path -Path "$($Path.path)\$($Path.leaf).zip"
|
||||||
|
|
||||||
|
if($IsSolutionPresent) {
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Generating Solution Settings File" -ForegroundColor Cyan
|
||||||
|
& $Global:pptConfig.pacPath solution create-settings --solution-zip "$($Path.path)\$($Path.leaf).zip" --settings-file $settingsFile
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Write-Host '[ Error ] ' -ForegroundColor Yellow -nonewline; write-host "Solution Package Missing: $($Path.path)\$($Path.leaf).zip" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# EXPORT ALIAS
|
||||||
|
New-Alias -Name settings -Value New-PPTSettings -Description 'posh-PowerPlatformToolkit - New-PPTSettings alias' -Force
|
||||||
93
README.md
Normal file
93
README.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# posh-PowerPlatformToolkit
|
||||||
|
|
||||||
|
> TODO: Update README markdown documentaiton
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||||
|
|
||||||
|
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||||
|
|
||||||
|
## Add your files
|
||||||
|
|
||||||
|
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||||
|
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd existing_repo
|
||||||
|
git remote add origin https://gitlab.dcma.mil/sdg/powershell/posh-PowerPlatformToolkit.git
|
||||||
|
git branch -M main
|
||||||
|
git push -uf origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrate with your tools
|
||||||
|
|
||||||
|
- [ ] [Set up project integrations](https://gitlab.dcma.mil/sdg/powershell/posh-PowerPlatformToolkit/-/settings/integrations)
|
||||||
|
|
||||||
|
## Collaborate with your team
|
||||||
|
|
||||||
|
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||||
|
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||||
|
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||||
|
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||||
|
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||||
|
|
||||||
|
## Test and Deploy
|
||||||
|
|
||||||
|
Use the built-in continuous integration in GitLab.
|
||||||
|
|
||||||
|
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||||
|
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||||
|
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||||
|
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||||
|
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
# Editing this README
|
||||||
|
|
||||||
|
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||||
|
|
||||||
|
## Suggestions for a good README
|
||||||
|
|
||||||
|
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||||
|
|
||||||
|
## Name
|
||||||
|
Choose a self-explaining name for your project.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||||
|
|
||||||
|
## Badges
|
||||||
|
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||||
|
|
||||||
|
## Visuals
|
||||||
|
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
State if you are open to contributions and what your requirements are for accepting them.
|
||||||
|
|
||||||
|
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||||
|
|
||||||
|
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||||
|
|
||||||
|
## Authors and acknowledgment
|
||||||
|
Show your appreciation to those who have contributed to the project.
|
||||||
|
|
||||||
|
## License
|
||||||
|
For open source projects, say how it is licensed.
|
||||||
|
|
||||||
|
## Project status
|
||||||
|
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||||
73
Start-PPT-SolutionRepack.ps1
Normal file
73
Start-PPT-SolutionRepack.ps1
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
function Start-PPTSolutionRepack {
|
||||||
|
[CmdLetBinding()]
|
||||||
|
Param(
|
||||||
|
$Path = (Get-Location).Path,
|
||||||
|
[Alias('m')]
|
||||||
|
[switch]$Managed
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
$Path = @{
|
||||||
|
qualifier = (Split-Path -Path $Path -Qualifier)
|
||||||
|
parent = (Split-Path -Path $Path)
|
||||||
|
leaf = (Split-Path -Path $Path -Leaf)
|
||||||
|
path = $Path
|
||||||
|
pathBuild = (Join-Path -Path $Path -ChildPath 'Build')
|
||||||
|
pathConfig = (Join-Path -Path $Path -ChildPath 'Build\config.json')
|
||||||
|
sourcePath = (Join-Path -Path $PSScriptRoot -ChildPath 'source')
|
||||||
|
sourceConfig = (Join-Path -Path $PSScriptRoot -ChildPath 'source\config.ps1')
|
||||||
|
sourceIgnore = (Join-Path -Path $PSScriptRoot -ChildPath 'source\.gitignore')
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = (Get-Content $Path.pathConfig | ConvertFrom-Json)
|
||||||
|
$env = ($config.env | ?{$_.name -eq $Environment})
|
||||||
|
|
||||||
|
function NameThatSolution () {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`t`tNAME THAT SOLUTION`t`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
do {
|
||||||
|
$solutionNameProvided = Read-Host -Prompt "Enter Solution Package name"
|
||||||
|
If($solutionNameProvided -match '\s*(\W+?)') {
|
||||||
|
Write-Host "We had to fix a few things with the Solution Package name provided [" -NoNewline -ForegroundColor Yellow
|
||||||
|
Write-Host "$($solutionNameProvided)" -NoNewLine -ForegroundColor White
|
||||||
|
Write-Host "]`nHope you're not too upset." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
$solutionNewName = $solutionNameProvided -replace ('\s*(\W+?)', '')
|
||||||
|
Write-Host "`n$(If($solutionNameProvided -match '\s*(\W+?)'){"A little fixer upper: "}Else{"Solution Package Name:"})" -NoNewline -ForegroundColor Green
|
||||||
|
Write-Host "$($solutionNewName)" -ForegroundColor Magenta
|
||||||
|
$continueSolutionName = Read-Host -Prompt "$(If($solutionNameProvided -match '\s*(\W+?)'){"We good?"}Else{"Continue"}) (y/n)"
|
||||||
|
} while ($continueSolutionName -ne 'y' -or $continueSolutionName -ne 'Y')
|
||||||
|
#$Path.leaf = $solutionNewName
|
||||||
|
return $solutionNewName
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
$Path.leaf = NameThatSolution
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Repacking $(If($Managed){'managed'}else{'unmanaged'}) solution used for deployment" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
foreach ($msapp in (Get-ChildItem -Path (Join-Path -Path $Path.path -ChildPath 'CanvasApps') -Filter '*.msapp')) {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Compiling $($msapp.basename.split('_')[1]) Binary Canvas Application" -ForegroundColor Cyan
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "$($msapp.Fullname)" -ForegroundColor Cyan
|
||||||
|
$applicationManifest = $null
|
||||||
|
$applicationManifest = Get-ChildItem -Path (Join-Path -Path $Path.path -ChildPath "CanvasApps\src") -Filter "*_$($msapp.basename.split('_')[1])_*"
|
||||||
|
& $Global:pptConfig.pacPath canvas pack --msapp $msapp.Fullname --sources "$($applicationManifest.Fullname)"
|
||||||
|
}
|
||||||
|
|
||||||
|
& $Global:pptConfig.pacPath solution pack --zipfile "$($Path.path)\$($Path.leaf).zip" --folder $Path.path --processCanvasApps --packagetype $(If($Managed){'Managed'}else{'Unmanaged'}) --errorLevel Verbose
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# EXPORT ALIAS
|
||||||
|
New-Alias -Name repack -Value Start-PPTSolutionRepack -Description 'posh-PowerPlatformToolkit - Start-PPTSolutionRepack alias' -Force
|
||||||
132
Start-PPTSolutionDeploy.ps1
Normal file
132
Start-PPTSolutionDeploy.ps1
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
function Start-PPTSolutionDeploy {
|
||||||
|
[CmdLetBinding()]
|
||||||
|
Param (
|
||||||
|
[ValidateSet('DCMA_DEV', 'DCMA_Sustainment', 'DCMA_TEST', 'DCMA_PROD', 'ACP-DCMA-CDE-DEV', 'ACP-DCMA-CDE-PROD')]
|
||||||
|
[string]$Environment,
|
||||||
|
$Path = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
$Path = @{
|
||||||
|
qualifier = (Split-Path -Path $Path -Qualifier)
|
||||||
|
parent = (Split-Path -Path $Path)
|
||||||
|
leaf = (Split-Path -Path $Path -Leaf)
|
||||||
|
path = $Path
|
||||||
|
pathBuild = (Join-Path -Path $Path -ChildPath 'Build')
|
||||||
|
pathConfig = (Join-Path -Path $Path -ChildPath 'Build\config.json')
|
||||||
|
sourcePath = (Join-Path -Path $PSScriptRoot -ChildPath 'source')
|
||||||
|
sourceConfig = (Join-Path -Path $PSScriptRoot -ChildPath 'source\config.ps1')
|
||||||
|
sourceIgnore = (Join-Path -Path $PSScriptRoot -ChildPath 'source\.gitignore')
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = (Get-Content $Path.pathConfig | ConvertFrom-Json)
|
||||||
|
$env = ($config.env | ?{$_.name -eq $Environment})
|
||||||
|
|
||||||
|
if (!$env) {
|
||||||
|
do {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`t`tCONFIGURED ENVIRONMENTS`t`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
$config.env | %{"[ {0} ] {1}" -f $_.id,$_.name}
|
||||||
|
$environmentId = Read-Host -Prompt "`nSelect Environment ($((1..$config.env.Count) -join ','))"
|
||||||
|
} while ($environmentId -notin (1..$config.env.Count))
|
||||||
|
$env = ($config.env | ?{$_.id -eq $environmentId})
|
||||||
|
}
|
||||||
|
|
||||||
|
If((Get-ChildItem -Path $Path.path -Name *.zip).Count -ge 1) {
|
||||||
|
$index = 1
|
||||||
|
$solutions = Get-ChildItem -Path $Path.path -Name *.zip | Get-Item | ForEach-Object {
|
||||||
|
@{
|
||||||
|
$index++ = @{
|
||||||
|
id = $index - 1
|
||||||
|
name = "$($_.Name)"
|
||||||
|
fullname = $_.FullName
|
||||||
|
directory = $_.Directory
|
||||||
|
basename = $_.BaseName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`tPACKAGES AVAILABLE IN CURRENT PROJECT`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
$solutions | %{"[ {0} ] {1}" -f $_.Values.id,$_.Values.basename}
|
||||||
|
$solutionsId = Read-Host -Prompt "`nSelect Solution Package ($((1..$solutions.Values.id.Count) -join ','))"
|
||||||
|
} while ($solutionsId -notin (1..$solutions.Values.id.Count))
|
||||||
|
$solutionSelectd = ($solutions | ?{$_.Values.id -eq $solutionsId})
|
||||||
|
|
||||||
|
$Path.leaf = $solutionSelectd.Values.basename
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
if(!(Test-Path "$($Path.path)\$($env.name).$($env.env_id).$($Path.leaf).json")) {
|
||||||
|
|
||||||
|
Write-Warning -Message "Missing settings file for $($env)"
|
||||||
|
return
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
Write-Host "Using settings for environment: $($env)" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<#if (!(Test-Path "$($Path.path)\DCMA_DEV*.json") -or !(Test-Path "$($Path.path)\DCMA_TEST*.json") -or !(Test-Path "$($Path.path)\DCMA_PROD*.json") -or !(Test-Path "$($Path.path)\ACP-DCMA-CDE-DEV*.json") -or !(Test-Path "$($Path.path)\ACP-DCMA-CDE_PROD*.json")) {
|
||||||
|
|
||||||
|
Write-Warning -Message "Missing settings file for environment(s)"
|
||||||
|
return
|
||||||
|
}#>
|
||||||
|
|
||||||
|
$pacAuthResponse = & $Global:pptConfig.pacPath auth list
|
||||||
|
|
||||||
|
switch ($pacAuthResponse) {
|
||||||
|
|
||||||
|
{$_ -match 'No profiles were found on this computer'} {
|
||||||
|
Write-Host "[ Error ] " -ForegroundColor Yellow -nonewline
|
||||||
|
Write-Host "No profiles were found on this computer" -ForegroundColor Yellow
|
||||||
|
$authResponse = auth
|
||||||
|
if ($authResponse) {
|
||||||
|
$IsAuth = $true
|
||||||
|
& $Global:pptConfig.pacPath org select -env $env.env_id
|
||||||
|
} else {
|
||||||
|
$IsAuth = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{$_ -match '\*'} {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
write-host "Authentication profile found" -ForegroundColor Cyan
|
||||||
|
$IsAuth = $true
|
||||||
|
& $Global:pptConfig.pacPath org select -env $env.env_id}
|
||||||
|
|
||||||
|
#Default {Write-Warning -Message "Unhandled exception"; return}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((& $Global:pptConfig.pacPath org list | ?{$_ -match '\*'}) -match $env.env_id -and $IsAuth) {
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Building solution package" -ForegroundColor Cyan
|
||||||
|
& $Global:pptConfig.pacPath solution import --path "$($Path.path)\$($Path.leaf).zip" --settings-file "$($env.name).$($env.env_id).$($Path.leaf).json" --activate-plugins --publish-changes
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Write-Host '[ Error ] ' -ForegroundColor Yellow -nonewline; write-host 'Fatal exception' -ForegroundColor Red
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# EXPORT ALIAS
|
||||||
|
New-Alias -Name deploySolution -Value Start-PPTSolutionDeploy -Description 'posh-PowerPlatformToolkit - Start-PPTSolutionDeploy alias' -Force
|
||||||
188
Start-PPTSolutionPull.ps1
Normal file
188
Start-PPTSolutionPull.ps1
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
function Start-PPTSolutionPull {
|
||||||
|
[CmdLetBinding()]
|
||||||
|
Param (
|
||||||
|
[Alias('env')]
|
||||||
|
[ValidateSet('DCMA_DEV', 'DCMA_Sustainment', 'DCMA_TEST', 'DCMA_PROD', 'ACP-DCMA-CDE-DEV', 'ACP-DCMA-CDE-PROD')]
|
||||||
|
[string]$Environment = 'DCMA_DEV',
|
||||||
|
$Path = (Get-Location).Path,
|
||||||
|
[Alias('m')]
|
||||||
|
[switch]$Managed,
|
||||||
|
[Alias('p')]
|
||||||
|
[switch]$Patch,
|
||||||
|
[Alias('sn')]
|
||||||
|
[switch]$SolutionName
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
$Path = @{
|
||||||
|
qualifier = (Split-Path -Path $Path -Qualifier)
|
||||||
|
parent = (Split-Path -Path $Path)
|
||||||
|
leaf = (Split-Path -Path $Path -Leaf)
|
||||||
|
path = $Path
|
||||||
|
pathBuild = (Join-Path -Path $Path -ChildPath 'Build')
|
||||||
|
pathConfig = (Join-Path -Path $Path -ChildPath 'Build\config.json')
|
||||||
|
sourcePath = (Join-Path -Path $PSScriptRoot -ChildPath 'source')
|
||||||
|
sourceConfig = (Join-Path -Path $PSScriptRoot -ChildPath 'source\config.ps1')
|
||||||
|
sourceIgnore = (Join-Path -Path $PSScriptRoot -ChildPath 'source\.gitignore')
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = (Get-Content $Path.pathConfig | ConvertFrom-Json)
|
||||||
|
$env = ($config.env | ?{$_.name -eq $Environment})
|
||||||
|
|
||||||
|
function ConfiguredEnvironments () {
|
||||||
|
if (!$env) {
|
||||||
|
do {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│`t`t`t`t`t`t`t`t│ -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`t`tCONFIGURED ENVIRONMENTS`t`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
$config.env | %{"[ {0} ] {1}" -f $_.id,$_.name}
|
||||||
|
$environmentId = Read-Host -Prompt "Select Environment ($((1..$config.env.Count) -join ','))"
|
||||||
|
} while ($environmentId -notin (1..$config.env.Count))
|
||||||
|
#$env = ($config.env | ?{$_.id -eq $environmentId})
|
||||||
|
return ($config.env | ?{$_.id -eq $environmentId})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function NameThatSolution () {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`t`tNAME THAT SOLUTION`t`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
do {
|
||||||
|
$solutionNameProvided = Read-Host -Prompt "Enter Solution Package name"
|
||||||
|
If($solutionNameProvided -match '\s*(\W+?)') {
|
||||||
|
Write-Host "We had to fix a few things with the Solution Package name provided [" -NoNewline -ForegroundColor Yellow
|
||||||
|
Write-Host "$($solutionNameProvided)" -NoNewLine -ForegroundColor White
|
||||||
|
Write-Host "]`nHope you're not too upset." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
$solutionNewName = $solutionNameProvided -replace ('\s*(\W+?)', '')
|
||||||
|
Write-Host "`n$(If($solutionNameProvided -match '\s*(\W+?)'){"A little fixer upper: "}Else{"Solution Package Name:"})" -NoNewline -ForegroundColor Green
|
||||||
|
Write-Host "$($solutionNewName)" -ForegroundColor Magenta
|
||||||
|
$continueSolutionName = Read-Host -Prompt "$(If($solutionNameProvided -match '\s*(\W+?)'){"We good?"}Else{"Continue"}) (y/n)"
|
||||||
|
} while ($continueSolutionName -ne 'y' -or $continueSolutionName -ne 'Y')
|
||||||
|
#$Path.leaf = $solutionNewName
|
||||||
|
return $solutionNewName
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetAvailablePatches () {
|
||||||
|
#Write-Host "┌───────────────────────────────────────────────────────────────┐" -ForegroundColor Green
|
||||||
|
#Write-Host "│" -ForegroundColor Green -NoNewLine; Write-Host "`t`t`tAVAILABLE PATCHES`t`t`t" -ForegroundColor Cyan -NoNewline; Write-Host "│" -ForegroundColor Green
|
||||||
|
#Write-Host "└───────────────────────────────────────────────────────────────┘" -ForegroundColor Green
|
||||||
|
$pacResponse = (& $Global:pptConfig.pacPath solution list | ?{$_ -match $Path.leaf -and $_ -match "patch"}) -split "`r?`n" | %{
|
||||||
|
$g1 = ($_ -split "(?'g1'^\S*)")
|
||||||
|
$g2 = ($g1[2] -split "((\d+|\.){1,})")[0,1,-1]
|
||||||
|
$solutionObject = @{
|
||||||
|
Name = $g1[1]
|
||||||
|
DisplayName = ($g2[0]).Trim()
|
||||||
|
Version = ($g2[1])
|
||||||
|
Managed = switch([string]($g2[2]).Trim()){'False' {$false} Default {$true}}
|
||||||
|
ManagedQuantifier = switch([string]($g2[2]).Trim()){'False' {0} Default {1}}
|
||||||
|
ManagedValue = [string]($g2[2]).Trim()
|
||||||
|
IsPatch = $g1[1] -imatch 'patch'
|
||||||
|
}
|
||||||
|
New-Object -TypeName psObject -Property $solutionObject
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
$index = 1
|
||||||
|
$pacResponse | %{
|
||||||
|
Write-Host "[ $(($index++)) ]`t" -NoNewline
|
||||||
|
Write-Host "Name: " -NoNewline -ForegroundColor DarkGray; Write-Host "$($_.Name)`t" -NoNewline
|
||||||
|
Write-Host "DisplayName: " -NoNewline -ForegroundColor DarkGray; Write-Host "$($_.DisplayName)`t" -NoNewline
|
||||||
|
Write-Host "Version: " -NoNewline -ForegroundColor DarkGray; Write-Host "$($_.Version)`t" -NoNewline
|
||||||
|
Write-Host "IsPatch: " -NoNewline -ForegroundColor DarkGray; Write-Host "$($_.IsPatch)`t"
|
||||||
|
}
|
||||||
|
$patchIndex = Read-Host "Select Patch ($((1..$pacResponse.Count) -join ','))"
|
||||||
|
$patchSelection = $pacResponse[$patchIndex-1]
|
||||||
|
} while ($patchSelection.Name -notin $pacResponse.Name)
|
||||||
|
return $patchSelection
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
|
||||||
|
$pacAuthResponse = & $Global:pptConfig.pacPath auth list
|
||||||
|
|
||||||
|
switch ($pacAuthResponse) {
|
||||||
|
|
||||||
|
{$_ -match 'No profiles were found on this computer'} {
|
||||||
|
Write-Host "[ Error ] " -ForegroundColor Yellow -nonewline
|
||||||
|
Write-Host "No profiles were found on this computer" -ForegroundColor Yellow
|
||||||
|
break
|
||||||
|
<#$authResponse = auth
|
||||||
|
if ($authResponse) {
|
||||||
|
$IsAuth = $true
|
||||||
|
& $Global:pptConfig.pacPath org select -env $env.env_id
|
||||||
|
} else {
|
||||||
|
$IsAuth = $false
|
||||||
|
}#>
|
||||||
|
|
||||||
|
<#if (& $Global:pptConfig.pacPath org list | ?{$_ -match '\*'}) {
|
||||||
|
$IsAuth = $true
|
||||||
|
& $Global:pptConfig.pacPath org select -env $env.env_id
|
||||||
|
} else {
|
||||||
|
$IsAuth = $false
|
||||||
|
}#>
|
||||||
|
}
|
||||||
|
|
||||||
|
{$_ -match '\*'} {
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline
|
||||||
|
write-host "Authentication profile found" -ForegroundColor Cyan
|
||||||
|
& $Global:pptConfig.pacPath org select -env $env.env_id
|
||||||
|
$IsAuth = $true}
|
||||||
|
|
||||||
|
#Default {Write-Warning -Message "Unhandled exception"; return}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch($Patch) {
|
||||||
|
true {
|
||||||
|
if ((& $Global:pptConfig.pacPath org list | ?{$_ -match '\*'}) -match $env.env_id -and $IsAuth) {
|
||||||
|
|
||||||
|
$patchSolution = GetAvailablePatches
|
||||||
|
$patchSolution
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Building $(If($Managed){'managed'}else{'unmanaged'}) solution patch" -ForegroundColor Cyan
|
||||||
|
& $Global:pptConfig.pacPath solution export --name $patchSolution.Name -ow --path $Path.path $(if($Managed){'--managed'})
|
||||||
|
& $Global:pptConfig.pacPath solution unpack --zipfile "$($patchSolution.Name)$(If($Managed){'_managed'}).zip" --folder $Path.path -pca --packagetype $(If($Managed){'Managed'}else{'Unmanaged'}) --errorLevel Verbose
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Write-Host '[ Error ] ' -ForegroundColor Yellow -nonewline; write-host 'Fatal exception' -ForegroundColor Red
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Default {
|
||||||
|
if ((& $Global:pptConfig.pacPath org list | ?{$_ -match '\*'}) -match $env.env_id -and $IsAuth) {
|
||||||
|
|
||||||
|
Write-Host "[ Info ] " -ForegroundColor Green -nonewline; write-host "Building $(If($Managed){'managed'}else{'unmanaged'}) solution" -ForegroundColor Cyan
|
||||||
|
& $Global:pptConfig.pacPath solution export --name $Path.leaf -ow --path $Path.path $(if($Managed){'--managed'})
|
||||||
|
& $Global:pptConfig.pacPath solution unpack --zipfile "$($Path.leaf)$(If($Managed){'_managed'}).zip" --folder $Path.path -pca --packagetype $(If($Managed){'Managed'}else{'Unmanaged'}) --errorLevel Verbose
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Write-Host '[ Error ] ' -ForegroundColor Yellow -nonewline; write-host 'Fatal exception' -ForegroundColor Red
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
If($SolutionName) {
|
||||||
|
$sn = NameThatSolution
|
||||||
|
Move-Item -Path (Join-Path -Path $Path.path -ChildPath "$($Path.leaf)$(If($Managed){'_managed'}).zip") -Destination (Join-Path -Path $Path.path -ChildPath "$($sn).zip") -Force -Confirm:$false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# EXPORT ALIAS
|
||||||
|
New-Alias -Name pullSolution -Value Start-PPTSolutionPull -Description 'posh-PowerPlatformToolkit - Start-PPTSolutionPull alias' -Force
|
||||||
BIN
bin/pac/.signature.p7s
Normal file
BIN
bin/pac/.signature.p7s
Normal file
Binary file not shown.
6831
bin/pac/3rdPartyNotice.txt
Normal file
6831
bin/pac/3rdPartyNotice.txt
Normal file
File diff suppressed because it is too large
Load Diff
53
bin/pac/LICENSE.txt
Normal file
53
bin/pac/LICENSE.txt
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
MICROSOFT SOFTWARE LICENSE TERMS
|
||||||
|
MICROSOFT POWERAPPS CLI
|
||||||
|
________________________________________
|
||||||
|
These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
|
||||||
|
1. INSTALLATION AND USE RIGHTS.
|
||||||
|
a) General. You may install and use any number of copies of the software to develop and test your applications.
|
||||||
|
b) Third Party Software. The software may include third party applications that Microsoft, not the third party, licenses to you under this agreement. Any included notices for third party applications are for your information only.
|
||||||
|
2. DISTRIBUTABLE CODE. The software may contain code you are permitted to distribute (i.e. make available for third parties) in applications you develop, as described in this Section.
|
||||||
|
a) Distribution Rights. The code and test files described below are distributable if included with the software.
|
||||||
|
i. Sample Code and Templates. You may copy, modify, and distribute the source and object code form of code marked as “sample” and “template”;
|
||||||
|
ii. Other Distributable Code. You may copy and distribute the object code form of code if it is a file with the extension *.dll.
|
||||||
|
iii. Third Party Distribution. You may permit distributors of your applications to copy and distribute any of this distributable code you elect to distribute with your applications.
|
||||||
|
b) Distribution Requirements. For any code you distribute, you must:
|
||||||
|
i. add significant primary functionality to it in your applications;
|
||||||
|
ii. require distributors and external end users to agree to terms that protect it and Microsoft at least as much as this agreement; and
|
||||||
|
iii. indemnify, defend, and hold harmless Microsoft from any claims, including attorneys’ fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the unmodified distributable code.
|
||||||
|
c) Distribution Restrictions. You may not:
|
||||||
|
i. use Microsoft’s trademarks or trade dress in your application in any way that suggests your application comes from or is endorsed by Microsoft; or
|
||||||
|
ii. modify or distribute the source code of any distributable code so that any part of it becomes subject to any license that requires that the distributable code, any other part of the software, or any of Microsoft’s other intellectual property be disclosed or distributed in source code form, or that others have the right to modify it.
|
||||||
|
3. DATA
|
||||||
|
a) Data Collection. The software may collect information about you and your use of the software and send that to Microsoft. Microsoft may use this information to provide services and improve Microsoft’s products and services. Your opt-out rights, if any, are described in the product documentation. Some features in the software may enable collection of data from users of your applications that access or use the software. If you use these features to enable data collection in your applications, you must comply with applicable law, including getting any required user consent, and maintain a prominent privacy policy that accurately informs users about how you use, collect, and share their data. You can learn more about Microsoft’s data collection and use in the product documentation and the Microsoft Privacy Statement at https://go.microsoft.com/fwlink/?LinkID=824704. You agree to comply with all applicable provisions of the Microsoft Privacy Statement.
|
||||||
|
b) Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733.
|
||||||
|
4. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to):
|
||||||
|
a) work around any technical limitations in the software that only allow you to use it in certain ways;
|
||||||
|
b) reverse engineer, decompile or disassemble the software;
|
||||||
|
c) remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software;
|
||||||
|
d) use the software in any way that is against the law or to create or propagate malware; or
|
||||||
|
e) share, publish, distribute, or lend the software (except for any distributable code, subject to the terms above), provide the software as a stand-alone hosted solution for others to use, or transfer the software or this agreement to any third party.
|
||||||
|
5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit http://aka.ms/exporting.
|
||||||
|
6. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind.
|
||||||
|
7. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software.
|
||||||
|
8. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court.
|
||||||
|
9. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
|
||||||
|
a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
|
||||||
|
b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
|
||||||
|
c) Germany and Austria.
|
||||||
|
i. Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
|
||||||
|
ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
|
||||||
|
Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
|
||||||
|
10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||||
|
11. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT, OR INCIDENTAL DAMAGES.
|
||||||
|
This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law.
|
||||||
|
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages.
|
||||||
|
|
||||||
|
Please note: As this software is distributed in Canada, some of the clauses in this agreement are provided below in French.
|
||||||
|
Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.
|
||||||
|
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues.
|
||||||
|
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
|
||||||
|
Cette limitation concerne:
|
||||||
|
• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
|
||||||
|
• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.
|
||||||
|
Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard.
|
||||||
|
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
|
||||||
628
bin/pac/Microsoft.PowerApps.CLI.nuspec
Normal file
628
bin/pac/Microsoft.PowerApps.CLI.nuspec
Normal file
@@ -0,0 +1,628 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.PowerApps.CLI</id>
|
||||||
|
<version>1.38.3</version>
|
||||||
|
<title>Microsoft PowerPlatform CLI</title>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<owners>crmsdk,Microsoft</owners>
|
||||||
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
|
<license type="file">LICENSE.txt</license>
|
||||||
|
<licenseUrl>https://aka.ms/deprecateLicenseUrl</licenseUrl>
|
||||||
|
<icon>images\PowerApps.128x128.png</icon>
|
||||||
|
<readme>docs\README.md</readme>
|
||||||
|
<projectUrl>https://learn.microsoft.com/en-us/power-platform/developer/cli/introduction</projectUrl>
|
||||||
|
<description>Microsoft PowerPlatform CLI is a simple, single-stop, developer command-line interface (CLI) for developing customizations and extensions for Microsoft PowerPlatform. See project site how to install.</description>
|
||||||
|
<summary>This package contains the Microsoft PowerPlatform CLI.</summary>
|
||||||
|
<releaseNotes>Please make sure to update your Microsoft Power Platform CLI to the latest version and take advantage of all the latest capabilities by following https://aka.ms/PowerPlatformCLI.
|
||||||
|
If you are a new user please install the Power Platform CLI directly from here: https://aka.ms/PowerPlatformCLI
|
||||||
|
|
||||||
|
1.38.3:
|
||||||
|
Admin
|
||||||
|
- New list-groups command to list all environment groups in the tenant
|
||||||
|
- New add-group command to add an environment to an environment group
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft Graph to 5.63.0
|
||||||
|
|
||||||
|
1.36:
|
||||||
|
power-fx:
|
||||||
|
- JSON not available in Power Fx https://github.com/microsoft/Power-Fx/discussions/2734 reported by https://github.com/rajyraman
|
||||||
|
|
||||||
|
data:
|
||||||
|
- Fixed an issue where the updateCompare flag was ignored if the target table exceeded the default prefetch size of 4,000 records.
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft Graph to 5.61.0
|
||||||
|
- Updated Azure.Identity to 1.13.1
|
||||||
|
- Updated Microsoft.Identity.Client to 4.66.1
|
||||||
|
|
||||||
|
1.35:
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft Graph to 5.58.0
|
||||||
|
- Updated Microsoft.Identity.Client to 4.65.0
|
||||||
|
|
||||||
|
1.34:
|
||||||
|
The dotnet tool version of PAC has been upgraded to .NET 8.0; the original MSI installed version of PAC remains on .NET Framework 4.8
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- `merge-translations` fixed overwriting isCustomizable
|
||||||
|
- `extract-template` fixed NotImplemented exception
|
||||||
|
|
||||||
|
solution check
|
||||||
|
- New --clearCache argument to clear the cache as part of the solution check process
|
||||||
|
|
||||||
|
env
|
||||||
|
- list-settings supports --json output format
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Dataverse Service Client version to 1.1.27
|
||||||
|
- Updated Microsoft.CrmSdk.SolutionPackagerLib version to 9.1.1.180
|
||||||
|
- Updated Microsoft.Identity.Client to 4.63.0
|
||||||
|
- Updated Microsoft.PowerPlatform.Dataverse.Client version to 1.1.32
|
||||||
|
|
||||||
|
1.33:
|
||||||
|
Misc
|
||||||
|
- Updated Azure.Identity to 1.12
|
||||||
|
- Updated Microsoft Graph to 5.56.0
|
||||||
|
- Updated Microsoft.Identity.Client to 4.61.3
|
||||||
|
- Updated Dataverse ModelBuilder to 2.0.11
|
||||||
|
- Updated Microsoft Power Fx 1.3.0-build.20240626-1003
|
||||||
|
- Updated Microsoft.PowerPlatform.Formulas.Tools to 0.8.02735.117-preview (resolves https://github.com/microsoft/PowerApps-Tooling/issues/668)
|
||||||
|
- Updated Microsoft.CrmSdk.SolutionPackagerLib version to 9.1.1.178
|
||||||
|
|
||||||
|
1.32:
|
||||||
|
solution
|
||||||
|
- `solution sync` now supports `--map` to skip items in the unpack process (https://github.com/microsoft/powerplatform-build-tools/discussions/832)
|
||||||
|
- `solution clone` now supports `--map` to skip items in the unpack process (https://github.com/microsoft/powerplatform-build-tools/discussions/832)
|
||||||
|
|
||||||
|
auth
|
||||||
|
- New `auth who` verb which displays information about current authentication profile
|
||||||
|
- (Preview) New `auth create` Federated login flows for Service Principals or User Assigned Managed Identities
|
||||||
|
- These two new options permit authentication via Federated Credentials set in the Azure Portal
|
||||||
|
instead of needing a Client Secret or Client Certificate on supported build agents.
|
||||||
|
- GitHub Actions Federation via the `--githubFederated` switch
|
||||||
|
Configuration instructions will be found on the next release of https://github.com/microsoft/powerplatform-actions/releases (ie, higher than the current v1.4.0)
|
||||||
|
- Azure DevOps Task Federation via the `--azureDevOpsFederated` switch
|
||||||
|
Configuration instructions will be found on the next release of https://github.com/microsoft/powerplatform-build-tools/releases (ie, higher than the current v2.0.63)
|
||||||
|
- Fixed issue with Service Principal Certificate authentication expiring after 1 hour
|
||||||
|
- Fixed issue with Managed Identities Auth Profile creation when the identity did not have optional BAP permissions.
|
||||||
|
|
||||||
|
catalog
|
||||||
|
- `catalog install` now supports `--target-env` to specify target environment (https://github.com/microsoft/powerplatform-build-tools/issues/872)
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft.CrmSdk.SolutionPackagerLib version to 9.1.1.176
|
||||||
|
- Updated Microsoft.PowerPlatform.Dataverse.Client version to 1.1.22
|
||||||
|
|
||||||
|
1.31:
|
||||||
|
auth
|
||||||
|
- Fixed `auth create` bug for SPNs on MacOS https://github.com/microsoft/powerplatform-build-tools/issues/716 reported by https://github.com/jjdd12
|
||||||
|
- Fixed `auth create` with Managed Identity
|
||||||
|
- Fixed `auth clear` bug with invalid or expired SPN profile
|
||||||
|
|
||||||
|
solution
|
||||||
|
- Fixed `solution pack/unpack` bug https://github.com/microsoft/powerplatform-build-tools/issues/695 reported by https://github.com/h-karthik12
|
||||||
|
- Fixed `soltuion sync` bug https://github.com/microsoft/powerplatform-build-tools/discussions/772 reported by https://github.com/Zerajima
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- Fixes export-template loading issue
|
||||||
|
|
||||||
|
- Change default module type to 'es2020' to allow for better tree-shaking to reduce bundle size.
|
||||||
|
- NOTE: If the previous behavior is required, add the line `"module": "commonjs"` to the `tsconfig.json` file under section `compilerOptions`.
|
||||||
|
- Change default target type to 'es6'.
|
||||||
|
- NOTE: If the previous behavior is required, add the line `"target": "es5"` to the `tsconfig.json` file under section `compilerOptions`.
|
||||||
|
|
||||||
|
Fixed URL for the GCC/China/DoD PowerApps Checker endpoints
|
||||||
|
Fixed Microsoft Graph endpoints for GCC & GCC High
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft.Identity.Client to 4.59.0
|
||||||
|
- Updated Microsoft Graph version to 5.43.0
|
||||||
|
- Updated Microsoft.CrmSdk.XrmTooling.CoreAssembly version to 9.1.1.57
|
||||||
|
- Updated Microsoft Power Fx to 1.3
|
||||||
|
- Updated SolutionPackager version to >9.1.1.171
|
||||||
|
|
||||||
|
1.30:
|
||||||
|
Affects all verbs:
|
||||||
|
- The current Universal auth profile will now be selected before falling back on previous logic for the Dataverse and Admin auth profile kinds.
|
||||||
|
This means that old profiles will never be used if there is an existing Universal profile.
|
||||||
|
In the future, these old profiles will no longer be supported. Please create new profiles (which will be Universal) and set the --environment argument or 'pac org select' to set the active Dataverse environment for the profile.
|
||||||
|
- All verbs that interact with Dataverse now support the `--environment` argument.
|
||||||
|
This argument allows the user to explicitly override the active environment for the current profile.
|
||||||
|
For most verbs this argument is optional, as it will fall back to the active environment for the current profile.
|
||||||
|
Only when a verb will potentially corrupt or change security policies will these arguments be required to be specified. (e.g. pac admin copy, pac admin delete)
|
||||||
|
|
||||||
|
auth
|
||||||
|
- Deprecation of all but the Universal auth kinds. The `--kind` argument for `pac auth create` is now officially ignored. All new authentication profiles will use the Universal auth kind.
|
||||||
|
- auth create argument `--url` is now deprecated, replaced with `--environment`. While `--url` supports only a url, the `--environment` argument supports organization id, environment id, and name searches. Other than the kinds of values allowed, these two argument behave the same.
|
||||||
|
- Output of the `auth list` table has been reorganized.
|
||||||
|
- Only Dataverse environment url's are displayed (for some profile kinds and for universal when the tenant doesn't have a default environment a service endpoint was being displayed)
|
||||||
|
- Json result object also updated to use property `ActiveEnvironment` vs `Resource` and `FriendlyName`.
|
||||||
|
- `org select`, `auth update --environment` will now verify the auth profile is able to authenticate with the environment before changing the active environment on the profile. This was causing some profiles to be corrupted.
|
||||||
|
- `org select`, `auth update --environment` will only modify existing Universal and Dataverse environments.
|
||||||
|
- Removed erroneous output "Connected to..." for verbs requiring authentication and supporting an `--environment` argument when the active profile had an active environment selected but the --environment argument on the command line is for a different environment.
|
||||||
|
- Bug fix: Auth profile names should be unique. Existing profiles will get picked on the first in the list, but will not be possible to reuse a profile name.
|
||||||
|
|
||||||
|
admin
|
||||||
|
- set-runtime-state updates the environment administration mode
|
||||||
|
- set-governance-config has 6 new arguments --maker-onboarding-url, --maker-onboarding-markdown, --suppress-validation-emails, --checker-rule-overrides, --cloud-flows-mode, --cloud-flows-limit
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- Command renamed from `copilot` to `copilot model`. Users using e.g. `pac copilot list` need to change their commands to `pac copilot model list`.
|
||||||
|
- Moved commands from `virtual-agent` to `copilot`.
|
||||||
|
- Added alias `virtual-agent` to `copilot`. Users using e.g. `pac virtual-agent list` can continue to do so but are encouraged to changed their commands to `pac copilot list`.
|
||||||
|
|
||||||
|
plugin
|
||||||
|
- updated plugin template for init command
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Dataverse Service Client version to 1.1.17
|
||||||
|
- Updated SolutionPackager version to 9.1.1.164
|
||||||
|
- Updated PDPackageGenerator version to 1.0.13
|
||||||
|
- Updated Power Apps Checker version 1.0.0.17
|
||||||
|
|
||||||
|
1.29:
|
||||||
|
auth
|
||||||
|
- Security improvements to the storage mechanism for the Token Cache
|
||||||
|
- Windows: no effective change; Token Cache is already stored via Windows Data Protection API for encryption at rest
|
||||||
|
- macOS: Token Cache is now stored within Keychain. This may lead to occasional OS prompts for PAC to access the Keychain
|
||||||
|
- Linux:
|
||||||
|
- For desktop environments with a Secret Service implementation (such as gnome-keyring or ksecretservice), the Token Cache is now stored there via libsecret.
|
||||||
|
- If libsecret or a Secret Service implementation is not installed or not available (such as an SSH session, headless, or without x11), the Token Cache remains in a plaintext file with user-only (chomd 600) permissions.
|
||||||
|
|
||||||
|
canvas download
|
||||||
|
- Added new --extract-to-directory parameter to extract the contents of the downloaded msapp file to a directory
|
||||||
|
|
||||||
|
power-fx
|
||||||
|
- Added pfx alias for power-fx command
|
||||||
|
- Added function list for Power Fx Repl
|
||||||
|
|
||||||
|
pcf push supports target environment
|
||||||
|
- Adds the --solution-unique-name argument (mutually exclusive with --publisher-prefix argument)
|
||||||
|
- The temporary solution (and the temporary publisher) is now deleted after import is successful.
|
||||||
|
- The publisher prefix from the target environment is used
|
||||||
|
|
||||||
|
data import
|
||||||
|
- returns nonzero exit code when import fails
|
||||||
|
|
||||||
|
solution sync
|
||||||
|
- Now supports long path names on Windows
|
||||||
|
|
||||||
|
admin create
|
||||||
|
- Added new --security-group-id parameter to specify the security group id for the environment as suggested by https://github.com/just-marc-stevenson
|
||||||
|
https://github.com/microsoft/powerplatform-build-tools/discussions/535
|
||||||
|
|
||||||
|
package deploy
|
||||||
|
- New --solution argument which adds the ability to pass a solution to pac package deploy, using PD to deploy the solution
|
||||||
|
This will allow for the deployment of solutions using the PD processor to support async, retry, timeout and other features
|
||||||
|
that PD uses to deliver a solution.
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft.PowerPlatform.PackageGeneratorLib to 1.0.10
|
||||||
|
- Updated Microsoft.Identity.Client to 4.57.0
|
||||||
|
- Updated Microsoft.Graph to 5.32.0
|
||||||
|
|
||||||
|
1.28:
|
||||||
|
power-fx
|
||||||
|
- new repl command for read-eval-print-loop of Power FX expressions
|
||||||
|
- new run command to run Power FX expressions from file
|
||||||
|
|
||||||
|
canvas
|
||||||
|
- Added new list command to list all canvas apps in the environment
|
||||||
|
- Added new download command to download msapp file for a canvas app
|
||||||
|
|
||||||
|
data
|
||||||
|
- Import command has new --connection-count parameter to specify the number of connections to use during import with 5 being the default
|
||||||
|
|
||||||
|
admin
|
||||||
|
- Create command has new --user parameter to specify the owner of the developer environment
|
||||||
|
|
||||||
|
solution
|
||||||
|
- Import command has new --stage-and-upgrade switch to perform a Solution Upgrade in a single command, instead of needing `pac solution import --import-as-holding` followed by a `pac solution upgrade`
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- PAC CLI is outputting in Unicode (UTF16) by default
|
||||||
|
- Improved environment discovery for service principal authentication
|
||||||
|
- Improved service pricnipal access token refresh and exchange flows
|
||||||
|
- Improved asyncronous polling
|
||||||
|
- fixed https://github.com/microsoft/powerplatform-build-tools/issues/516 reported by https://github.com/joje1234
|
||||||
|
- PAC CLI is now long path aware on Windows for file names longer than 260 characters
|
||||||
|
- Updated Microsoft.Graph to 5.28.0
|
||||||
|
|
||||||
|
1.27:
|
||||||
|
admin
|
||||||
|
- Added new list-tenant-settings as requested by https://github.com/Laskewitz: https://github.com/microsoft/powerplatform-build-tools/discussions/460
|
||||||
|
- Added new update-tenant-settings as requested by https://github.com/Laskewitz: https://github.com/microsoft/powerplatform-build-tools/discussions/460
|
||||||
|
- Improved list command which now shows environment selected in current auth profile
|
||||||
|
|
||||||
|
connection
|
||||||
|
As requested by https://github.com/jboliveira and based on large number of votes on https://github.com/microsoft/powerplatform-build-tools/discussions/481
|
||||||
|
- (Preview) Added create, update, list and delete verbs for Dataverse connections with Service Principal authentication
|
||||||
|
|
||||||
|
org
|
||||||
|
- Added new alias "env": "pac env list" is equivalent to "pac org list"
|
||||||
|
|
||||||
|
paportal
|
||||||
|
- Added new aliases "powerpages" and "pages"
|
||||||
|
|
||||||
|
auth
|
||||||
|
- create --managedIdentity flow can include regular users, specified by Username + Password Environment Variables
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Removed support for .NET 5.0
|
||||||
|
- Updated Microsoft.Graph to 5.26.0
|
||||||
|
- Updated Microsoft.PowerPlatform.Dataverse.Client to 1.1.14
|
||||||
|
|
||||||
|
1.26:
|
||||||
|
pcf
|
||||||
|
- Added new --incremental flag which only pushes changed files via entity update
|
||||||
|
- project templates now include react and react-dom as devDependencies
|
||||||
|
- Added pcfStartPath option to improve monorepo support
|
||||||
|
|
||||||
|
admin
|
||||||
|
- create-service-principal now has internal retry logic after Entra ID app creation
|
||||||
|
- Most votes got idea from https://github.com/Laskewitz: https://github.com/microsoft/powerplatform-build-tools/discussions/406
|
||||||
|
create-service-principal now has --name and --environment is optional
|
||||||
|
- Added list-service-principal command to list all application service principals in the tenant which have access to Dataverse environments
|
||||||
|
- Added support for managed environments with set-governance-config
|
||||||
|
|
||||||
|
auth
|
||||||
|
- Better detection of Azure Cloud based on environment URL
|
||||||
|
- Operating system auth profile can now have default environment URL (org select)
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- predict now accepts model by name in addition to model id
|
||||||
|
- list shows which models are active or inactive
|
||||||
|
|
||||||
|
test
|
||||||
|
- execution of automated tests for Power Apps with Playwright
|
||||||
|
|
||||||
|
catalog
|
||||||
|
- Add Support for common Packager
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Updated Microsoft.PowerPlatform.Dataverse.Client to 1.1.12
|
||||||
|
- Updated SolutionPackager to 9.1.1.156
|
||||||
|
- Updated Microsoft.Graph to 5.21.0
|
||||||
|
- Updated Dataverse ModelBuilder to 2.0.6
|
||||||
|
- Updated Microsoft.PowerPlatform.Formulas.Tools to 0.6.4-preview
|
||||||
|
- Added --log-to-console for use with Azure DevOps Build Tools
|
||||||
|
|
||||||
|
1.25:
|
||||||
|
solution
|
||||||
|
- "smarter" solution import (GitHub issue #200 by HansMeiser999). Added new --skip-lower-version flag to solution import
|
||||||
|
- export path is optional
|
||||||
|
|
||||||
|
org
|
||||||
|
- New list-settings command displays list of current environment settings
|
||||||
|
- New update-settings command updates environment settings
|
||||||
|
|
||||||
|
pcf
|
||||||
|
- Fixed pcf push when pac is installed as a dotnet tool
|
||||||
|
- Updated init command defaults
|
||||||
|
- Solution customization prefix is now optional during push
|
||||||
|
- pcf-scripts is fixed when generated types were either deleted or contain errors
|
||||||
|
|
||||||
|
admin
|
||||||
|
- Updated assign-user to not error on duplicate entry
|
||||||
|
- Added support for creating app user and assigning role to pac admin create-service-principal
|
||||||
|
- Added support for managed environments with set-governance-config
|
||||||
|
- Deprecated commands are now hidden from help but still available
|
||||||
|
|
||||||
|
modelbuilder
|
||||||
|
- Removed --generateactions Command and Replaced with --generatesdkmessages
|
||||||
|
Change is backward compatible if using a settings file to generate. shortcut for generatesdkmessages remains -a for compatibility
|
||||||
|
- Added --emitentityetc control for emitting ETC code in code base, Defaulted is now to not emit ETC on write.
|
||||||
|
- Added --emitvirtualattributes control for emitting Virtual Attributes as part of ModelBuilding. This allows access to "name" properties that are stored in the formatedvalues property bag.
|
||||||
|
added at the request of git: https://github.com/microsoft/powerplatform-vscode/issues/509
|
||||||
|
- Updated Suppress Code Generation attribute behavior to remove tool version from files.
|
||||||
|
- Updated generation of field enums to a partial class to support the request on Git: https://github.com/microsoft/powerplatform-vscode/discussions/558
|
||||||
|
- Fixed issue where Warning about not writhing Proxy attribute was not emitted to the console. https://github.com/microsoft/powerplatform-vscode/issues/516
|
||||||
|
- Fixed issue where SDK message builder would miss messages due to the volume of data being read from Dataverse. https://github.com/microsoft/powerplatform-vscode/issues/413
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- New list command displays list of AI Builder models
|
||||||
|
- New predict command allows to test AI Builder models
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Fixed 'React PCF creation not working' (GitHub issue #584 by Ionavoss)
|
||||||
|
- Increased Dataverse Service Client Timeout to default of 30 minutes.
|
||||||
|
- Updated Microsoft.Identity.Client to 4.54.1
|
||||||
|
- Updated Microsoft.PowerPlatform.Formulas.Tools to 0.6.3-preview
|
||||||
|
- Updated Microsoft.Xrm.Tooling.Dmt libraries to 4.0.0.139
|
||||||
|
|
||||||
|
1.24:
|
||||||
|
admin
|
||||||
|
- Added new command to allow for setting backup retention period of environments with managed environment enabled.
|
||||||
|
- Added new --skip-audit-data flag to allow for skipping audit data during environment copy and restore.
|
||||||
|
- Added new create-service-principal command to provide alternative for separate PowerShell script which creates Azure AD app.
|
||||||
|
|
||||||
|
catalog
|
||||||
|
- New catalog update command to update settings for a catalog
|
||||||
|
|
||||||
|
solution
|
||||||
|
- Fixed unpack command when solution contains canvas apps
|
||||||
|
|
||||||
|
pipeline
|
||||||
|
- Improved deployment wait flag and environment selection
|
||||||
|
|
||||||
|
application
|
||||||
|
- Added new "Application Id" column to list command
|
||||||
|
- Added application argument to list command which will accept app id/app name
|
||||||
|
|
||||||
|
copilot
|
||||||
|
- (Preview) New: "copilot" for tools and utilities in copilot scenarios
|
||||||
|
- (Preview) prepare-fetch: takes FetchXML file from AI LLM and prepares it for execution against Dataverse environment
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- telemetry status now shows log file location
|
||||||
|
- Updated Dataverse Service Client to 1.1.9
|
||||||
|
- Updated Microsoft.PowerPlatform.Formulas.Tools to 0.6.2-preview
|
||||||
|
- Nuget packages for CLI.Core* include all resource assemblies
|
||||||
|
- Updated Microsoft.CrmSdk.XrmTooling.PackageDeployment.Core to 9.1.0.142
|
||||||
|
|
||||||
|
1.23:
|
||||||
|
Added support for dotnet tool install on Windows, Linux, Mac: dotnet tool install --global Microsoft.PowerApps.CLI.Tool
|
||||||
|
Added support for Web Account Manager - single sign-on, pac auth create is now optional on Windows
|
||||||
|
|
||||||
|
connector create / update
|
||||||
|
- Added Script support for pac connector create / update
|
||||||
|
|
||||||
|
solution
|
||||||
|
- clone: Added --localization switch to allow for localized solution clone operations.
|
||||||
|
- sync: Added --localization switch to allow for localized solution sync operations.
|
||||||
|
- init: Added new property (SolutionPackageEnableLocalization - true|false) to project file to enabled / disable localization during pack operations.
|
||||||
|
- check: Added --saveResults switch to allow storing solution analysis results in the current Dataverse environment.
|
||||||
|
|
||||||
|
paportal
|
||||||
|
- Added bootstrap-migrate verb to pac paportal command that provides ability to migrate bootstrap v3 portal to bootstrap v5
|
||||||
|
|
||||||
|
modelbuilder
|
||||||
|
- New verbose flag [--loglevel] for modelbuilder
|
||||||
|
|
||||||
|
data
|
||||||
|
- Updated to latest CMT bits, including bug fixes
|
||||||
|
|
||||||
|
package
|
||||||
|
- Updated to latest package deployer bits, including new operation telemetry feature and bug fixes. Updated progress log reporting to reflect package progress notifications.
|
||||||
|
|
||||||
|
Misc
|
||||||
|
- Breaking change: Renamed Mooncake to China (--cloud China)
|
||||||
|
- Updated fluent V9 platform library from 9.5.2 -> 9.19.1. This brings in the common PCF package that has the new fluent library and configuration json file.
|
||||||
|
- SolutionPackager version is updated
|
||||||
|
- GitLibrary updated in new version [ARM/Linux]
|
||||||
|
|
||||||
|
1.22.4:
|
||||||
|
modelbuilder
|
||||||
|
- Update to ModelBuilder lib to pick up bugfixes
|
||||||
|
|
||||||
|
pcf push
|
||||||
|
- support for interactive auth and console logging
|
||||||
|
|
||||||
|
Catalog for Power Platform:
|
||||||
|
- catalog list: List all published catalog items from the current Dataverse Organization.
|
||||||
|
- catalog submit: Submit catalog approval request.
|
||||||
|
- catalog install: Install a catalog item to the target environment.
|
||||||
|
- catalog status: Get status of the catalog install/submit request.
|
||||||
|
- catalog create-submission: Create catalog submission document. Note: This command will be removed in a future release."
|
||||||
|
|
||||||
|
connector
|
||||||
|
- create | update now accepts --solution-unique-name
|
||||||
|
|
||||||
|
solution check
|
||||||
|
- Support for additional GEOs: SouthAfrica, Norway, Singapore, Korea
|
||||||
|
|
||||||
|
solution clone | sync: fixed issues in managed and unmanaged solutions
|
||||||
|
|
||||||
|
admin list
|
||||||
|
- supports for new argument --application-id
|
||||||
|
|
||||||
|
paportal
|
||||||
|
- Support for working with Power Pages websites utilizing the enhanced data model (v2)
|
||||||
|
|
||||||
|
1.21.13:
|
||||||
|
- Fixed issues with versioning.
|
||||||
|
- Connector noun support: Create/Update permit setting values via settings file
|
||||||
|
|
||||||
|
PAPortal
|
||||||
|
- Support for reading and writing optionsetvaluecollection.
|
||||||
|
- Support for uploading datetime fields.
|
||||||
|
- Download support for multi-language portals in v2 data model.
|
||||||
|
- v1 webfiles having 'adx_migratedtofilecontent' attribute is no longer supported.
|
||||||
|
- Support for custom name handling in v2 data model for entities.
|
||||||
|
- Renamed 'annotations' to 'webfiles' in v2 data model download.
|
||||||
|
- Added content field in 'powerpagesitelanguage', display name field to 'powerpagesitelanguage' entity.
|
||||||
|
- Added additional fields to YML files.
|
||||||
|
|
||||||
|
New Verb
|
||||||
|
- (Preview) New Verb: "org fetch" to perform FetchXML query against Dataverse.
|
||||||
|
|
||||||
|
Admin async operation improvements
|
||||||
|
- `admin status` now displays the internal pac operation ID.
|
||||||
|
- All admin verbs that support async operations now display the internal pac operation ID.
|
||||||
|
- Deprecated `admin assign-user --async`.
|
||||||
|
|
||||||
|
1.21.8:
|
||||||
|
- canvas pack|unpack: updated to Microsoft.PowerPlatform.Formulas.Tools to 0.5.8-preview.
|
||||||
|
- modelbuilder updated to latest version 1.0.16
|
||||||
|
- virtual-agent status: new verb to poll for completion of provisioning status of bots
|
||||||
|
|
||||||
|
1.21.4:
|
||||||
|
- admin assign-group: new verb to complement assign-user
|
||||||
|
- auth create: support for Azure Managed Identities
|
||||||
|
- canvas pack|unpack: updated to Microsoft.PowerPlatform.Formulas.Tools to 0.5.7-preview.
|
||||||
|
- pipeline: new noun to list and start in-product Pipelines
|
||||||
|
- virtual-agent: listing of Power VA in environment
|
||||||
|
|
||||||
|
- package: update to latest PD Core 9.1.0.118
|
||||||
|
- update to latest Dataverse Service client lib 1.0.26
|
||||||
|
|
||||||
|
1.20.3:
|
||||||
|
- modelbuilder build: generate C# classes from entities (integrates CrmSvcUtil functionality)
|
||||||
|
|
||||||
|
- auth create: fix to handle client secrets starting with '-' (pp-build-tools #206)
|
||||||
|
- solution check: fix incorrect checker endpoint urls for some sovereign clouds (pp-build-tools #211)
|
||||||
|
- solution pack|unpack:
|
||||||
|
- support PowerFX formulas in .yaml files for Entities
|
||||||
|
- unpack will sort RootComponents, MissingDependencies, AppModules to reduce noisy diffs between exports/sync calls
|
||||||
|
- solution sync: don't place PCF controls or plugin assemblies that are rebuilt from src via solution add-references
|
||||||
|
|
||||||
|
1.19.4:
|
||||||
|
- QFE:
|
||||||
|
- fix for pcf push: <https://github.com/microsoft/powerplatform-vscode/issues/294>
|
||||||
|
- fix for solution sync: fails to package solution zip with 'Unable to find assembly registration configuration'
|
||||||
|
|
||||||
|
1.19.3:
|
||||||
|
- canvas pack|unpack: updated to Microsoft.PowerPlatform.Formulas.Tools to 0.5.5-preview.
|
||||||
|
- paportal: site visibility warning for upload/download verbs
|
||||||
|
- solution import: reject with error if deployment settings has Dataverse EnvVars without value
|
||||||
|
- tool cmt|pd|prt: install, launch and update WPF apps ConfigMigrationTool, PackageDeployer, PluginRegistrationTool
|
||||||
|
|
||||||
|
1.18.4:
|
||||||
|
- admin assign-user: also support application user
|
||||||
|
- application list|install: deprecate parameter `--environment-id` in favor of `--environment` which allows specifying url or id
|
||||||
|
- auth create: support for appID/SPN authN via certificate (in addition to client secret)
|
||||||
|
- canvas pack|unpack: updated to Microsoft.PowerPlatform.Formulas.Tools to 0.5.3-preview.
|
||||||
|
- data import:
|
||||||
|
- specify data to import as either directory or zip file with --data param
|
||||||
|
- deprecating the now obsolete --dataDirectory param
|
||||||
|
- NOTE: pac data import|export is a Windows-only feature for the time being
|
||||||
|
- package deploy: pass in runtime settings for package parameters
|
||||||
|
- plugin init: strong-name signing for plugin dll is opt-in now
|
||||||
|
- PREVIEW: new noun connector with verbs for interacting with Custom Connectors in Power Apps
|
||||||
|
- Updated to latest SolutionPackager (9.1.0.128)
|
||||||
|
|
||||||
|
1.17.6:
|
||||||
|
- macOS/linux: pac CLI now runs on and requires .NET6; get SDK installer from: https://dotnet.microsoft.com/en-us/download
|
||||||
|
NOTE: when running pac CLI on Apple Silicon ARM (M1/M2) macOS, this version still requires to also have the intel/x64 .NET6 SDK to be installed!!
|
||||||
|
- shipping with GA-ed Dataverse Service client (1.0.9)
|
||||||
|
- admin: new verbs:
|
||||||
|
- list-app-templates: enumerate available D365 application templates
|
||||||
|
- assign-user: Assign a user and role to a target environment
|
||||||
|
- auth:
|
||||||
|
- create verb, new opt. parameter: select a default environment by url, domain name or environmentId; change later with `pac org select`
|
||||||
|
- update verb: update name or default env url/id for existing auth profile
|
||||||
|
- canvas:
|
||||||
|
- create: new verb to generate Power Apps from custom connector
|
||||||
|
- updated to Microsoft.PowerPlatform.Formulas.Tools to 0.5.2-preview.
|
||||||
|
- data: new module to import/export configuration data, similar to CMT
|
||||||
|
- org:
|
||||||
|
- select: change pre-selected environment to use for e.g. solution export etc.
|
||||||
|
- list now supports filtering
|
||||||
|
- package:
|
||||||
|
- add-external-package: Adds support for external packages to app packages, including FnO packages.
|
||||||
|
- plugin:
|
||||||
|
- push: directly update an already registered plugin dll/package in the selected environment
|
||||||
|
- init:
|
||||||
|
- updated plugin code template with added ILogger, ServiceProvider, OrgSvcFactory accessors
|
||||||
|
- added ability to skip plug-in assembly signing which gives plug-in assembly strong name via new --skip-signing switch
|
||||||
|
- solution:
|
||||||
|
- add-solution-component: adds a solution component to the unmanaged solution in the connected Dataverse environment
|
||||||
|
- clone:
|
||||||
|
- also packs and unpacks any Canvas apps in solution.zip (new param --processCanvasApps)
|
||||||
|
- allow selecting managed/unmanaged solution
|
||||||
|
- sync, currently in preview:
|
||||||
|
-updates a previously cloned solution in the local filesystem with latest changes made in Maker studio
|
||||||
|
- also packs and unpacks any Canvas apps in solution.zip (new param --processCanvasApps)
|
||||||
|
- allow selecting managed/unmanaged solution
|
||||||
|
- check: extended default timeout to 1hr to check even larger/complex solution
|
||||||
|
|
||||||
|
1.16.6:
|
||||||
|
- auth create now supports "Single Sign On":
|
||||||
|
- '--kind' parameter is deprecated but still valid to use with its DATAVERSE and ADMIN kind values; defaults now to UNIVERSAL
|
||||||
|
- '--url' is now optional, will select default environment in tenant
|
||||||
|
- the single sign on authN can be used with all pac CLI nouns
|
||||||
|
- canvas: updated Microsoft.PowerPlatform.Formulas.Tools to 0.5.0-preview.
|
||||||
|
- admin:
|
||||||
|
- added China sovereign cloud admin endpoints
|
||||||
|
- fixed --language argument to accetp language ids and suggest valid ids
|
||||||
|
- package deploy: fixed error when packages contain .cab files
|
||||||
|
- solution check: --path supports now wildcards and globbing
|
||||||
|
- solution list: show if solutions are managed or not
|
||||||
|
|
||||||
|
1.15.3:
|
||||||
|
- admin: Added ability to backup, restore and list Microsoft Teams Power Apps environments.
|
||||||
|
- admin backup: --notes parameter has been deprecated in both pac CLI and service endpoint
|
||||||
|
- canvas: updated Microsoft.PowerPlatform.Formulas.Tools to 0.4.5-preview.
|
||||||
|
see also <https://github.com/microsoft/PowerApps-Language-Tooling/releases/tag/0.4.5-preview>
|
||||||
|
- package:
|
||||||
|
added support for creating and building additional package types, Dataverse For Teams, UNO
|
||||||
|
- init: now defaults to creating package projects as new sdk-style projects.
|
||||||
|
- add-solution: add prebuilt solution.zip to package.
|
||||||
|
- add-reference: support the new sdk-style project type.
|
||||||
|
- plugin: support building Dataverse plugins with dependent assemblies into nuget package
|
||||||
|
- solution:
|
||||||
|
- export|clone: parameter --targetVersion deprecated (not supported by Dataverse 9.x)
|
||||||
|
- pack|unpack verbs: also packs and unpacks any Canvas apps in solution.zip (new param --processCanvasApps)
|
||||||
|
- publish: Added ability to publish customizations asynchronously
|
||||||
|
- upgrade: check that an upgradeable solution exists in target environment
|
||||||
|
- Updated to latest SolutionPackager (9.1.0.110) and Dataverse Service Client (0.6.6) libraries
|
||||||
|
|
||||||
|
1.14.4:
|
||||||
|
- admin create: Added ability to create Microsoft Teams environments
|
||||||
|
- admin reset: fix language name parsing for --language
|
||||||
|
- canvas: updated Microsoft.PowerPlatform.Formulas.Tools to 0.4.2-preview.
|
||||||
|
- pcf init: support for React(virtual) and Fluent UI code components using platform libraries.
|
||||||
|
- pcf version | solution version: Fix "gittags" and "filetracking "version update strategies
|
||||||
|
- org list: fixed list of environments for authentication profiles in sovereign clouds
|
||||||
|
- emit path to pac CLI's diagnostic log when encountering non-recoverable errors
|
||||||
|
|
||||||
|
1.13.6:
|
||||||
|
- admin copy: fix regression when specifying --source-url was rejected with error
|
||||||
|
- new 'pac application' noun: list and install packages/application available for the PP tenant to the target environment
|
||||||
|
- canvas: updated Microsoft.PowerPlatform.Formulas.Tools to 0.4.0-preview.
|
||||||
|
- Added support for first-party PCF Control conversions.
|
||||||
|
- Controls and components with conflicting names will no longer overwrite the editor state.
|
||||||
|
- Empty test suites will no longer cause issues when roundtripping.
|
||||||
|
see also <https://github.com/microsoft/PowerApps-Language-Tooling/releases/tag/0.4.0-preview>
|
||||||
|
- paportal download: fix 'missing root pages' error for non-English PowerPages
|
||||||
|
- solution pack|unpack: latest SoPa 9.1.0.107
|
||||||
|
- strip XML comments from localizable elements
|
||||||
|
- fix AssemblyQualifiedName mapping for plugins
|
||||||
|
|
||||||
|
1.12.2:
|
||||||
|
- Device Code Authentication:
|
||||||
|
`pac auth create` now supports Device Code Authentication via the `--deviceCode` switch
|
||||||
|
- pcf init framework argument is now case insensitive
|
||||||
|
- "none" is no longer available as copy type for copy environment
|
||||||
|
- Fixed issue where pac pcf init fails with an unrecognized error when using --run-npm-install
|
||||||
|
- Updated pcf dependencies
|
||||||
|
- pac auth clear now deletes local user token cache
|
||||||
|
|
||||||
|
1.11.8:
|
||||||
|
- Sovereign cloud support authentication support:
|
||||||
|
pac admin and pac auth | org | paportal | solution noun/verbs can now interact with sovereign cloud environments
|
||||||
|
- Interactive OAuth logins now use single appID for all endpoints
|
||||||
|
- Update to latest SolutionPackager library:
|
||||||
|
- localization support for solution aware entities
|
||||||
|
- fix handling of CanvasApp where app name and paths to composite files (.msapp, image) differ; file name reference in meta xml is now source of truth
|
||||||
|
- fix EntityRelationshipRole/AssociationRoleOrdinal search bug
|
||||||
|
- pac package init: improved/fixed package template project
|
||||||
|
- paportal:
|
||||||
|
- improve error handling for deleted and missing key
|
||||||
|
- adding option to specify locale file format json or yaml
|
||||||
|
- solution:
|
||||||
|
- fix version verb to correctly increment version tuple in solution.xml (preserving version tupleness)
|
||||||
|
- add additional parameters (--solutionUri, --excludedFiles) to check verb
|
||||||
|
|
||||||
|
1.10.4:
|
||||||
|
- pac auth create: fixed interactive login for --kind admin on .NET Core 5 (linux, macOS)
|
||||||
|
- pac canvas pack: updated to latest library with fix for issue https://github.com/microsoft/PowerApps-Language-Tooling/issues/319
|
||||||
|
- pac org list: enumerate reachable Dataverse environments, using global discovery service
|
||||||
|
- pac paportal: added missing attributes adx_attachfileacceptextensions, adx_attachfilesaveoption
|
||||||
|
- pac solution add-license: fixed reported unhandled exception errors
|
||||||
|
- added: pac solution delete
|
||||||
|
- added: pac solution online-version to update version in connected Dataverse environment
|
||||||
|
- pac solution unpack
|
||||||
|
- fixed issue with resource localization incorrectly using Lcid ID's when not requested
|
||||||
|
- fixed issue with --allowDelete causing pac to hang.
|
||||||
|
- fixed issue with --useUnmanagedFileForMissingManaged that caused the setting to be ignored.
|
||||||
|
- fixed issue with --useLcid that caused the setting to be ignored.
|
||||||
|
- pac solution pack - plugin references in solution will be remapped to full strong name (type/version/pubKeyToken) of assembly;
|
||||||
|
--disablePluginRemap to disable plugin type name remapping</releaseNotes>
|
||||||
|
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||||
|
<language>en-US</language>
|
||||||
|
<tags>Dynamics CRM PowerApps PowerPlatform</tags>
|
||||||
|
</metadata>
|
||||||
|
</package>
|
||||||
33
bin/pac/[Content_Types].xml
Normal file
33
bin/pac/[Content_Types].xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||||
|
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
|
||||||
|
<Default Extension="psmdcp" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
|
||||||
|
<Default Extension="txt" ContentType="application/octet" />
|
||||||
|
<Default Extension="png" ContentType="application/octet" />
|
||||||
|
<Default Extension="md" ContentType="application/octet" />
|
||||||
|
<Default Extension="dll" ContentType="application/octet" />
|
||||||
|
<Default Extension="exe" ContentType="application/octet" />
|
||||||
|
<Default Extension="sh" ContentType="application/octet" />
|
||||||
|
<Default Extension="js" ContentType="application/octet" />
|
||||||
|
<Default Extension="json" ContentType="application/octet" />
|
||||||
|
<Default Extension="config" ContentType="application/octet" />
|
||||||
|
<Default Extension="gitignore" ContentType="application/octet" />
|
||||||
|
<Default Extension="ps1" ContentType="application/octet" />
|
||||||
|
<Default Extension="cs" ContentType="application/octet" />
|
||||||
|
<Default Extension="xml" ContentType="application/octet" />
|
||||||
|
<Default Extension="csproj" ContentType="application/octet" />
|
||||||
|
<Default Extension="cdsproj" ContentType="application/octet" />
|
||||||
|
<Default Extension="html" ContentType="application/octet" />
|
||||||
|
<Default Extension="css" ContentType="application/octet" />
|
||||||
|
<Default Extension="ttf" ContentType="application/octet" />
|
||||||
|
<Default Extension="nupkg" ContentType="application/octet" />
|
||||||
|
<Default Extension="pcfproj" ContentType="application/octet" />
|
||||||
|
<Default Extension="ts" ContentType="application/octet" />
|
||||||
|
<Default Extension="tsx" ContentType="application/octet" />
|
||||||
|
<Default Extension="cmd" ContentType="application/octet" />
|
||||||
|
<Default Extension="so" ContentType="application/octet" />
|
||||||
|
<Default Extension="mjs" ContentType="application/octet" />
|
||||||
|
<Default Extension="yml" ContentType="application/octet" />
|
||||||
|
<Default Extension="dylib" ContentType="application/octet" />
|
||||||
|
<Default Extension="nuspec" ContentType="application/octet" />
|
||||||
|
</Types>
|
||||||
5
bin/pac/_rels/.rels
Normal file
5
bin/pac/_rels/.rels
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
||||||
|
<Relationship Type="http://schemas.microsoft.com/packaging/2010/07/manifest" Target="/Microsoft.PowerApps.CLI.nuspec" Id="R3F00267ED94FE8F1" />
|
||||||
|
<Relationship Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="/package/services/metadata/core-properties/f298347dbc8140e0a9397098d9771ee5.psmdcp" Id="R13FFEE3D18FF5B47" />
|
||||||
|
</Relationships>
|
||||||
19
bin/pac/docs/README.md
Normal file
19
bin/pac/docs/README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# What is Microsoft Power Platform CLI?
|
||||||
|
Microsoft PowerPlatform CLI is a simple, single-stop, developer command-line interface (CLI)
|
||||||
|
for developing customizations and extensions for Microsoft PowerPlatform.
|
||||||
|
|
||||||
|
Learn more [here](https://learn.microsoft.com/en-us/power-platform/developer/cli/introduction).
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
Easiest way to install is to use the dotnet tool install command.
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet tool install --global Microsoft.PowerApps.CLI.Tool
|
||||||
|
```
|
||||||
|
|
||||||
|
More ways to install can be found [here](https://learn.microsoft.com/en-us/power-platform/developer/cli/introduction#install-microsoft-power-platform-cli).
|
||||||
|
|
||||||
|
# Reference
|
||||||
|
|
||||||
|
[Microsoft Power Platform CLI reference](https://learn.microsoft.com/en-us/power-platform/developer/cli/reference/)
|
||||||
BIN
bin/pac/images/PowerApps.128x128.png
Normal file
BIN
bin/pac/images/PowerApps.128x128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<coreProperties xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties">
|
||||||
|
<dc:creator>Microsoft</dc:creator>
|
||||||
|
<dc:description>Microsoft PowerPlatform CLI is a simple, single-stop, developer command-line interface (CLI) for developing customizations and extensions for Microsoft PowerPlatform. See project site how to install.</dc:description>
|
||||||
|
<dc:identifier>Microsoft.PowerApps.CLI</dc:identifier>
|
||||||
|
<version>1.38.3</version>
|
||||||
|
<keywords>Dynamics CRM PowerApps PowerPlatform</keywords>
|
||||||
|
<lastModifiedBy>NuGet, Version=6.11.1.2, Culture=neutral, PublicKeyToken=31bf3856ad364e35;Microsoft Windows NT 10.0.20348.0;.NET Framework 4.7.2</lastModifiedBy>
|
||||||
|
</coreProperties>
|
||||||
11
bin/pac/tools/.playwright/node/darwin-arm64/playwright.sh
Normal file
11
bin/pac/tools/.playwright/node/darwin-arm64/playwright.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
node -v > /dev/null 2>&1
|
||||||
|
if test $? -ne 0
|
||||||
|
then
|
||||||
|
echo "node wasn't found in the PATH. Please make sure node is installed and available in the PATH. Exiting..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||||
|
node "$SCRIPT_PATH/../../package/lib/cli/cli.js" "$@"
|
||||||
|
fi
|
||||||
11
bin/pac/tools/.playwright/node/darwin-x64/playwright.sh
Normal file
11
bin/pac/tools/.playwright/node/darwin-x64/playwright.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
node -v > /dev/null 2>&1
|
||||||
|
if test $? -ne 0
|
||||||
|
then
|
||||||
|
echo "node wasn't found in the PATH. Please make sure node is installed and available in the PATH. Exiting..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||||
|
node "$SCRIPT_PATH/../../package/lib/cli/cli.js" "$@"
|
||||||
|
fi
|
||||||
11
bin/pac/tools/.playwright/node/linux-arm64/playwright.sh
Normal file
11
bin/pac/tools/.playwright/node/linux-arm64/playwright.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
node -v > /dev/null 2>&1
|
||||||
|
if test $? -ne 0
|
||||||
|
then
|
||||||
|
echo "node wasn't found in the PATH. Please make sure node is installed and available in the PATH. Exiting..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||||
|
node "$SCRIPT_PATH/../../package/lib/cli/cli.js" "$@"
|
||||||
|
fi
|
||||||
11
bin/pac/tools/.playwright/node/linux-x64/playwright.sh
Normal file
11
bin/pac/tools/.playwright/node/linux-x64/playwright.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
node -v > /dev/null 2>&1
|
||||||
|
if test $? -ne 0
|
||||||
|
then
|
||||||
|
echo "node wasn't found in the PATH. Please make sure node is installed and available in the PATH. Exiting..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||||
|
node "$SCRIPT_PATH/../../package/lib/cli/cli.js" "$@"
|
||||||
|
fi
|
||||||
10
bin/pac/tools/.playwright/node/win32_x64/playwright.cmd
Normal file
10
bin/pac/tools/.playwright/node/win32_x64/playwright.cmd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
@REM Check if node is installed and use it, if not, exit with error.
|
||||||
|
node -v > NUL 2>&1
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
ECHO node.exe wasn't found in the PATH. Please make sure node is installed and available in the PATH. Exiting...
|
||||||
|
exit /b 1
|
||||||
|
) ELSE (
|
||||||
|
"node.exe" "%~dp0..\..\package\lib\cli\cli.js" %*
|
||||||
|
)
|
||||||
1679
bin/pac/tools/.playwright/package/ThirdPartyNotices.txt
Normal file
1679
bin/pac/tools/.playwright/package/ThirdPartyNotices.txt
Normal file
File diff suppressed because it is too large
Load Diff
1
bin/pac/tools/.playwright/package/api.json
Normal file
1
bin/pac/tools/.playwright/package/api.json
Normal file
File diff suppressed because one or more lines are too long
BIN
bin/pac/tools/.playwright/package/bin/PrintDeps.exe
Normal file
BIN
bin/pac/tools/.playwright/package/bin/PrintDeps.exe
Normal file
Binary file not shown.
223
bin/pac/tools/.playwright/package/bin/install_media_pack.ps1
Normal file
223
bin/pac/tools/.playwright/package/bin/install_media_pack.ps1
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
$osInfo = Get-WmiObject -Class Win32_OperatingSystem
|
||||||
|
# check if running on Windows Server
|
||||||
|
if ($osInfo.ProductType -eq 3) {
|
||||||
|
Install-WindowsFeature Server-Media-Foundation
|
||||||
|
}
|
||||||
|
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoRgYJKoZIhvcNAQcCoIIoNzCCKDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAozY2J/zs/KLri
|
||||||
|
# BMki3Tf+OWpCZfEvNi+Sg4O40S6muaCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJTVOYk7Cuqde813nhl4BinW
|
||||||
|
# SdpUR33uqqyUnzQirFlzMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEAhqnNmpbsn5slG6p7Ep0BeU/2Pw3e5cc9rCBpDAE3NkrSpR8cfPiK+HwV
|
||||||
|
# ZqEfic8wHSzPZ2mXvBdJg24MZPNArtGMvvWhvnbVM9RPUQqZ8qPl5junJSowugLl
|
||||||
|
# a/AIB2YgSNaTfxXssSCea6doac8HiC3ZW8EO4R2yVNzJNL8r2zSpJXsBMuC9ZlJJ
|
||||||
|
# jn9whzSZGjLe+fIx9yvYT6jjdBPghW7UofC/wM/bcQDybpExlHeJPCg83WLWi3e/
|
||||||
|
# fw2IjrviJc/Yw3cK8L95DZWQUIPjiUPTfld9Kn8Jxf8UZKLMZNm1JH3TKNT6tQ6L
|
||||||
|
# scMF6GyGbdwhVQMxI8hHqrpWdj0q7qGCF7AwghesBgorBgEEAYI3AwMBMYIXnDCC
|
||||||
|
# F5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCAL/JN+uM8tyJoWblzM2CSVdC+6zRbA73saWSoncGOa5wIGZzvDauLY
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxNi4wNjhaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo1NzFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB+8vLbDdn5TCVAAEAAAH7MA0G
|
||||||
|
# CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||||
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||||
|
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0
|
||||||
|
# MDcyNTE4MzExM1oXDTI1MTAyMjE4MzExM1owgdMxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w
|
||||||
|
# ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjU3MUEt
|
||||||
|
# MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
||||||
|
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqMJWQeWAq4LwvSjYsjP0
|
||||||
|
# Uvhvm0j0aAOJiMLg0sLfxKoTXAdKD6oMuq5rF5oEiOxV+9ox0H95Q8fhoZq3x9lx
|
||||||
|
# guZyTOK4l2xtcgtJCtjXRllM2bTpjOg35RUrBy0cAloBU9GJBs7LBNrcbH6rBiOv
|
||||||
|
# qDQNicPRZwq16xyjMidU1J1AJuat9yLn7taifoD58blYEcBvkj5dH1la9zU846QD
|
||||||
|
# eOoRO6NcqHLsDx8/zVKZxP30mW6Y7RMsqtB8cGCgGwVVurOnaNLXs31qTRTyVHX8
|
||||||
|
# ppOdoSihCXeqebgJCRzG8zG/e/k0oaBjFFGl+8uFELwCyh4wK9Z5+azTzfa2GD4p
|
||||||
|
# 6ihtskXs3lnW05UKfDJhAADt6viOc0Rk/c8zOiqzh0lKpf/eWUY2o/hvcDPZNgLa
|
||||||
|
# HvyfDqb8AWaKvO36iRZSXqhSw8SxJo0TCpsbCjmtx0LpHnqbb1UF7cq09kCcfWTD
|
||||||
|
# PcN12pbYLqck0bIIfPKbc7HnrkNQks/mSbVZTnDyT3O8zF9q4DCfWesSr1akycDd
|
||||||
|
# uGxCdKBvgtJh1YxDq1skTweYx5iAWXnB7KMyls3WQZbTubTCLLt8Xn8t+slcKm5D
|
||||||
|
# kvobubmHSriuTA3wTyIy4FxamTKm0VDu9mWds8MtjUSJVwNVVlBXaQ3ZMcVjijyV
|
||||||
|
# oUNVuBY9McwYcIQK62wQ20ECAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRHVSGYUNQ3
|
||||||
|
# RwOl71zIAuUjIKg1KjAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf
|
||||||
|
# BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
|
||||||
|
# L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww
|
||||||
|
# bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m
|
||||||
|
# dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El
|
||||||
|
# MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF
|
||||||
|
# BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAwzoIKOY2dnUj
|
||||||
|
# fWuMiGoz/ovoc1e86VwWaZNFdgRmOoQuRe4nLdtZONtTHNk3Sj3nkyBszzxSbZEQ
|
||||||
|
# 0DduyKHHI5P8V87jFttGnlR0wPP22FAebbvAbutkMMVQMFzhVBWiWD0VAnu9x0fj
|
||||||
|
# ifLKDAVXLwoun5rCFqwbasXFc7H/0DPiC+DBn3tUxefvcxUCys4+DC3s8CYp7WWX
|
||||||
|
# pZ8Wb/vdBhDliHmB7pWcmsB83uc4/P2GmAI3HMkOEu7fCaSYoQhouWOr07l/KM4T
|
||||||
|
# ndylIirm8f2WwXQcFEzmUvISM6ludUwGlVNfTTJUq2bTDEd3tlDKtV9AUY3rrnFw
|
||||||
|
# HTwJryLtT4IFhvgBfND3mL1eeSakKf7xTII4Jyt15SXhHd5oI/XGjSgykgJrWA57
|
||||||
|
# rGnAC7ru3/ZbFNCMK/Jj6X8X4L6mBOYa2NGKwH4A37YGDrecJ/qXXWUYvfLYqHGf
|
||||||
|
# 8ThYl12Yg1rwSKpWLolA/B1eqBw4TRcvVY0IvNNi5sm+//HJ9Aw6NJuR/uDR7X7v
|
||||||
|
# DXicpXMlRNgFMyADb8AFIvQPdHqcRpRorY+YUGlvzeJx/2gNYyezAokbrFhACsJ2
|
||||||
|
# BfyeLyCEo6AuwEHn511PKE8dK4JvlmLSoHj7VFR3NHDk3zRkx0ExkmF8aOdpvoKh
|
||||||
|
# uwBCxoZ/JhbzSzrvZ74GVjKKIyt5FA0wggdxMIIFWaADAgECAhMzAAAAFcXna54C
|
||||||
|
# m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
|
||||||
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
||||||
|
# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp
|
||||||
|
# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy
|
||||||
|
# MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
|
||||||
|
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
|
||||||
|
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B
|
||||||
|
# AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51
|
||||||
|
# yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY
|
||||||
|
# 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9
|
||||||
|
# cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN
|
||||||
|
# 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua
|
||||||
|
# Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74
|
||||||
|
# kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2
|
||||||
|
# K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5
|
||||||
|
# TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk
|
||||||
|
# i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q
|
||||||
|
# BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri
|
||||||
|
# Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC
|
||||||
|
# BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl
|
||||||
|
# pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB
|
||||||
|
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y
|
||||||
|
# eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA
|
||||||
|
# YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
|
||||||
|
# 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
|
||||||
|
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw
|
||||||
|
# MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
|
||||||
|
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w
|
||||||
|
# Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp
|
||||||
|
# b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm
|
||||||
|
# ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM
|
||||||
|
# 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW
|
||||||
|
# OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4
|
||||||
|
# FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw
|
||||||
|
# xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX
|
||||||
|
# fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX
|
||||||
|
# VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC
|
||||||
|
# onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU
|
||||||
|
# 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG
|
||||||
|
# ahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo1NzFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaIjCgEBMAcGBSsOAwIaAxUABHHn7NCGusZz2RfVbyuwYwPykBWggYMw
|
||||||
|
# gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF
|
||||||
|
# AAIFAOrwJKwwIhgPMjAyNDExMjYxMDQyNTJaGA8yMDI0MTEyNzEwNDI1MlowdzA9
|
||||||
|
# BgorBgEEAYRZCgQBMS8wLTAKAgUA6vAkrAIBADAKAgEAAgINJgIB/zAHAgEAAgIS
|
||||||
|
# xjAKAgUA6vF2LAIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAow
|
||||||
|
# CAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQALFoKWGPRg
|
||||||
|
# N3NzD6gTUGFFzMlKdvtuBN5MdrB9phus5y4xenH+RBff11B2BI0ugegJBYebORuv
|
||||||
|
# 753E4290DgYkdQ49kcYWPlHSKeP2CemB7ztaa0eMqMijHcntysZBCK6F2BA1pthy
|
||||||
|
# AIKbJts8p/I3a4m9XGTsfbod6RPqQah+3ZMwdolpZ8Z9c8rqskBB+0+fNk/6H2cn
|
||||||
|
# JqfN7Us85M00YOovJxp35aNlA1ibpjvdjNNqIkvLE/TyK4e5ERVliZAw1qMsr0+e
|
||||||
|
# K5icqqnTcU0uvbN669ZS+TTKsCJprWiSnVRsLOqHnGYvbjrt2sDoYP2V+ithiKZ9
|
||||||
|
# YdvPaA3Efpz1MYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
||||||
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
||||||
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
||||||
|
# IDIwMTACEzMAAAH7y8tsN2flMJUAAQAAAfswDQYJYIZIAWUDBAIBBQCgggFKMBoG
|
||||||
|
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgT5WjRtEe
|
||||||
|
# JSM4h43HIUleAChsCjIPIqFD2DrGfTA+yeswgfoGCyqGSIb3DQEJEAIvMYHqMIHn
|
||||||
|
# MIHkMIG9BCA52wKr/KCFlVNYiWsCLsB4qhjEYEP3xHqYqDu1SSTlGDCBmDCBgKR+
|
||||||
|
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
||||||
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
||||||
|
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB+8vLbDdn5TCVAAEA
|
||||||
|
# AAH7MCIEIKmKyq+vioruB6dbVTleQ+9z4dGDyCwN6noO8BCIHDhMMA0GCSqGSIb3
|
||||||
|
# DQEBCwUABIICAC7/y0HVAWUU6vZfmRideF6URwM1NVDSmHLrwlSEhAJdZdUH6xVZ
|
||||||
|
# 2NybbQnp9pi8tXgymHLtZxcI/w7duOd7r53az1pK33fC30kiSk369ZOZB6Jm4Fem
|
||||||
|
# TuAXbpSbRFClZ6o9HwLARuGbnIxXAWwH+Ws6BtSVSPOPPplfH3XeEP7WDa6jJaLw
|
||||||
|
# tBYCC87sqL8It0UdhjrEIz1RY1QKN17gngUA7huhvD+eWV9NDplSzhWb6U1pKqQL
|
||||||
|
# XfWlxy1mjKPAIvarlYjOgSdVXvbLM+CoA2ffttrrMcgCCzh14YKld4iekt2w1USg
|
||||||
|
# KLZCexHRfaygWkKDUxJIhiK4t6LRj+GMqu7yw739aQLg5ygDyFv2UsR9tg1S61oZ
|
||||||
|
# n31Pvvsd/u9zqKrkuFUtLYEqG5VFZ5iURdU+o69byuY1VJ7Cy67FnR7JR/72BFkR
|
||||||
|
# KH9wX9JHL4aUj7DWzzO/64KLjKaWBDQmg2IYAeLv55m4hlvwDdhL2CoW2PPhv2Q2
|
||||||
|
# Lc+4n+ppTFT/OzO/xt8kIuFJVaG8lbvNkI2VVwOEYAU8j1ldLNDrR6PDZE4fZV7F
|
||||||
|
# S0fo7wzXKP4yJPAXGGD7l8+NWy3NfqOKPyyZ6q+yT6/ValuJsqJdlAHjrUg5Xuey
|
||||||
|
# uTtQtnhgcxGD3vtQ24U5wmDP1fv+Zo/ZNaDpPFoGkTMQb/b9Nwrnl9rl
|
||||||
|
# SIG # End signature block
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ $(arch) == "aarch64" ]]; then
|
||||||
|
echo "ERROR: not supported on Linux Arm64"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/os-release" ]]; then
|
||||||
|
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
||||||
|
if [[ "${ID}" != "ubuntu" ]]; then
|
||||||
|
echo "ERROR: cannot install on $ID distribution - only Ubuntu is supported"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. make sure to remove old beta if any.
|
||||||
|
if dpkg --get-selections | grep -q "^google-chrome-beta[[:space:]]*install$" >/dev/null; then
|
||||||
|
apt-get remove -y google-chrome-beta
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Update apt lists (needed to install curl and chrome dependencies)
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# 3. Install curl to download chrome
|
||||||
|
if ! command -v curl >/dev/null; then
|
||||||
|
apt-get install -y curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. download chrome beta from dl.google.com and install it.
|
||||||
|
cd /tmp
|
||||||
|
curl -O https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb
|
||||||
|
apt-get install -y ./google-chrome-beta_current_amd64.deb
|
||||||
|
rm -rf ./google-chrome-beta_current_amd64.deb
|
||||||
|
cd -
|
||||||
|
google-chrome-beta --version
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
rm -rf "/Applications/Google Chrome Beta.app"
|
||||||
|
cd /tmp
|
||||||
|
curl -o ./googlechromebeta.dmg -k https://dl.google.com/chrome/mac/universal/beta/googlechromebeta.dmg
|
||||||
|
hdiutil attach -nobrowse -quiet -noautofsck -noautoopen -mountpoint /Volumes/googlechromebeta.dmg ./googlechromebeta.dmg
|
||||||
|
cp -rf "/Volumes/googlechromebeta.dmg/Google Chrome Beta.app" /Applications
|
||||||
|
hdiutil detach /Volumes/googlechromebeta.dmg
|
||||||
|
rm -rf /tmp/googlechromebeta.dmg
|
||||||
|
|
||||||
|
/Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta --version
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
$url = 'https://dl.google.com/tag/s/dl/chrome/install/beta/googlechromebetastandaloneenterprise.msi';
|
||||||
|
|
||||||
|
if ([Environment]::Is64BitProcess) {
|
||||||
|
$url = 'https://dl.google.com/tag/s/dl/chrome/install/beta/googlechromebetastandaloneenterprise64.msi'
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Downloading Google Chrome Beta"
|
||||||
|
$wc = New-Object net.webclient
|
||||||
|
$msiInstaller = "$env:temp\google-chrome-beta.msi"
|
||||||
|
$wc.Downloadfile($url, $msiInstaller)
|
||||||
|
|
||||||
|
Write-Host "Installing Google Chrome Beta"
|
||||||
|
$arguments = "/i `"$msiInstaller`" /quiet"
|
||||||
|
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
||||||
|
Remove-Item $msiInstaller
|
||||||
|
|
||||||
|
$suffix = "\\Google\\Chrome Beta\\Application\\chrome.exe"
|
||||||
|
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
||||||
|
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
||||||
|
} else {
|
||||||
|
write-host "ERROR: failed to install Google Chrome Beta"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoRgYJKoZIhvcNAQcCoIIoNzCCKDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB1DhiKuwcNb7EH
|
||||||
|
# hh293iRnCPFNZsyeP2TKuN4ynbAnfKCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFvbLgHdiNnQIVPdesqjNDzv
|
||||||
|
# 1wu78grmi93RqYLn/aiJMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEAUW2tHdSbXPxNf5yPP+36x3x4jwBj0YK5MB2YeAblF7R11k3GVAWWB3bf
|
||||||
|
# +HtACGgKfKsMUFLfg46q0Dehy1oSQfrPyDPdNKh6h3jC0yP0JyfMyANIwSeTpsG2
|
||||||
|
# vaDv54+ec74tlSMA/B4qaAxOxOrLRffjgHST9ogT0qqNTRCHlAkKiQ8T+Q4Hqqpg
|
||||||
|
# pLefxtf4ixUeAK42W2+SKtFunaZ4hBM3a3WOFGilMNjgWtWE7DNuT17y6fJ6imZa
|
||||||
|
# +qBZh2k2y9eHEBBibEsbVT/4zTlMeUET4SLd7g/WR1m1mA5sH60ppKz41seFXHUj
|
||||||
|
# 9UOLfxCLxqoB01WslO3BsKARJd1SC6GCF7AwghesBgorBgEEAYI3AwMBMYIXnDCC
|
||||||
|
# F5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCChMWzv4Ep2PaZsFqiKdCqutq+spGdOw+aQRYhP8QvKyQIGZzu/PiQf
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxNS4zODVaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# TjozNjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB91ggdQTK+8L0AAEAAAH3MA0G
|
||||||
|
# CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||||
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||||
|
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0
|
||||||
|
# MDcyNTE4MzEwNloXDTI1MTAyMjE4MzEwNlowgdMxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w
|
||||||
|
# ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjM2MDUt
|
||||||
|
# MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
||||||
|
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0OdHTBNom6/uXKaEKP9r
|
||||||
|
# PITkT6QxF11tjzB0Nk1byDpPrFTHha3hxwSdTcr8Y0a3k6EQlwqy6ROz42e0R5eD
|
||||||
|
# W+dCoQapipDIFUOYp3oNuqwX/xepATEkY17MyXFx6rQW2NcWUJW3Qo2AuJ0HOtbl
|
||||||
|
# SpItQZPGmHnGqkt/DB45Fwxk6VoSvxNcQKhKETkuzrt8U6DRccQm1FdhmPKgDzgc
|
||||||
|
# fDPM5o+GnzbiMu6y069A4EHmLMmkecSkVvBmcZ8VnzFHTDkGLdpnDV5FXjVObAgb
|
||||||
|
# SM0cnqYSGfRp7VGHBRqyoscvR4bcQ+CV9pDjbJ6S5rZn1uA8hRhj09Hs33HRevt4
|
||||||
|
# oWAVYGItgEsG+BrCYbpgWMDEIVnAgPZEiPAaI8wBGemE4feEkuz7TAwgkRBcUzLg
|
||||||
|
# Q4uvPqRD1A+Jkt26+pDqWYSn0MA8j0zacQk9q/AvciPXD9It2ez+mqEzgFRRsJGL
|
||||||
|
# tcf9HksvK8Jsd6I5zFShlqi5bpzf1Y4NOiNOh5QwW1pIvA5irlal7qFhkAeeeZqm
|
||||||
|
# op8+uNxZXxFCQG3R3s5pXW89FiCh9rmXrVqOCwgcXFIJQAQkllKsI+UJqGq9rmRA
|
||||||
|
# BJz5lHKTFYmFwcM52KWWjNx3z6odwz2h+sxaxewToe9GqtDx3/aU+yqNRcB8w0tS
|
||||||
|
# XUf+ylN4uk5xHEpLpx+ZNNsCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBTfRqQzP3m9
|
||||||
|
# PZWuLf1p8/meFfkmmDAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf
|
||||||
|
# BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
|
||||||
|
# L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww
|
||||||
|
# bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m
|
||||||
|
# dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El
|
||||||
|
# MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF
|
||||||
|
# BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAN0ajafILeL6S
|
||||||
|
# QIMIMAXM1Qd6xaoci2mOrpR8vKWyyTsL3b83A7XGLiAbQxTrqnXvVWWeNst5YQD8
|
||||||
|
# saO+UTgOLJdTdfUADhLXoK+RlwjfndimIJT9MH9tUYXLzJXKhZM09ouPwNsrn8YO
|
||||||
|
# LIpdAi5TPyN8Cl11OGZSlP9r8JnvomW00AoJ4Pl9rlg0G5lcQknAXqHa9nQdWp1Z
|
||||||
|
# xXqNd+0JsKmlR8tcANX33ClM9NnaClJExLQHiKeHUUWtqyLMl65TW6wRM7XlF7Y+
|
||||||
|
# PTnC8duNWn4uLng+ON/Z39GO6qBj7IEZxoq4o3avEh9ba43UU6TgzVZaBm8VaA0w
|
||||||
|
# SwUe/pqpTOYFWN62XL3gl/JC2pzfIPxP66XfRLIxafjBVXm8KVDn2cML9IvRK02s
|
||||||
|
# 941Y5+RR4gSAOhLiQQ6A03VNRup+spMa0k+XTPAi+2aMH5xa1Zjb/K8u9f9M05U0
|
||||||
|
# /bUMJXJDP++ysWpJbVRDiHG7szaca+r3HiUPjQJyQl2NiOcYTGV/DcLrLCBK2zG5
|
||||||
|
# 03FGb04N5Kf10XgAwFaXlod5B9eKh95PnXKx2LNBgLwG85anlhhGxxBQ5mFsJGkB
|
||||||
|
# n0PZPtAzZyfr96qxzpp2pH9DJJcjKCDrMmZziXazpa5VVN36CO1kDU4ABkSYTXOM
|
||||||
|
# 8RmJXuQm7mUF3bWmj+hjAJb4pz6hT5UwggdxMIIFWaADAgECAhMzAAAAFcXna54C
|
||||||
|
# m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
|
||||||
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
||||||
|
# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp
|
||||||
|
# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy
|
||||||
|
# MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
|
||||||
|
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
|
||||||
|
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B
|
||||||
|
# AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51
|
||||||
|
# yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY
|
||||||
|
# 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9
|
||||||
|
# cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN
|
||||||
|
# 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua
|
||||||
|
# Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74
|
||||||
|
# kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2
|
||||||
|
# K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5
|
||||||
|
# TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk
|
||||||
|
# i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q
|
||||||
|
# BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri
|
||||||
|
# Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC
|
||||||
|
# BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl
|
||||||
|
# pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB
|
||||||
|
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y
|
||||||
|
# eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA
|
||||||
|
# YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
|
||||||
|
# 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
|
||||||
|
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw
|
||||||
|
# MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
|
||||||
|
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w
|
||||||
|
# Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp
|
||||||
|
# b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm
|
||||||
|
# ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM
|
||||||
|
# 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW
|
||||||
|
# OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4
|
||||||
|
# FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw
|
||||||
|
# xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX
|
||||||
|
# fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX
|
||||||
|
# VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC
|
||||||
|
# onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU
|
||||||
|
# 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG
|
||||||
|
# ahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# TjozNjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAb28KDG/xXbNBjmM7/nqw3bgrEOaggYMw
|
||||||
|
# gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF
|
||||||
|
# AAIFAOrwIH8wIhgPMjAyNDExMjYxMDI1MDNaGA8yMDI0MTEyNzEwMjUwM1owdzA9
|
||||||
|
# BgorBgEEAYRZCgQBMS8wLTAKAgUA6vAgfwIBADAKAgEAAgIr2QIB/zAHAgEAAgIU
|
||||||
|
# mTAKAgUA6vFx/wIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAow
|
||||||
|
# CAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQB0LXZGhgQt
|
||||||
|
# DbroRk574qzymt1zTmwoSvA2n3eo/3rycgSqRBl0Z8d5dbGNXXRoPxN8rahjXref
|
||||||
|
# I4fJIK490Lf8h0bJh7QZFYsBfENm9k8icJ4JLMQWyqiG984DQATArgIZs2eqGfd+
|
||||||
|
# SShgg5DmuYS+vXAxrQZOHBlq54/Oh5ozRbcsYxwCaVutNVG2d5gaTOn0AckohNsY
|
||||||
|
# fsJml3DIqlCiiwCDOr+CkQyVs9BFN7MleKOycn+TPCSmx3bh0frD23iQzQpXolSZ
|
||||||
|
# 9p9L0wXwlccQ5/F0Q9PRfremg3BitogiDIp4PrxO3fQLjXIaSantrR7Fqj0VtBCz
|
||||||
|
# Gfhm3wy82tzuMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
||||||
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
||||||
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
||||||
|
# IDIwMTACEzMAAAH3WCB1BMr7wvQAAQAAAfcwDQYJYIZIAWUDBAIBBQCgggFKMBoG
|
||||||
|
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgmIaBTLk3
|
||||||
|
# euRk1kxerxq9SQp/3Uksjcl/F/+5HFauuc4wgfoGCyqGSIb3DQEJEAIvMYHqMIHn
|
||||||
|
# MIHkMIG9BCAh2pjaa3ca0ecYuhu60uYHP/IKnPbedbVQJ5SoIH5Z4jCBmDCBgKR+
|
||||||
|
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
||||||
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
||||||
|
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB91ggdQTK+8L0AAEA
|
||||||
|
# AAH3MCIEICNEh+XmpmJload1kkrx3vPoOky8/8wP01Ayyy31hiosMA0GCSqGSIb3
|
||||||
|
# DQEBCwUABIICADtaHTPMXo7xQbnEbo5R07eY9H5BMaX408Ht8tgCcolEz6pbfsp+
|
||||||
|
# pI68BJC3uiwpc2/f2YWwQb8BLCMOlqjqk1aAOLTy10ldqNkz+Io0kwfKgvugsahS
|
||||||
|
# +tdfzuMj0w+wy5TnRV+UI+cDPrIIMsPaXjDpQVVIUn2Y1vNVDQXY825iWjLirBQl
|
||||||
|
# q8hZ7BtjqkrkGFxG039HCe4PFPJNvyZW47jh+1ND/8341EVOl3tfCTBAl5+Ujbux
|
||||||
|
# trdUdbNMB2YDS1maCrJUMA367xialBhtgoDJ9jI9XfW+CUtalGdjiez6vPzdx7y/
|
||||||
|
# qHJbkKLsnJQoEsW/2fioCBBoNr9dBAeBSdNMt914kLS1v9tZh6abxGizaNWeSZVT
|
||||||
|
# jKlmC70Ay5X1ICKZ/GFDEE1TQXXZjPPuOlSU/zKSb3yP8o2jRw+DPM8ZKirx4mk/
|
||||||
|
# braPO+ViqqBYvouOvXVXcECr17/dajJGcLClXvU0Be4N6vZGxsA0L9lZRKaVYMB/
|
||||||
|
# e7yuo535Pd3cSdadaYEu6Hzl0X715/FJbnp4CgOmE5JL38wo/QbYTScyA1sBYWaQ
|
||||||
|
# shYRgSNhDpFKH7AyVp/1YvRMtouu/2YUAerBuSAy0U7Bb7bMOQCKx2u8OeO56wS1
|
||||||
|
# IIfa5RkOUOyO7gswLSOmQGxf4JD7dAyxqGzhxkjkCbtzwrh96PvJPUr8
|
||||||
|
# SIG # End signature block
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ $(arch) == "aarch64" ]]; then
|
||||||
|
echo "ERROR: not supported on Linux Arm64"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/os-release" ]]; then
|
||||||
|
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
||||||
|
if [[ "${ID}" != "ubuntu" ]]; then
|
||||||
|
echo "ERROR: cannot install on $ID distribution - only Ubuntu is supported"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. make sure to remove old stable if any.
|
||||||
|
if dpkg --get-selections | grep -q "^google-chrome[[:space:]]*install$" >/dev/null; then
|
||||||
|
apt-get remove -y google-chrome
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Update apt lists (needed to install curl and chrome dependencies)
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# 3. Install curl to download chrome
|
||||||
|
if ! command -v curl >/dev/null; then
|
||||||
|
apt-get install -y curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. download chrome stable from dl.google.com and install it.
|
||||||
|
cd /tmp
|
||||||
|
curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||||
|
apt-get install -y ./google-chrome-stable_current_amd64.deb
|
||||||
|
rm -rf ./google-chrome-stable_current_amd64.deb
|
||||||
|
cd -
|
||||||
|
google-chrome --version
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
rm -rf "/Applications/Google Chrome.app"
|
||||||
|
cd /tmp
|
||||||
|
curl -o ./googlechrome.dmg -k https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg
|
||||||
|
hdiutil attach -nobrowse -quiet -noautofsck -noautoopen -mountpoint /Volumes/googlechrome.dmg ./googlechrome.dmg
|
||||||
|
cp -rf "/Volumes/googlechrome.dmg/Google Chrome.app" /Applications
|
||||||
|
hdiutil detach /Volumes/googlechrome.dmg
|
||||||
|
rm -rf /tmp/googlechrome.dmg
|
||||||
|
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
$url = 'https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise.msi';
|
||||||
|
|
||||||
|
if ([Environment]::Is64BitProcess) {
|
||||||
|
$url = 'https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi'
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc = New-Object net.webclient
|
||||||
|
$msiInstaller = "$env:temp\google-chrome.msi"
|
||||||
|
Write-Host "Downloading Google Chrome"
|
||||||
|
$wc.Downloadfile($url, $msiInstaller)
|
||||||
|
|
||||||
|
Write-Host "Installing Google Chrome"
|
||||||
|
$arguments = "/i `"$msiInstaller`" /quiet"
|
||||||
|
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
||||||
|
Remove-Item $msiInstaller
|
||||||
|
|
||||||
|
|
||||||
|
$suffix = "\\Google\\Chrome\\Application\\chrome.exe"
|
||||||
|
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
||||||
|
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
||||||
|
} else {
|
||||||
|
write-host "ERROR: failed to install Google Chrome"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoRgYJKoZIhvcNAQcCoIIoNzCCKDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCApHGIDy0iPxLxp
|
||||||
|
# YspqTScUjuZcphWTWoewNYY4w1ywAKCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIKssaeVczmQgezQ6TQqmw62I
|
||||||
|
# s11tqGTKmJtKnAgE/e0nMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEArJGSEQ5qRHpkV6DpTBOvd7H/YvCSdstYQAkdyZ3/2uD7nbFUwa+xk/up
|
||||||
|
# pmBHbFUpllB2KLV3Qoa/1PnEBT/jsgmye67HiRQTJdPrSpjq/05cTE3kAfo94rT2
|
||||||
|
# iz659XD/1/PjMtq9NBrcKhTzxVrNWyBZIPO1yeS3fpRPsu2Knn2w+3MssjXNDUiE
|
||||||
|
# 6IWKUuY1Q0H3GiVQrrnkp6QeZPhjx3zkdYnL4CQ+6psjBAIqXWpchpYqnyeWp/dO
|
||||||
|
# 5ru8ElthEczMiziIt0uHh+SlC21SXrFAkVewssYI1NJ1nZYeDAAXDM2CLH72VDwL
|
||||||
|
# 7npY1MaL+ZnzF4RvEvtopyIJ5GTwBaGCF7AwghesBgorBgEEAYI3AwMBMYIXnDCC
|
||||||
|
# F5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCBkhdUAYGySGL86xgeJ7SrU39wLG9LKqQGle8YjPbcXAgIGZzu9GUYY
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxMi4yNThaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB9oMvJmpUXSLBAAEAAAH2MA0G
|
||||||
|
# CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||||
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||||
|
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0
|
||||||
|
# MDcyNTE4MzEwNFoXDTI1MTAyMjE4MzEwNFowgdMxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w
|
||||||
|
# ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjZCMDUt
|
||||||
|
# MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
||||||
|
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0UJeLMR/N9WPBZhuKVFF
|
||||||
|
# +eWJZ68Wujdj4X6JR05cxO5CepNXo17rVazwWLkm5AjaVh19ZVjDChHzimxsoaXx
|
||||||
|
# Nu8IDggKwpXvpAAItv4Ux50e9S2uVwfKv57p9JKG+Q7VONShujl1NCMkcgSrPdmd
|
||||||
|
# /8zcsmhzcNobLomrCAIORZ8IwhYy4siVQlf1NKhlyAzmkWJD0N+60IiogFBzg3yI
|
||||||
|
# SsvroOx0x1xSi2PiRIQlTXE74MggZDIDKqH/hb9FT2kK/nV/aXjuo9LMrrRmn44o
|
||||||
|
# YYADe/rO95F+SG3uuuhf+H4IriXr0h9ptA6SwHJPS2VmbNWCjQWq5G4YkrcqbPMa
|
||||||
|
# x7vNXUwu7T65E8fFPd1IuE9RsG4TMAV7XkXBopmPNfvL0hjxg44kpQn384V46o+z
|
||||||
|
# dQqy5K9dDlWm/J6vZtp5yA1PyD3w+HbGubS0niEQ1L6wGOrPfzIm0FdOn+xFo48E
|
||||||
|
# Rl+Fxw/3OvXM5CY1EqnzEznPjzJc7OJwhJVR3VQDHjBcEFTOvS9E0diNu1eocw+Z
|
||||||
|
# Ckz4Pu/oQv+gqU+bfxL8e7PFktfRDlM6FyOzjP4zuI25gD8tO9zJg6g6fRpaZc43
|
||||||
|
# 9mAbkl3zCVzTLDgchv6SxQajJtvvoQaZxQf0tRiPcbr2HWfMoqqd9uiQ0hTUEhG4
|
||||||
|
# 4FBSTeUPZeEenRCWadCW4G8CAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRIwZsJuOcJ
|
||||||
|
# fScPWcXZuBA4B89K8jAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf
|
||||||
|
# BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
|
||||||
|
# L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww
|
||||||
|
# bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m
|
||||||
|
# dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El
|
||||||
|
# MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF
|
||||||
|
# BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEA13kBirH1cHu1
|
||||||
|
# WYR1ysj125omGtQ0PaQkEzwGb70xtqSoI+svQihsgdTYxaPfp2IVFdgjaMaBi81w
|
||||||
|
# B8/nu866FfFKKdhdp3wnMZ91PpP4Ooe7Ncf6qICkgSuwgdIdQvqE0h8VQ5QW5sDV
|
||||||
|
# 4Q0Jnj4f7KHYx4NiM8C4jTw8SQtsuxWiTH2Hikf3QYB71a7dB9zgHOkW0hgUEeWO
|
||||||
|
# 9mh2wWqYS/Q48ASjOqYw/ha54oVOff22WaoH+/Hxd9NTEU/4vlvsRIMWT0jsnNI7
|
||||||
|
# 1jVArT4Q9Bt6VShWzyqraE6SKUoZrEwBpVsI0LMg2X3hOLblC1vxM3+wMyOh97aF
|
||||||
|
# Os7sFnuemtI2Mfj8qg16BZTJxXlpPurWrG+OBj4BoTDkC9AxXYB3yEtuwMs7pRWL
|
||||||
|
# yxIxw/wV9THKUGm+x+VE0POLwkrSMgjulSXkpfELHWWiCVslJbFIIB/4Alv+jQJS
|
||||||
|
# KAJuo9CErbm2qeDk/zjJYlYaVGMyKuYZ+uSRVKB2qkEPcEzG1dO9zIa1Mp32J+zz
|
||||||
|
# W3P7suJfjw62s3hDOLk+6lMQOR04x+2o17G3LceLkkxJm41ErdiTjAmdClen9yl6
|
||||||
|
# HgMpGS4okjFCJX+CpOFX7gBA3PVxQWubisAQbL5HgTFBtQNEzcCdh1GYw/6nzzNN
|
||||||
|
# t+0GQnnobBddfOAiqkzvItqXjvGyK1QwggdxMIIFWaADAgECAhMzAAAAFcXna54C
|
||||||
|
# m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
|
||||||
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
||||||
|
# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp
|
||||||
|
# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy
|
||||||
|
# MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
|
||||||
|
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
|
||||||
|
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B
|
||||||
|
# AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51
|
||||||
|
# yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY
|
||||||
|
# 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9
|
||||||
|
# cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN
|
||||||
|
# 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua
|
||||||
|
# Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74
|
||||||
|
# kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2
|
||||||
|
# K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5
|
||||||
|
# TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk
|
||||||
|
# i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q
|
||||||
|
# BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri
|
||||||
|
# Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC
|
||||||
|
# BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl
|
||||||
|
# pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB
|
||||||
|
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y
|
||||||
|
# eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA
|
||||||
|
# YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
|
||||||
|
# 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
|
||||||
|
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw
|
||||||
|
# MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
|
||||||
|
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w
|
||||||
|
# Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp
|
||||||
|
# b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm
|
||||||
|
# ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM
|
||||||
|
# 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW
|
||||||
|
# OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4
|
||||||
|
# FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw
|
||||||
|
# xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX
|
||||||
|
# fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX
|
||||||
|
# VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC
|
||||||
|
# onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU
|
||||||
|
# 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG
|
||||||
|
# ahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAFU9eSpdxs0a06JFIuGFHIj/I+36ggYMw
|
||||||
|
# gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF
|
||||||
|
# AAIFAOrwHlowIhgPMjAyNDExMjYxMDE1NTRaGA8yMDI0MTEyNzEwMTU1NFowdzA9
|
||||||
|
# BgorBgEEAYRZCgQBMS8wLTAKAgUA6vAeWgIBADAKAgEAAgInaQIB/zAHAgEAAgIT
|
||||||
|
# JjAKAgUA6vFv2gIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAow
|
||||||
|
# CAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQDTjykwci1W
|
||||||
|
# qYP29DQ84PpthOKq76GOT04VqA3oUFCqlE1CO8HvsqG0We26k6ogOb0wH6OKCKRA
|
||||||
|
# YLIYWmHD1fUg7MVFhbaC5KfQNVG4V+i+ajlVfTuHUjvJO/dh06bGkUTK5UvHPe25
|
||||||
|
# BYlJWHqanK1pacoK59VS6mL9iqAb8WvpJPcUdlWJxJmCW+fznycE7iFbHuVxH9VO
|
||||||
|
# NYQYg2ju7snYKr80bhM1M8K96leX+iAUrDTOl65hVQzow5ACY8tulrWAZH9b6AL6
|
||||||
|
# gQ3ARY7qnbE6K892vbajUlvv0XheCZMvWcCjW1Jwcm+oLAZ8GIRhy/9dnXkvW4Rd
|
||||||
|
# ru7sIdvC0TTkMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
||||||
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
||||||
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
||||||
|
# IDIwMTACEzMAAAH2gy8malRdIsEAAQAAAfYwDQYJYIZIAWUDBAIBBQCgggFKMBoG
|
||||||
|
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgyGkejFdr
|
||||||
|
# 2C0H9vp3MnP7Vc87l4S5U6DNob7AIrH6CogwgfoGCyqGSIb3DQEJEAIvMYHqMIHn
|
||||||
|
# MIHkMIG9BCArYUzxlF6m5USLS4f8NXL/8aoNEVdsCZRmF+LlQjG2ojCBmDCBgKR+
|
||||||
|
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
||||||
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
||||||
|
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB9oMvJmpUXSLBAAEA
|
||||||
|
# AAH2MCIEICAwWF7ZmU+CItAHOAZPKBBt7wUgxhozhxo3KL7p+bXRMA0GCSqGSIb3
|
||||||
|
# DQEBCwUABIICAHMZVMiQQVTX/Dz8M/uajlU5UZXbKIewrirrSbGmNAXBSUohp5UG
|
||||||
|
# ZykI3Gd8B9f0EcONICwr8U19os9IOyl9CuPnOBr96flDCoXwj45dGUSXYJLBDBiG
|
||||||
|
# pDueQGX9Apd8SL6RmB5HOnFbJ60ZhenuiOiLoxIE8SH0LcEwdGD9lCYbrix0Ly94
|
||||||
|
# LlPblhfuaZnPD7MWPYyVKPQLLH/0UGWqoAmmW2Imu877G5IRzqXh1x9WGJbGGXB1
|
||||||
|
# m2udDdeTAHleFHTmGMfK0FPhf6KJ6zZ/iqRc3RxFCLMGNGe2HcmspuOafqJeIoj0
|
||||||
|
# 4VAierfuE2dT/cOcihZNOykzJbfOua9pPaGIO/LWB+fIRqparSq81qR77JXHAe7Z
|
||||||
|
# OnFdO7OaRaUK+IaI2xxGZIAlLGySZ+7H2wjbcddCb/SfyIQNnMb5Xl1mgjw52/zr
|
||||||
|
# HXjIscR7p1aj2cFAKAtJpnORLGGXLYiih6ly9ZY9yGHRhIZFXBZTnt8EeAkbFLOE
|
||||||
|
# V5eiFMKjH7LIJ3QaEcjFlkpIfUcW++UhxzsNjNxeU+MU/doD0wokxVsFWr3VjzgI
|
||||||
|
# gT7h8phpuZu4XywES7GDgRPdm6OhefHBivh09lHvuH+WfnEKdk6mxB1PfZvBoZ3+
|
||||||
|
# dyFJk3EiUwrkIHg7Raj4IJWY+D28sAbkEpC27Co16LEy/O6C/8alJDkx
|
||||||
|
# SIG # End signature block
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ $(arch) == "aarch64" ]]; then
|
||||||
|
echo "ERROR: not supported on Linux Arm64"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/os-release" ]]; then
|
||||||
|
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
||||||
|
if [[ "${ID}" != "ubuntu" ]]; then
|
||||||
|
echo "ERROR: cannot install on $ID distribution - only Ubuntu is supported"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. make sure to remove old beta if any.
|
||||||
|
if dpkg --get-selections | grep -q "^microsoft-edge-beta[[:space:]]*install$" >/dev/null; then
|
||||||
|
apt-get remove -y microsoft-edge-beta
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Install curl to download Microsoft gpg key
|
||||||
|
if ! command -v curl >/dev/null; then
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Add the GPG key, the apt repo, update the apt cache, and install the package
|
||||||
|
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
|
||||||
|
install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
|
||||||
|
sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge-dev.list'
|
||||||
|
rm /tmp/microsoft.gpg
|
||||||
|
apt-get update && apt-get install -y microsoft-edge-beta
|
||||||
|
|
||||||
|
microsoft-edge-beta --version
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
curl -o ./msedge_beta.pkg -k "$1"
|
||||||
|
# Note: there's no way to uninstall previously installed MSEdge.
|
||||||
|
# However, running PKG again seems to update installation.
|
||||||
|
sudo installer -pkg /tmp/msedge_beta.pkg -target /
|
||||||
|
rm -rf /tmp/msedge_beta.pkg
|
||||||
|
/Applications/Microsoft\ Edge\ Beta.app/Contents/MacOS/Microsoft\ Edge\ Beta --version
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
$url = $args[0]
|
||||||
|
|
||||||
|
Write-Host "Downloading Microsoft Edge Beta"
|
||||||
|
$wc = New-Object net.webclient
|
||||||
|
$msiInstaller = "$env:temp\microsoft-edge-beta.msi"
|
||||||
|
$wc.Downloadfile($url, $msiInstaller)
|
||||||
|
|
||||||
|
Write-Host "Installing Microsoft Edge Beta"
|
||||||
|
$arguments = "/i `"$msiInstaller`" /quiet"
|
||||||
|
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
||||||
|
Remove-Item $msiInstaller
|
||||||
|
|
||||||
|
$suffix = "\\Microsoft\\Edge Beta\\Application\\msedge.exe"
|
||||||
|
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
||||||
|
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
||||||
|
} else {
|
||||||
|
write-host "ERROR: failed to install Microsoft Edge"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoKgYJKoZIhvcNAQcCoIIoGzCCKBcCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDf1+3BD26c9pYb
|
||||||
|
# sKMta6Lxdx8taMn7lUbKogdG2g1bIqCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGgowghoGAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJbZXIB/gM5/cPnsr8OtbKo3
|
||||||
|
# gpf9C/rBj48NvJPCvGflMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEALmeXMxMrMs7EdpKUTgl9NRlyrjRXyy0SMAyM9YCuATJ7rOQa5HcyKhwl
|
||||||
|
# XyBjNeX9KPfQLwqN7U35sWc8kFiOfeM5IRVUZWvI90V8S/5fS2V5+N1bHuZu04YE
|
||||||
|
# BRbVMpdaVcFs/vTOQ/7PbIXhoKdccw9PRO+XPGxdZp8sJNxRxqCDY+Q97UVdt/qq
|
||||||
|
# ykTRFqVyZS5Oc2nsEcO//Qi0J7CE2zdQDylIhtxs6l9siJisxEUQA+1gKxnPL7NF
|
||||||
|
# 1bqWwD6SP/cHyqmbOitYDxb7OGdvofqZ2icVZ324DAatgD+gh6ikaPEZhaJTNh2T
|
||||||
|
# av+zvinxPPBWf3dXxxax+JQhs28zcaGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCC
|
||||||
|
# F3wGCSqGSIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCAO//YbVA4sXXhm+ZjKsaFx8sVRi3eEoEqxk8spL6wsAQIGZz9JAIED
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxMy44OTZaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l
|
||||||
|
# cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046OTYwMC0w
|
||||||
|
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wg
|
||||||
|
# ghHqMIIHIDCCBQigAwIBAgITMwAAAe+JP1ahWMyo2gABAAAB7zANBgkqhkiG9w0B
|
||||||
|
# AQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yMzEyMDYxODQ1
|
||||||
|
# NDhaFw0yNTAzMDUxODQ1NDhaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
|
||||||
|
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
|
||||||
|
# cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z
|
||||||
|
# MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046OTYwMC0wNUUwLUQ5NDcxJTAjBgNV
|
||||||
|
# BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4ICDwAwggIKAoICAQCjC1jinwzgHwhOakZqy17oE4BIBKsm5kX4DUmCBWI0
|
||||||
|
# lFVpEiK5mZ2Kh59soL4ns52phFMQYGG5kypCipungwP9Nob4VGVE6aoMo5hZ9Nyt
|
||||||
|
# XR5ZRgb9Z8NR6EmLKICRhD4sojPMg/RnGRTcdf7/TYvyM10jLjmLyKEegMHfvIwP
|
||||||
|
# mM+AP7hzQLfExDdqCJ2u64Gd5XlnrFOku5U9jLOKk1y70c+Twt04/RLqruv1fGP8
|
||||||
|
# LmYmtHvrB4TcBsADXSmcFjh0VgQkX4zXFwqnIG8rgY+zDqJYQNZP8O1Yo4kSckHT
|
||||||
|
# 43XC0oM40ye2+9l/rTYiDFM3nlZe2jhtOkGCO6GqiTp50xI9ITpJXi0vEek8AejT
|
||||||
|
# 4PKMEO2bPxU63p63uZbjdN5L+lgIcCNMCNI0SIopS4gaVR4Sy/IoDv1vDWpe+I28
|
||||||
|
# /Ky8jWTeed0O3HxPJMZqX4QB3I6DnwZrHiKn6oE38tgBTCCAKvEoYOTg7r2lF0Iu
|
||||||
|
# bt/3+VPvKtTCUbZPFOG8jZt9q6AFodlvQntiolYIYtqSrLyXAQIlXGhZ4gNcv4dv
|
||||||
|
# 1YAilnbWA9CsnYh+OKEFr/4w4M69lI+yaoZ3L/t/UfXpT/+yc7hS/FolcmrGFJTB
|
||||||
|
# YlS4nE1cuKblwZ/UOG26SLhDONWXGZDKMJKN53oOLSSk4ldR0HlsbT4heLlWlOEl
|
||||||
|
# JQIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFO1MWqKFwrCbtrw9P8A63bAVSJzLMB8G
|
||||||
|
# A1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCG
|
||||||
|
# Tmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy
|
||||||
|
# MFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4w
|
||||||
|
# XAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2Vy
|
||||||
|
# dHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwG
|
||||||
|
# A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQD
|
||||||
|
# AgeAMA0GCSqGSIb3DQEBCwUAA4ICAQAYGZa3aCDudbk9EVdkP8xcQGZuIAIPRx9K
|
||||||
|
# 1CA7uRzBt80fC0aWkuYYhQMvHHJRHUobSM4Uw3zN7fHEN8hhaBDb9NRaGnFWdtHx
|
||||||
|
# mJ9eMz6Jpn6KiIyi9U5Og7QCTZMl17n2w4eddq5vtk4rRWOVvpiDBGJARKiXWB9u
|
||||||
|
# 2ix0WH2EMFGHqjIhjWUXhPgR4C6NKFNXHvWvXecJ2WXrJnvvQGXAfNJGETJZGpR4
|
||||||
|
# 1nUN3ijfiCSjFDxamGPsy5iYu904Hv9uuSXYd5m0Jxf2WNJSXkPGlNhrO27pPxgT
|
||||||
|
# 111myAR61S3S2hc572zN9yoJEObE98Vy5KEM3ZX53cLefN81F1C9p/cAKkE6u9V6
|
||||||
|
# ryyl/qSgxu1UqeOZCtG/iaHSKMoxM7Mq4SMFsPT/8ieOdwClYpcw0CjZe5KBx2xL
|
||||||
|
# a4B1neFib8J8/gSosjMdF3nHiyHx1YedZDtxSSgegeJsi0fbUgdzsVMJYvqVw52W
|
||||||
|
# qQNu0GRC79ZuVreUVKdCJmUMBHBpTp6VFopL0Jf4Srgg+zRD9iwbc9uZrn+89odp
|
||||||
|
# InbznYrnPKHiO26qe1ekNwl/d7ro2ItP/lghz0DoD7kEGeikKJWHdto7eVJoJhkr
|
||||||
|
# UcanTuUH08g+NYwG6S+PjBSB/NyNF6bHa/xR+ceAYhcjx0iBiv90Mn0JiGfnA2/h
|
||||||
|
# Lj5evhTcAjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZI
|
||||||
|
# hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
|
||||||
|
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
||||||
|
# MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy
|
||||||
|
# MDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMC
|
||||||
|
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
||||||
|
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
|
||||||
|
# bWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
||||||
|
# AQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25Phdg
|
||||||
|
# M/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPF
|
||||||
|
# dvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6
|
||||||
|
# GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBp
|
||||||
|
# Dco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50Zu
|
||||||
|
# yjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3E
|
||||||
|
# XzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0
|
||||||
|
# lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1q
|
||||||
|
# GFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ
|
||||||
|
# +QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PA
|
||||||
|
# PBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkw
|
||||||
|
# EgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxG
|
||||||
|
# NSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARV
|
||||||
|
# MFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj
|
||||||
|
# cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAK
|
||||||
|
# BggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
|
||||||
|
# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
|
||||||
|
# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
|
||||||
|
# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
|
||||||
|
# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG
|
||||||
|
# 9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0x
|
||||||
|
# M7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmC
|
||||||
|
# VgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449
|
||||||
|
# xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wM
|
||||||
|
# nosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDS
|
||||||
|
# PeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2d
|
||||||
|
# Y3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxn
|
||||||
|
# GSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+Crvs
|
||||||
|
# QWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokL
|
||||||
|
# jzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL
|
||||||
|
# 6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNN
|
||||||
|
# MIICNQIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
|
||||||
|
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
|
||||||
|
# b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn
|
||||||
|
# MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjk2MDAtMDVFMC1EOTQ3MSUwIwYDVQQD
|
||||||
|
# ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQBL
|
||||||
|
# cI81gxbea1Ex2mFbXx7ck+0g/6CBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
|
||||||
|
# IFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA6vBemjAiGA8yMDI0MTEyNjE0NTAw
|
||||||
|
# MloYDzIwMjQxMTI3MTQ1MDAyWjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDq8F6a
|
||||||
|
# AgEAMAcCAQACAhLqMAcCAQACAhRhMAoCBQDq8bAaAgEAMDYGCisGAQQBhFkKBAIx
|
||||||
|
# KDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZI
|
||||||
|
# hvcNAQELBQADggEBAKVyZWygzcL1G3D4hsEutB0PmLExvb5v8aZRREcrR7CWGJ/W
|
||||||
|
# l3x6086qxcJlTLi1sYaKwaH4CBpxTFVA0/3+26IaXZlBcl4Wfm2d7U4+s25EJB59
|
||||||
|
# vWj8tE/zRGjYUjdQLAx7CcXVepl4yJ6kRT62NcmM0Tb1RPtHsm5mDQM/agSNTOaC
|
||||||
|
# 4F7Oi6SxtO2J+Oj8N0+ndViGFan+/PhZzsYprYsqFR3gHHJNQ277C+755nx0yCws
|
||||||
|
# Vt5OhPr6Ktrj3jdMEDegS7nwpQkNNOOcCFMUDQS2hUQWVKBSRNorYayo+hHahANr
|
||||||
|
# N2o5Aer+7oay/Y3GvLM+EQxtmkiksj7d4YmVBk0xggQNMIIECQIBATCBkzB8MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy
|
||||||
|
# b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAe+JP1ahWMyo2gABAAAB7zAN
|
||||||
|
# BglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8G
|
||||||
|
# CSqGSIb3DQEJBDEiBCAaHFWvQXYjHnKX1KKco0i+NlcmSock6OS5pvpVJU4UVzCB
|
||||||
|
# +gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIPBhKEW4Fo3wUz09NQx2a0DbcdsX
|
||||||
|
# 8jovM5LizHmnyX+jMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
|
||||||
|
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
|
||||||
|
# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
|
||||||
|
# MTACEzMAAAHviT9WoVjMqNoAAQAAAe8wIgQg0hdmAewFzmmrMS3Pizl+RggBp1Xr
|
||||||
|
# Gw1SsQAlShqoodIwDQYJKoZIhvcNAQELBQAEggIANdnIIuRAXOuM2IXoUhz83UE0
|
||||||
|
# GS805ohNrWtuGpnEbK7A2n9wfOC2JvKzkODuaeD784ZICtYV/gB1+h9PRM7w7UcY
|
||||||
|
# Vc78DzX0Txjin802d+RfXpCU8w8NBioX5unGCpQFvBASW2lAZQ68xwOPQj8iqJ7Q
|
||||||
|
# blNI+M+YTWMK+7oDrIXIk3C+Udd066DZvUElB+qSqYX5sEK2cyuvQjBJ20slcPUs
|
||||||
|
# v2o7w2A/Q3sbm2tRj7V36N2EIcJuYxz8JeQGBG5Wf8Ufe28fSQ/LpYjZYw4v0wxo
|
||||||
|
# XfvfYmxyfiO1Ok7hChsNEpANDZ22kGIA571w1wg3Wa5mr9Rvqc2l15GOrB6pn0c/
|
||||||
|
# 5sufet4fHquTh8fBYDr1DWccW0DBSdYuBdrtrGHdcY7mCXZtQGeduUMoKUurgbQh
|
||||||
|
# ASh+9Ax2FIkeK/tNFu3vbI/Lg5nL08RwWJJQq06vfr+NAjYazKx6DMrjbVYXOfY4
|
||||||
|
# vQuLJRN8qrcU6ffX4NYd+7fYHMuoIjq6Gx4wOkEZmyJw+roVC1nUXEHuEvDjrZqv
|
||||||
|
# w+E5MVeU8IokMw50NMDbL9jRzNXl05o+1IbMLUt9yj6pR+QyBz64jh2VvT8u1im4
|
||||||
|
# P9Dy5Zjy5HSrPPubBvjgHaJv1k2q3lWagQQL3SLzY/G7DHINhNC2uUmI1mnH6OHl
|
||||||
|
# XppahuvB7Hrzi0uqbfM=
|
||||||
|
# SIG # End signature block
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ $(arch) == "aarch64" ]]; then
|
||||||
|
echo "ERROR: not supported on Linux Arm64"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/os-release" ]]; then
|
||||||
|
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
||||||
|
if [[ "${ID}" != "ubuntu" ]]; then
|
||||||
|
echo "ERROR: cannot install on $ID distribution - only Ubuntu is supported"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. make sure to remove old dev if any.
|
||||||
|
if dpkg --get-selections | grep -q "^microsoft-edge-dev[[:space:]]*install$" >/dev/null; then
|
||||||
|
apt-get remove -y microsoft-edge-dev
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Install curl to download Microsoft gpg key
|
||||||
|
if ! command -v curl >/dev/null; then
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Add the GPG key, the apt repo, update the apt cache, and install the package
|
||||||
|
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
|
||||||
|
install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
|
||||||
|
sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge-dev.list'
|
||||||
|
rm /tmp/microsoft.gpg
|
||||||
|
apt-get update && apt-get install -y microsoft-edge-dev
|
||||||
|
|
||||||
|
microsoft-edge-dev --version
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
curl -o ./msedge_dev.pkg -k "$1"
|
||||||
|
# Note: there's no way to uninstall previously installed MSEdge.
|
||||||
|
# However, running PKG again seems to update installation.
|
||||||
|
sudo installer -pkg /tmp/msedge_dev.pkg -target /
|
||||||
|
rm -rf /tmp/msedge_dev.pkg
|
||||||
|
/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev --version
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
$url = $args[0]
|
||||||
|
|
||||||
|
Write-Host "Downloading Microsoft Edge Dev"
|
||||||
|
$wc = New-Object net.webclient
|
||||||
|
$msiInstaller = "$env:temp\microsoft-edge-dev.msi"
|
||||||
|
$wc.Downloadfile($url, $msiInstaller)
|
||||||
|
|
||||||
|
Write-Host "Installing Microsoft Edge Dev"
|
||||||
|
$arguments = "/i `"$msiInstaller`" /quiet"
|
||||||
|
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
||||||
|
Remove-Item $msiInstaller
|
||||||
|
|
||||||
|
$suffix = "\\Microsoft\\Edge Dev\\Application\\msedge.exe"
|
||||||
|
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
||||||
|
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
||||||
|
} else {
|
||||||
|
write-host "ERROR: failed to install Microsoft Edge"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoQwYJKoZIhvcNAQcCoIIoNDCCKDACAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCADMmpfIFdXXhCe
|
||||||
|
# m6Q+NeQN596UnSVzYU7JtWLGiS1zzqCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGiMwghofAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMdvGUm7aF0Zb46hREU/zrq2
|
||||||
|
# u9UKTPE5IivLW0213k/NMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEAsWIOnf0XB2ivtzVyHDuS60arH0nKocF19pv4F9S7NuXPXVKW7sk5DRgh
|
||||||
|
# GIxaQhVjnuv0YV5cbi/PNFkxL42lapOt8H3G50NGjzmZCWAz2C6vQCoAENjr6hHY
|
||||||
|
# BUG7USdPf5WuRVcDN/ZUNJZW9JODZCMMbtf0n+TcXlaE3m/Z62JQrjT9+EEbhQyy
|
||||||
|
# 8YF/orIyQwcUt+9MyJ3irtvEq2BTakmdueJPr7Gh5rREMVSyLxIuVzagm5i/jcA2
|
||||||
|
# GkEJw1LkACZcGKwmOGME65oJ4x1km7Nuc5XxVKVCUhafMteEpEsZC0Quy8oYue8/
|
||||||
|
# VdJMnSnNDQC+DWQJ3VV45F2+r3UbLaGCF60wghepBgorBgEEAYI3AwMBMYIXmTCC
|
||||||
|
# F5UGCSqGSIb3DQEHAqCCF4YwgheCAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCAtUqkU0bk9X1gPuY4qiZrpCjdzz2prbiFW2sMXBLQBgAIGZzvAfUWI
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxMi40NDFaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo0MDFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaCCEfswggcoMIIFEKADAgECAhMzAAAB/tCowns0IQsBAAEAAAH+MA0G
|
||||||
|
# CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||||
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||||
|
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0
|
||||||
|
# MDcyNTE4MzExOFoXDTI1MTAyMjE4MzExOFowgdMxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w
|
||||||
|
# ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjQwMUEt
|
||||||
|
# MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
||||||
|
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLwhFxWlqA43olsE4PCe
|
||||||
|
# gZ4mSfsH2YTSKEYv8Gn3362Bmaycdf5T3tQxpP3NWm62YHUieIQXw+0u4qlay4AN
|
||||||
|
# 3IonI+47Npi9fo52xdAXMX0pGrc0eqW8RWN3bfzXPKv07O18i2HjDyLuywYyKA9F
|
||||||
|
# mWbePjahf9Mwd8QgygkPtwDrVQGLyOkyM3VTiHKqhGu9BCGVRdHW9lmPMrrUlPWi
|
||||||
|
# YV9LVCB5VYd+AEUtdfqAdqlzVxA53EgxSqhp6JbfEKnTdcfP6T8Mir0HrwTTtV2h
|
||||||
|
# 2yDBtjXbQIaqycKOb633GfRkn216LODBg37P/xwhodXT81ZC2aHN7exEDmmbiWss
|
||||||
|
# jGvFJkli2g6dt01eShOiGmhbonr0qXXcBeqNb6QoF8jX/uDVtY9pvL4j8aEWS49h
|
||||||
|
# KUH0mzsCucIrwUS+x8MuT0uf7VXCFNFbiCUNRTofxJ3B454eGJhL0fwUTRbgyCbp
|
||||||
|
# LgKMKDiCRub65DhaeDvUAAJT93KSCoeFCoklPavbgQyahGZDL/vWAVjX5b8Jzhly
|
||||||
|
# 9gGCdK/qi6i+cxZ0S8x6B2yjPbZfdBVfH/NBp/1Ln7xbeOETAOn7OT9D3UGt0q+K
|
||||||
|
# iWgY42HnLjyhl1bAu5HfgryAO3DCaIdV2tjvkJay2qOnF7Dgj8a60KQT9QgfJfwX
|
||||||
|
# nr3ZKibYMjaUbCNIDnxz2ykCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRvznuJ9SU2
|
||||||
|
# g5l/5/b+5CBibbHF3TAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf
|
||||||
|
# BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
|
||||||
|
# L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww
|
||||||
|
# bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m
|
||||||
|
# dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El
|
||||||
|
# MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF
|
||||||
|
# BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAiT4NUvO2lw+0
|
||||||
|
# dDMtsBuxmX2o3lVQqnQkuITAGIGCgI+sl7ZqZOTDd8LqxsH4GWCPTztc3tr8AgBv
|
||||||
|
# sYIzWjFwioCjCQODq1oBMWNzEsKzckHxAzYo5Sze7OPkMA3DAxVq4SSR8y+TRC2G
|
||||||
|
# cOd0JReZ1lPlhlPl9XI+z8OgtOPmQnLLiP9qzpTHwFze+sbqSn8cekduMZdLyHJk
|
||||||
|
# 3Niw3AnglU/WTzGsQAdch9SVV4LHifUnmwTf0i07iKtTlNkq3bx1iyWg7N7jGZAB
|
||||||
|
# RWT2mX+YAVHlK27t9n+WtYbn6cOJNX6LsH8xPVBRYAIRVkWsMyEAdoP9dqfaZzwX
|
||||||
|
# GmjuVQ931NhzHjjG+Efw118DXjk3Vq3qUI1re34zMMTRzZZEw82FupF3viXNR3DV
|
||||||
|
# OlS9JH4x5emfINa1uuSac6F4CeJCD1GakfS7D5ayNsaZ2e+sBUh62KVTlhEsQRHZ
|
||||||
|
# RwCTxbix1Y4iJw+PDNLc0Hf19qX2XiX0u2SM9CWTTjsz9SvCjIKSxCZFCNv/zpKI
|
||||||
|
# lsHx7hQNQHSMbKh0/wwn86uiIALEjazUszE0+X6rcObDfU4h/O/0vmbF3BMR+45r
|
||||||
|
# AZMAETJsRDPxHJCo/5XGhWdg/LoJ5XWBrODL44YNrN7FRnHEAAr06sflqZ8eeV3F
|
||||||
|
# uDKdP5h19WUnGWwO1H/ZjUzOoVGiV3gwggdxMIIFWaADAgECAhMzAAAAFcXna54C
|
||||||
|
# m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
|
||||||
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
||||||
|
# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp
|
||||||
|
# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy
|
||||||
|
# MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
|
||||||
|
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
|
||||||
|
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B
|
||||||
|
# AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51
|
||||||
|
# yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY
|
||||||
|
# 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9
|
||||||
|
# cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN
|
||||||
|
# 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua
|
||||||
|
# Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74
|
||||||
|
# kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2
|
||||||
|
# K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5
|
||||||
|
# TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk
|
||||||
|
# i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q
|
||||||
|
# BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri
|
||||||
|
# Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC
|
||||||
|
# BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl
|
||||||
|
# pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB
|
||||||
|
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y
|
||||||
|
# eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA
|
||||||
|
# YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
|
||||||
|
# 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
|
||||||
|
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw
|
||||||
|
# MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
|
||||||
|
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w
|
||||||
|
# Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp
|
||||||
|
# b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm
|
||||||
|
# ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM
|
||||||
|
# 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW
|
||||||
|
# OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4
|
||||||
|
# FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw
|
||||||
|
# xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX
|
||||||
|
# fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX
|
||||||
|
# VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC
|
||||||
|
# onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU
|
||||||
|
# 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG
|
||||||
|
# ahC0HVUzWLOhcGbyoYIDVjCCAj4CAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
|
||||||
|
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
|
||||||
|
# Tjo0MDFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
||||||
|
# U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAhGNHD/a7Q0bQLWVG9JuGxgLRXseggYMw
|
||||||
|
# gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF
|
||||||
|
# AAIFAOrwIb4wIhgPMjAyNDExMjYxMDMwMjJaGA8yMDI0MTEyNzEwMzAyMlowdDA6
|
||||||
|
# BgorBgEEAYRZCgQBMSwwKjAKAgUA6vAhvgIBADAHAgEAAgIQ8zAHAgEAAgISxTAK
|
||||||
|
# AgUA6vFzPgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB
|
||||||
|
# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQCmpJwvY4rQRcmX
|
||||||
|
# pwCz2YhgwNEN1xpWjqARqD2XKbAtCFcAEeEqjPmFrG2W3c/mxt2uH02nNCeXPF/s
|
||||||
|
# 5i0oC7y4NFL9sfssLAw+Izu1+CVSNrd0Crqe7f6mwY8NOhaj/1vhnF7++Vqu80fH
|
||||||
|
# fjv/yTyefawgNj+A3kiAzppRXs6ZiWNA7GGU6ZZUDbOd/0VwDMRwH17HIkUvdICV
|
||||||
|
# 3u7oyOoAmNeiJUJqLqb8jg89eJYQABJiYUV2lb7JNFGh4o2GvAEiRsFNhTmmfQkP
|
||||||
|
# jSrMxFhZhQmJNnh2McIbblbfuopSh9XT4hYjHUo2bHeW8ebh+aowtSFIylrlyxc6
|
||||||
|
# RAvekpAHMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
|
||||||
|
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
|
||||||
|
# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
|
||||||
|
# MTACEzMAAAH+0KjCezQhCwEAAQAAAf4wDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqG
|
||||||
|
# SIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg798IVqPaeHJn
|
||||||
|
# JfPvb5AQG603llQwUB0pv3yy6L2Y1vowgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHk
|
||||||
|
# MIG9BCARhczd/FPInxjR92m2hPWqc+vGOG1+/I0WtkCstyh0eTCBmDCBgKR+MHwx
|
||||||
|
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
||||||
|
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p
|
||||||
|
# Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB/tCowns0IQsBAAEAAAH+
|
||||||
|
# MCIEIC/jjfBH/gWNuHNfFE4lbtDVmjrj7hQt5hHR2NrQ2ChvMA0GCSqGSIb3DQEB
|
||||||
|
# CwUABIICAApD0Mp01OD08uB2OtQysqkhN0FpWll4BWwymk6Wm08klp5Y5RUplmat
|
||||||
|
# quvraxuNqQYK5TSSNCJVEfy5T+7aOJJYbkWX2LWblS2YjzOoj9MrM1mrZgCfczyU
|
||||||
|
# fuhmNMt7DCcseRcjZB32SRJgMM3Avldp07mzsOUNwDdcXrGvrRSP7KQZhG1ec0Lr
|
||||||
|
# WBGzXjgU+yewy/cXWTRKPJB+kIUvzrt8IpYtdzrwIawdhJZsXdnIghdYd/G7Slsn
|
||||||
|
# WkyBo1FpNOYr2R4S5xhhilR5SGgWcMvv9gbIkEp4fixrliI8TPZbEc9zKWLYvhPP
|
||||||
|
# r1nKVLO2K68H7UUbP5kmFLLLIcaeVC+Fm6eI7HuA5CC7CRWNJFAEmlq0ee4zsVYJ
|
||||||
|
# +XP7a8D0mkmKZFyV1RYxH7bwH9BRXBU7YP+3bIDud3Gwo8WmQB+J6f2FaTEO2GiV
|
||||||
|
# kg1fFHcdRHugVKsUAGa3XKqBenv+AfMhr4prUiHXAwk10TAmjnyAsYY5YvFVe3XP
|
||||||
|
# rfjDGSPH5sawd5gOfE7NHOCCnDDR+DTNrtzi8Xz3e2atqOnACS8+4pdgyMsnVKDi
|
||||||
|
# AcH0L+WJzTLmLMup2t4qKUZVFCXjpQ7gIO38OAK7HscUZh9y05efXQHQYJTQAtPx
|
||||||
|
# 4gI2dpGC9Mnvuox6Cbt1ahBNigu9Wu0VSTBwaAIbrDQN0xKJ3nPL
|
||||||
|
# SIG # End signature block
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ $(arch) == "aarch64" ]]; then
|
||||||
|
echo "ERROR: not supported on Linux Arm64"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/os-release" ]]; then
|
||||||
|
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
||||||
|
if [[ "${ID}" != "ubuntu" ]]; then
|
||||||
|
echo "ERROR: cannot install on $ID distribution - only Ubuntu is supported"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. make sure to remove old stable if any.
|
||||||
|
if dpkg --get-selections | grep -q "^microsoft-edge-stable[[:space:]]*install$" >/dev/null; then
|
||||||
|
apt-get remove -y microsoft-edge-stable
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Install curl to download Microsoft gpg key
|
||||||
|
if ! command -v curl >/dev/null; then
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Add the GPG key, the apt repo, update the apt cache, and install the package
|
||||||
|
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
|
||||||
|
install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
|
||||||
|
sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge-stable.list'
|
||||||
|
rm /tmp/microsoft.gpg
|
||||||
|
apt-get update && apt-get install -y microsoft-edge-stable
|
||||||
|
|
||||||
|
microsoft-edge-stable --version
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
curl -o ./msedge_stable.pkg -k "$1"
|
||||||
|
# Note: there's no way to uninstall previously installed MSEdge.
|
||||||
|
# However, running PKG again seems to update installation.
|
||||||
|
sudo installer -pkg /tmp/msedge_stable.pkg -target /
|
||||||
|
rm -rf /tmp/msedge_stable.pkg
|
||||||
|
/Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge --version
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
$url = $args[0]
|
||||||
|
|
||||||
|
Write-Host "Downloading Microsoft Edge"
|
||||||
|
$wc = New-Object net.webclient
|
||||||
|
$msiInstaller = "$env:temp\microsoft-edge-stable.msi"
|
||||||
|
$wc.Downloadfile($url, $msiInstaller)
|
||||||
|
|
||||||
|
Write-Host "Installing Microsoft Edge"
|
||||||
|
$arguments = "/i `"$msiInstaller`" /quiet"
|
||||||
|
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
||||||
|
Remove-Item $msiInstaller
|
||||||
|
|
||||||
|
$suffix = "\\Microsoft\\Edge\\Application\\msedge.exe"
|
||||||
|
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
||||||
|
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
||||||
|
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
||||||
|
} else {
|
||||||
|
write-host "ERROR: failed to install Microsoft Edge"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
# SIG # Begin signature block
|
||||||
|
# MIIoLQYJKoZIhvcNAQcCoIIoHjCCKBoCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBgZ/Xuousck7h9
|
||||||
|
# nOlw4gMpz5dLhBQDziSEm6zaBMKtxaCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
|
||||||
|
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
|
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
|
||||||
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
|
||||||
|
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
|
||||||
|
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
|
||||||
|
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
|
||||||
|
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
|
||||||
|
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
|
||||||
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
|
||||||
|
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
|
||||||
|
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
|
||||||
|
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
|
||||||
|
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
|
||||||
|
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
|
||||||
|
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
|
||||||
|
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
|
||||||
|
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
|
||||||
|
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
|
||||||
|
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
|
||||||
|
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
|
||||||
|
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
|
||||||
|
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
|
||||||
|
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
|
||||||
|
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
|
||||||
|
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
|
||||||
|
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
|
||||||
|
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||||
|
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||||
|
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||||
|
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
|
||||||
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||||
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
|
||||||
|
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
|
||||||
|
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
|
||||||
|
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
|
||||||
|
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
|
||||||
|
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
|
||||||
|
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
|
||||||
|
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
|
||||||
|
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
|
||||||
|
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
|
||||||
|
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
|
||||||
|
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
|
||||||
|
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
|
||||||
|
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
|
||||||
|
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
|
||||||
|
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
|
||||||
|
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
|
||||||
|
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
||||||
|
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
|
||||||
|
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
|
||||||
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
|
||||||
|
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
|
||||||
|
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
|
||||||
|
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
|
||||||
|
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
|
||||||
|
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
|
||||||
|
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
|
||||||
|
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
|
||||||
|
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
|
||||||
|
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
|
||||||
|
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
|
||||||
|
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
|
||||||
|
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
|
||||||
|
# /Xmfwb1tbWrJUnMTDXpQzTGCGg0wghoJAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
|
||||||
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
||||||
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
|
||||||
|
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
|
||||||
|
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
|
||||||
|
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMn7/PRxf4AocI2amBowFff8
|
||||||
|
# +5szm/JC3Mt6GiaJFDb9MEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
|
||||||
|
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
|
||||||
|
# BQAEggEAjiVUnS+GfeTfJ9U/SmoetYJlnFUy8rpT12IIa9UZLG2sEueqij30b3Sv
|
||||||
|
# l2jatCrFnUmt1ta0/XihJYBC76INAD9MzxH/YDbyMwvnIR+A7zW3+G5qp/+5KkLQ
|
||||||
|
# pWVxyghxhkTJj+giTDKu5o+8894pr2zDb5Cb/kyFLKs6tqtQmHlSgpUhH8rUmJqg
|
||||||
|
# oTdSPd43+RiCfDmYeNMi67lLAu0dkmfeQIpt891/C64f6PAbwgZUTEhrYaXZ+EdS
|
||||||
|
# CGm7ctqxrhgAeXqu2DQ75uY5xURzANqX+xsMxWsCl19MJF+neqSKB27+4bhi0xqr
|
||||||
|
# 9Cf3jaSIXStIcgC7IReqo8WuEwGR86GCF5cwgheTBgorBgEEAYI3AwMBMYIXgzCC
|
||||||
|
# F38GCSqGSIb3DQEHAqCCF3AwghdsAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsq
|
||||||
|
# hkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
|
||||||
|
# AwQCAQUABCChK0FIVu5Ls5SB5K7JV/VQBojp7cGfdU5PcdohQW3XMgIGZz8w626G
|
||||||
|
# GBMyMDI0MTEyNjE4NDUxMy45NDdaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJV
|
||||||
|
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||||
|
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l
|
||||||
|
# cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0w
|
||||||
|
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wg
|
||||||
|
# ghHtMIIHIDCCBQigAwIBAgITMwAAAehQsIDPK3KZTQABAAAB6DANBgkqhkiG9w0B
|
||||||
|
# AQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
||||||
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
|
||||||
|
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yMzEyMDYxODQ1
|
||||||
|
# MjJaFw0yNTAzMDUxODQ1MjJaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
|
||||||
|
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
|
||||||
|
# cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z
|
||||||
|
# MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0wNUUwLUQ5NDcxJTAjBgNV
|
||||||
|
# BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4ICDwAwggIKAoICAQDhQXdE0WzXG7wzeC9SGdH6eVwdGlF6YgpU7weOFBkp
|
||||||
|
# W9yuEmJSDE1ADBx/0DTuRBaplSD8CR1QqyQmxRDD/CdvDyeZFAcZ6l2+nlMssmZy
|
||||||
|
# C8TPt1GTWAUt3GXUU6g0F0tIrFNLgofCjOvm3G0j482VutKS4wZT6bNVnBVsChr2
|
||||||
|
# AjmVbGDN/6Qs/EqakL5cwpGel1te7UO13dUwaPjOy0Wi1qYNmR8i7T1luj2JdFdf
|
||||||
|
# ZhMPyqyq/NDnZuONSbj8FM5xKBoar12ragC8/1CXaL1OMXBwGaRoJTYtksi9njuq
|
||||||
|
# 4wDkcAwitCZ5BtQ2NqPZ0lLiQB7O10Bm9zpHWn9x1/HmdAn4koMWKUDwH5sd/zDu
|
||||||
|
# 4vi887FWxm54kkWNvk8FeQ7ZZ0Q5gqGKW4g6revV2IdAxBobWdorqwvzqL70Wdsg
|
||||||
|
# DU/P5c0L8vYIskUJZedCGHM2hHIsNRyw9EFoSolDM+yCedkz69787s8nIp55icLf
|
||||||
|
# DoKw5hak5G6MWF6d71tcNzV9+v9RQKMa6Uwfyquredd5sqXWCXv++hek4A15WybI
|
||||||
|
# c6ufT0ilazKYZvDvoaswgjP0SeLW7mvmcw0FELzF1/uWaXElLHOXIlieKF2i/YzQ
|
||||||
|
# 6U50K9dbhnMaDcJSsG0hXLRTy/LQbsOD0hw7FuK0nmzotSx/5fo9g7fCzoFjk3tD
|
||||||
|
# EwIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFPo5W8o980kMfRVQba6T34HwelLaMB8G
|
||||||
|
# A1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCG
|
||||||
|
# Tmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy
|
||||||
|
# MFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4w
|
||||||
|
# XAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2Vy
|
||||||
|
# dHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwG
|
||||||
|
# A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQD
|
||||||
|
# AgeAMA0GCSqGSIb3DQEBCwUAA4ICAQCWfcJm2rwXtPi74km6PKAkni9+BWotq+Qt
|
||||||
|
# DGgeT5F3ro7PsIUNKRkUytuGqI8thL3Jcrb03x6DOppYJEA+pb6o2qPjFddO1TLq
|
||||||
|
# vSXrYm+OgCLL+7+3FmRmfkRu8rHvprab0O19wDbukgO8I5Oi1RegMJl8t5k/UtE0
|
||||||
|
# Wb3zAlOHnCjLGSzP/Do3ptwhXokk02IvD7SZEBbPboGbtw4LCHsT2pFakpGOBh+I
|
||||||
|
# SUMXBf835CuVNfddwxmyGvNSzyEyEk5h1Vh7tpwP7z7rJ+HsiP4sdqBjj6Avopuf
|
||||||
|
# 4rxUAfrEbV6aj8twFs7WVHNiIgrHNna/55kyrAG9Yt19CPvkUwxYK0uZvPl2WC39
|
||||||
|
# nfc0jOTjivC7s/IUozE4tfy3JNkyQ1cNtvZftiX3j5Dt+eLOeuGDjvhJvYMIEkpk
|
||||||
|
# V68XLNH7+ZBfYa+PmfRYaoFFHCJKEoRSZ3PbDJPBiEhZ9yuxMddoMMQ19Tkyftot
|
||||||
|
# 6Ez0XhSmwjYBq39DvBFWhlyDGBhrU3GteDWiVd9YGSB2WnxuFMy5fbAK6o8PWz8Q
|
||||||
|
# RMiptXHK3HDBr2wWWEcrrgcTuHZIJTqepNoYlx9VRFvj/vCXaAFcmkW1nk7VE+ow
|
||||||
|
# aXr5RJjryDq9ubkyDq1mdrF/geaRALXcNZbfNXIkhXzXA6a8CiamcQW/DgmLJpiV
|
||||||
|
# QNriZYCHIDCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZI
|
||||||
|
# hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
|
||||||
|
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
||||||
|
# MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy
|
||||||
|
# MDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMC
|
||||||
|
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
||||||
|
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
|
||||||
|
# bWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
||||||
|
# AQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25Phdg
|
||||||
|
# M/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPF
|
||||||
|
# dvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6
|
||||||
|
# GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBp
|
||||||
|
# Dco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50Zu
|
||||||
|
# yjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3E
|
||||||
|
# XzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0
|
||||||
|
# lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1q
|
||||||
|
# GFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ
|
||||||
|
# +QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PA
|
||||||
|
# PBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkw
|
||||||
|
# EgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxG
|
||||||
|
# NSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARV
|
||||||
|
# MFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj
|
||||||
|
# cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAK
|
||||||
|
# BggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
|
||||||
|
# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
|
||||||
|
# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
|
||||||
|
# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
|
||||||
|
# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||||
|
# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG
|
||||||
|
# 9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0x
|
||||||
|
# M7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmC
|
||||||
|
# VgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449
|
||||||
|
# xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wM
|
||||||
|
# nosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDS
|
||||||
|
# PeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2d
|
||||||
|
# Y3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxn
|
||||||
|
# GSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+Crvs
|
||||||
|
# QWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokL
|
||||||
|
# jzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL
|
||||||
|
# 6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNQ
|
||||||
|
# MIICOAIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
|
||||||
|
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
|
||||||
|
# b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn
|
||||||
|
# MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkRDMDAtMDVFMC1EOTQ3MSUwIwYDVQQD
|
||||||
|
# ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQCM
|
||||||
|
# JG4vg0juMOVn2BuKACUvP80FuqCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
|
# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
|
||||||
|
# IFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA6vBGhDAiGA8yMDI0MTEyNjEzMDcx
|
||||||
|
# NloYDzIwMjQxMTI3MTMwNzE2WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDq8EaE
|
||||||
|
# AgEAMAoCAQACAgjSAgH/MAcCAQACAhIsMAoCBQDq8ZgEAgEAMDYGCisGAQQBhFkK
|
||||||
|
# BAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJ
|
||||||
|
# KoZIhvcNAQELBQADggEBAD1C24BCFWdExlh4qmTnrM3Y7Uo1FtVcFMi8mWP3ZhaK
|
||||||
|
# Y+5volZQX+/gUYz67fqXEx12jSc1ODSeNy2IopJUYTNtpyGqqR10js1RH6c7bmhQ
|
||||||
|
# IvRfbrsSEEmpg3qFLFjIHE0Py5y5C3IF+Zo328dXyg3/Qsg5eIt2F5uDqflLdkW4
|
||||||
|
# mT0GpDisefHduysF6H1E1goK00koClsoc1vH6AFKnQ9LrZtez2AAoQcdimXFsXWh
|
||||||
|
# QmSSIHkXJ9Pvw2HEJ+BKMhs+Riozeuc9RQyERP2d2AwtoZTcrZQcbq5AHBJ/J1HF
|
||||||
|
# V7PWVDuGtAsAnGzK/lM800HVWkOsi7GLwUYmyOboqeExggQNMIIECQIBATCBkzB8
|
||||||
|
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
|
||||||
|
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
|
||||||
|
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAehQsIDPK3KZTQABAAAB
|
||||||
|
# 6DANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE
|
||||||
|
# MC8GCSqGSIb3DQEJBDEiBCDCaJbfJiAKuvDzjKc5ZPW+FmsawqKwY+lMQdzd9x5T
|
||||||
|
# 4zCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EICrS2sTVAoQggkHR59pNqige
|
||||||
|
# 0xfJT2J3U8W1Sc8H+OsdMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
||||||
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
||||||
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
||||||
|
# IDIwMTACEzMAAAHoULCAzytymU0AAQAAAegwIgQgA5J8HADqawZlUczSZb5IjYuR
|
||||||
|
# YHNLroHvTTOO/TGY6n8wDQYJKoZIhvcNAQELBQAEggIA0vOrrMehhowgRCbau+GG
|
||||||
|
# zh7xt7kebyQ5vdSYQbHOB7hVyc9pd2J4FO7H2e78GI1tuvJ132WIqm77zxZLl/sw
|
||||||
|
# wtLLnYFIrVwhP+Xm/DDDtgtYgArLKkQSRdE/JrRj/5ZunhzNlyXbdxgbPep/88xm
|
||||||
|
# gVL0/fLjTNRjJd/NgwS1oHtgaTU4u8BRK4DXrhdqnJcIoBCL2GL4bKNQ9cuJIUCC
|
||||||
|
# XY0uwqRrIVNHpF4rSVkRD0k3YC9L7OGHwvqh0U9BY3AQr1DsvTl0eWTp6mDcU6yo
|
||||||
|
# p37tXGXKQZnxk8yy6iArWtt1AXmj8NqoCmZp1go8cVBzeWoQLiqoQ0xi9xIUML5e
|
||||||
|
# OObRc6bple1+Dv31APDNQLhEHHCmEGz01uAqrovDDjngTQ745IsNhPYvHgfRHZ4b
|
||||||
|
# Flkr+Y9V/0MT+Zjkam5KZF9D08NqfF5i4paGwocCXKTW4YN52t9PUR7C69mm0YFB
|
||||||
|
# 43kU3zT2qfuFxwr7j8hBymziNb8o5A2+C+NbgA7rbLP9dQP/+BW+IZPeq2kSzoD8
|
||||||
|
# TY+9gEZLvYYNIIe0tIO0bawMaXOVzFVYy3Qsg1D6KNdXzCg4U+nMYO3Pp9pA6hgl
|
||||||
|
# idpsUITBiJ0ADnExlnaKOZU0MwcvYhRjq0PZaA9Wa3JhI51lXk0FV+ptFBiqT+Mk
|
||||||
|
# RpGfRswbp2MBosXZpF1e1Pg=
|
||||||
|
# SIG # End signature block
|
||||||
58
bin/pac/tools/.playwright/package/browsers.json
Normal file
58
bin/pac/tools/.playwright/package/browsers.json
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"comment": "Do not edit this file, use utils/roll_browser.js",
|
||||||
|
"browsers": [
|
||||||
|
{
|
||||||
|
"name": "chromium",
|
||||||
|
"revision": "1067",
|
||||||
|
"installByDefault": true,
|
||||||
|
"browserVersion": "115.0.5790.24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chromium-with-symbols",
|
||||||
|
"revision": "1067",
|
||||||
|
"installByDefault": false,
|
||||||
|
"browserVersion": "115.0.5790.24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chromium-tip-of-tree",
|
||||||
|
"revision": "1120",
|
||||||
|
"installByDefault": false,
|
||||||
|
"browserVersion": "116.0.5805.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "firefox",
|
||||||
|
"revision": "1408",
|
||||||
|
"installByDefault": true,
|
||||||
|
"browserVersion": "113.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "firefox-beta",
|
||||||
|
"revision": "1410",
|
||||||
|
"installByDefault": false,
|
||||||
|
"browserVersion": "114.0b3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "webkit",
|
||||||
|
"revision": "1860",
|
||||||
|
"installByDefault": true,
|
||||||
|
"revisionOverrides": {
|
||||||
|
"mac10.14": "1446",
|
||||||
|
"mac10.15": "1616",
|
||||||
|
"mac11": "1816",
|
||||||
|
"mac11-arm64": "1816",
|
||||||
|
"ubuntu18.04": "1728"
|
||||||
|
},
|
||||||
|
"browserVersion": "16.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ffmpeg",
|
||||||
|
"revision": "1009",
|
||||||
|
"installByDefault": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "android",
|
||||||
|
"revision": "1000",
|
||||||
|
"installByDefault": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
17
bin/pac/tools/.playwright/package/cli.js
Normal file
17
bin/pac/tools/.playwright/package/cli.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
module.exports = require('playwright-core/lib/cli/cli');
|
||||||
17
bin/pac/tools/.playwright/package/index.d.ts
vendored
Normal file
17
bin/pac/tools/.playwright/package/index.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './types/types';
|
||||||
33
bin/pac/tools/.playwright/package/index.js
Normal file
33
bin/pac/tools/.playwright/package/index.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const currentNodeVersion = process.versions.node;
|
||||||
|
const semver = currentNodeVersion.split('.');
|
||||||
|
const [major] = [+semver[0]];
|
||||||
|
|
||||||
|
if (major < 14) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(
|
||||||
|
'You are running Node.js ' +
|
||||||
|
currentNodeVersion +
|
||||||
|
'.\n' +
|
||||||
|
'Playwright requires Node.js 14 or higher. \n' +
|
||||||
|
'Please update your version of Node.js.'
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = require('./lib/inprocess');
|
||||||
28
bin/pac/tools/.playwright/package/index.mjs
Normal file
28
bin/pac/tools/.playwright/package/index.mjs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import playwright from './index.js';
|
||||||
|
|
||||||
|
export const chromium = playwright.chromium;
|
||||||
|
export const firefox = playwright.firefox;
|
||||||
|
export const webkit = playwright.webkit;
|
||||||
|
export const selectors = playwright.selectors;
|
||||||
|
export const devices = playwright.devices;
|
||||||
|
export const errors = playwright.errors;
|
||||||
|
export const request = playwright.request;
|
||||||
|
export const _electron = playwright._electron;
|
||||||
|
export const _android = playwright._android;
|
||||||
|
export default playwright;
|
||||||
69
bin/pac/tools/.playwright/package/lib/androidServerImpl.js
Normal file
69
bin/pac/tools/.playwright/package/lib/androidServerImpl.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.AndroidServerLauncherImpl = void 0;
|
||||||
|
var _utilsBundle = require("./utilsBundle");
|
||||||
|
var _utils = require("./utils");
|
||||||
|
var _playwright = require("./server/playwright");
|
||||||
|
var _playwrightServer = require("./remote/playwrightServer");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AndroidServerLauncherImpl {
|
||||||
|
async launchServer(options = {}) {
|
||||||
|
const playwright = (0, _playwright.createPlaywright)({
|
||||||
|
sdkLanguage: 'javascript',
|
||||||
|
isServer: true
|
||||||
|
});
|
||||||
|
// 1. Pre-connect to the device
|
||||||
|
let devices = await playwright.android.devices({
|
||||||
|
host: options.adbHost,
|
||||||
|
port: options.adbPort,
|
||||||
|
omitDriverInstall: options.omitDriverInstall
|
||||||
|
});
|
||||||
|
if (devices.length === 0) throw new Error('No devices found');
|
||||||
|
if (options.deviceSerialNumber) {
|
||||||
|
devices = devices.filter(d => d.serial === options.deviceSerialNumber);
|
||||||
|
if (devices.length === 0) throw new Error(`No device with serial number '${options.deviceSerialNumber}' not found`);
|
||||||
|
}
|
||||||
|
if (devices.length > 1) throw new Error(`More than one device found. Please specify deviceSerialNumber`);
|
||||||
|
const device = devices[0];
|
||||||
|
const path = options.wsPath ? options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}` : `/${(0, _utils.createGuid)()}`;
|
||||||
|
|
||||||
|
// 2. Start the server
|
||||||
|
const server = new _playwrightServer.PlaywrightServer({
|
||||||
|
mode: 'launchServer',
|
||||||
|
path,
|
||||||
|
maxConnections: 1,
|
||||||
|
preLaunchedAndroidDevice: device
|
||||||
|
});
|
||||||
|
const wsEndpoint = await server.listen(options.port);
|
||||||
|
|
||||||
|
// 3. Return the BrowserServer interface
|
||||||
|
const browserServer = new _utilsBundle.ws.EventEmitter();
|
||||||
|
browserServer.wsEndpoint = () => wsEndpoint;
|
||||||
|
browserServer.close = () => device.close();
|
||||||
|
browserServer.kill = () => device.close();
|
||||||
|
device.on('close', () => {
|
||||||
|
server.close();
|
||||||
|
browserServer.emit('close');
|
||||||
|
});
|
||||||
|
return browserServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.AndroidServerLauncherImpl = AndroidServerLauncherImpl;
|
||||||
91
bin/pac/tools/.playwright/package/lib/browserServerImpl.js
Normal file
91
bin/pac/tools/.playwright/package/lib/browserServerImpl.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.BrowserServerLauncherImpl = void 0;
|
||||||
|
var _utilsBundle = require("./utilsBundle");
|
||||||
|
var _clientHelper = require("./client/clientHelper");
|
||||||
|
var _utils = require("./utils");
|
||||||
|
var _instrumentation = require("./server/instrumentation");
|
||||||
|
var _playwright = require("./server/playwright");
|
||||||
|
var _playwrightServer = require("./remote/playwrightServer");
|
||||||
|
var _helper = require("./server/helper");
|
||||||
|
var _stackTrace = require("./utils/stackTrace");
|
||||||
|
var _socksProxy = require("./common/socksProxy");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BrowserServerLauncherImpl {
|
||||||
|
constructor(browserName) {
|
||||||
|
this._browserName = void 0;
|
||||||
|
this._browserName = browserName;
|
||||||
|
}
|
||||||
|
async launchServer(options = {}) {
|
||||||
|
const playwright = (0, _playwright.createPlaywright)({
|
||||||
|
sdkLanguage: 'javascript',
|
||||||
|
isServer: true
|
||||||
|
});
|
||||||
|
// TODO: enable socks proxy once ipv6 is supported.
|
||||||
|
const socksProxy = false ? new _socksProxy.SocksProxy() : undefined;
|
||||||
|
playwright.options.socksProxyPort = await (socksProxy === null || socksProxy === void 0 ? void 0 : socksProxy.listen(0));
|
||||||
|
|
||||||
|
// 1. Pre-launch the browser
|
||||||
|
const metadata = (0, _instrumentation.serverSideCallMetadata)();
|
||||||
|
const browser = await playwright[this._browserName].launch(metadata, {
|
||||||
|
...options,
|
||||||
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
|
env: options.env ? (0, _clientHelper.envObjectToArray)(options.env) : undefined
|
||||||
|
}, toProtocolLogger(options.logger)).catch(e => {
|
||||||
|
const log = _helper.helper.formatBrowserLogs(metadata.log);
|
||||||
|
(0, _stackTrace.rewriteErrorMessage)(e, `${e.message} Failed to launch browser.${log}`);
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
const path = options.wsPath ? options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}` : `/${(0, _utils.createGuid)()}`;
|
||||||
|
|
||||||
|
// 2. Start the server
|
||||||
|
const server = new _playwrightServer.PlaywrightServer({
|
||||||
|
mode: 'launchServer',
|
||||||
|
path,
|
||||||
|
maxConnections: Infinity,
|
||||||
|
preLaunchedBrowser: browser,
|
||||||
|
preLaunchedSocksProxy: socksProxy
|
||||||
|
});
|
||||||
|
const wsEndpoint = await server.listen(options.port);
|
||||||
|
|
||||||
|
// 3. Return the BrowserServer interface
|
||||||
|
const browserServer = new _utilsBundle.ws.EventEmitter();
|
||||||
|
browserServer.process = () => browser.options.browserProcess.process;
|
||||||
|
browserServer.wsEndpoint = () => wsEndpoint;
|
||||||
|
browserServer.close = () => browser.options.browserProcess.close();
|
||||||
|
browserServer.kill = () => browser.options.browserProcess.kill();
|
||||||
|
browserServer._disconnectForTest = () => server.close();
|
||||||
|
browserServer._userDataDirForTest = browser._userDataDirForTest;
|
||||||
|
browser.options.browserProcess.onclose = (exitCode, signal) => {
|
||||||
|
socksProxy === null || socksProxy === void 0 ? void 0 : socksProxy.close().catch(() => {});
|
||||||
|
server.close();
|
||||||
|
browserServer.emit('close', exitCode, signal);
|
||||||
|
};
|
||||||
|
return browserServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BrowserServerLauncherImpl = BrowserServerLauncherImpl;
|
||||||
|
function toProtocolLogger(logger) {
|
||||||
|
return logger ? (direction, message) => {
|
||||||
|
if (logger.isEnabled('protocol', 'verbose')) logger.log('protocol', 'verbose', (direction === 'send' ? 'SEND ► ' : '◀ RECV ') + JSON.stringify(message), [], {});
|
||||||
|
} : undefined;
|
||||||
|
}
|
||||||
65
bin/pac/tools/.playwright/package/lib/cli/cli.js
Normal file
65
bin/pac/tools/.playwright/package/lib/cli/cli.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _program = _interopRequireDefault(require("./program"));
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
function printPlaywrightTestError(command) {
|
||||||
|
const packages = [];
|
||||||
|
for (const pkg of ['playwright', 'playwright-chromium', 'playwright-firefox', 'playwright-webkit']) {
|
||||||
|
try {
|
||||||
|
require.resolve(pkg);
|
||||||
|
packages.push(pkg);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
if (!packages.length) packages.push('playwright');
|
||||||
|
const packageManager = (0, _utils.getPackageManager)();
|
||||||
|
if (packageManager === 'yarn') {
|
||||||
|
console.error(`Please install @playwright/test package before running "yarn playwright ${command}"`);
|
||||||
|
console.error(` yarn remove ${packages.join(' ')}`);
|
||||||
|
console.error(' yarn add -D @playwright/test');
|
||||||
|
} else if (packageManager === 'pnpm') {
|
||||||
|
console.error(`Please install @playwright/test package before running "pnpm exec playwright ${command}"`);
|
||||||
|
console.error(` pnpm remove ${packages.join(' ')}`);
|
||||||
|
console.error(' pnpm add -D @playwright/test');
|
||||||
|
} else {
|
||||||
|
console.error(`Please install @playwright/test package before running "npx playwright ${command}"`);
|
||||||
|
console.error(` npm uninstall ${packages.join(' ')}`);
|
||||||
|
console.error(' npm install -D @playwright/test');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const command = _program.default.command('test').allowUnknownOption(true);
|
||||||
|
command.description('Run tests with Playwright Test. Available in @playwright/test package.');
|
||||||
|
command.action(async () => {
|
||||||
|
printPlaywrightTestError('test');
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const command = _program.default.command('show-report').allowUnknownOption(true);
|
||||||
|
command.description('Show Playwright Test HTML report. Available in @playwright/test package.');
|
||||||
|
command.action(async () => {
|
||||||
|
printPlaywrightTestError('show-report');
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_program.default.parse(process.argv);
|
||||||
96
bin/pac/tools/.playwright/package/lib/cli/driver.js
Normal file
96
bin/pac/tools/.playwright/package/lib/cli/driver.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.launchBrowserServer = launchBrowserServer;
|
||||||
|
exports.printApiJson = printApiJson;
|
||||||
|
exports.runDriver = runDriver;
|
||||||
|
exports.runServer = runServer;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var playwright = _interopRequireWildcard(require("../.."));
|
||||||
|
var _server = require("../server");
|
||||||
|
var _transport = require("../protocol/transport");
|
||||||
|
var _playwrightServer = require("../remote/playwrightServer");
|
||||||
|
var _processLauncher = require("../utils/processLauncher");
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
function printApiJson() {
|
||||||
|
// Note: this file is generated by build-playwright-driver.sh
|
||||||
|
console.log(JSON.stringify(require('../../api.json')));
|
||||||
|
}
|
||||||
|
function runDriver() {
|
||||||
|
const dispatcherConnection = new _server.DispatcherConnection();
|
||||||
|
new _server.RootDispatcher(dispatcherConnection, async (rootScope, {
|
||||||
|
sdkLanguage
|
||||||
|
}) => {
|
||||||
|
const playwright = (0, _server.createPlaywright)({
|
||||||
|
sdkLanguage
|
||||||
|
});
|
||||||
|
return new _server.PlaywrightDispatcher(rootScope, playwright);
|
||||||
|
});
|
||||||
|
const transport = new _transport.PipeTransport(process.stdout, process.stdin);
|
||||||
|
transport.onmessage = message => dispatcherConnection.dispatch(JSON.parse(message));
|
||||||
|
dispatcherConnection.onmessage = message => transport.send(JSON.stringify(message));
|
||||||
|
transport.onclose = () => {
|
||||||
|
// Drop any messages during shutdown on the floor.
|
||||||
|
dispatcherConnection.onmessage = () => {};
|
||||||
|
selfDestruct();
|
||||||
|
};
|
||||||
|
// Ignore the SIGINT signal in the driver process so the parent can gracefully close the connection.
|
||||||
|
// We still will destruct everything (close browsers and exit) when the transport pipe closes.
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
// Keep the process running.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function runServer(options) {
|
||||||
|
const {
|
||||||
|
port,
|
||||||
|
path = '/',
|
||||||
|
maxConnections = Infinity,
|
||||||
|
extension
|
||||||
|
} = options;
|
||||||
|
const server = new _playwrightServer.PlaywrightServer({
|
||||||
|
mode: extension ? 'extension' : 'default',
|
||||||
|
path,
|
||||||
|
maxConnections
|
||||||
|
});
|
||||||
|
const wsEndpoint = await server.listen(port);
|
||||||
|
process.on('exit', () => server.close().catch(console.error));
|
||||||
|
console.log('Listening on ' + wsEndpoint); // eslint-disable-line no-console
|
||||||
|
process.stdin.on('close', () => selfDestruct());
|
||||||
|
}
|
||||||
|
async function launchBrowserServer(browserName, configFile) {
|
||||||
|
let options = {};
|
||||||
|
if (configFile) options = JSON.parse(_fs.default.readFileSync(configFile).toString());
|
||||||
|
const browserType = playwright[browserName];
|
||||||
|
const server = await browserType.launchServer(options);
|
||||||
|
console.log(server.wsEndpoint());
|
||||||
|
}
|
||||||
|
function selfDestruct() {
|
||||||
|
// Force exit after 30 seconds.
|
||||||
|
setTimeout(() => process.exit(0), 30000);
|
||||||
|
// Meanwhile, try to gracefully close all browsers.
|
||||||
|
(0, _processLauncher.gracefullyCloseAll)().then(() => {
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
575
bin/pac/tools/.playwright/package/lib/cli/program.js
Normal file
575
bin/pac/tools/.playwright/package/lib/cli/program.js
Normal file
@@ -0,0 +1,575 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.default = void 0;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _os = _interopRequireDefault(require("os"));
|
||||||
|
var _path = _interopRequireDefault(require("path"));
|
||||||
|
var _utilsBundle = require("../utilsBundle");
|
||||||
|
var _driver = require("./driver");
|
||||||
|
var _traceViewer = require("../server/trace/viewer/traceViewer");
|
||||||
|
var playwright = _interopRequireWildcard(require("../.."));
|
||||||
|
var _child_process = require("child_process");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _server = require("../server");
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
const packageJSON = require('../../package.json');
|
||||||
|
_utilsBundle.program.version('Version ' + (process.env.PW_CLI_DISPLAY_VERSION || packageJSON.version)).name(buildBasePlaywrightCLICommand(process.env.PW_LANG_NAME));
|
||||||
|
_utilsBundle.program.command('mark-docker-image [dockerImageNameTemplate]', {
|
||||||
|
hidden: true
|
||||||
|
}).description('mark docker image').allowUnknownOption(true).action(function (dockerImageNameTemplate) {
|
||||||
|
(0, _utils.assert)(dockerImageNameTemplate, 'dockerImageNameTemplate is required');
|
||||||
|
(0, _server.writeDockerVersion)(dockerImageNameTemplate).catch(logErrorAndExit);
|
||||||
|
});
|
||||||
|
commandWithOpenOptions('open [url]', 'open page in browser specified via -b, --browser', []).action(function (url, options) {
|
||||||
|
open(options, url, codegenId()).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ open
|
||||||
|
$ open -b webkit https://example.com`);
|
||||||
|
commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions', [['-o, --output <file name>', 'saves the generated script to a file'], ['--target <language>', `language to generate, one of javascript, playwright-test, python, python-async, python-pytest, csharp, csharp-mstest, csharp-nunit, java`, codegenId()], ['--save-trace <filename>', 'record a trace for the session and save it to a file'], ['--test-id-attribute <attributeName>', 'use the specified attribute to generate data test ID selectors']]).action(function (url, options) {
|
||||||
|
codegen(options, url).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ codegen
|
||||||
|
$ codegen --target=python
|
||||||
|
$ codegen -b webkit https://example.com`);
|
||||||
|
_utilsBundle.program.command('debug <app> [args...]', {
|
||||||
|
hidden: true
|
||||||
|
}).description('run command in debug mode: disable timeout, open inspector').allowUnknownOption(true).action(function (app, options) {
|
||||||
|
(0, _child_process.spawn)(app, options, {
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
PWDEBUG: '1'
|
||||||
|
},
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ debug node test.js
|
||||||
|
$ debug npm run test`);
|
||||||
|
function suggestedBrowsersToInstall() {
|
||||||
|
return _server.registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');
|
||||||
|
}
|
||||||
|
function checkBrowsersToInstall(args) {
|
||||||
|
const faultyArguments = [];
|
||||||
|
const executables = [];
|
||||||
|
for (const arg of args) {
|
||||||
|
const executable = _server.registry.findExecutable(arg);
|
||||||
|
if (!executable || executable.installType === 'none') faultyArguments.push(arg);else executables.push(executable);
|
||||||
|
}
|
||||||
|
if (faultyArguments.length) {
|
||||||
|
console.log(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return executables;
|
||||||
|
}
|
||||||
|
_utilsBundle.program.command('install [browser...]').description('ensure browsers necessary for this version of Playwright are installed').option('--with-deps', 'install system dependencies for browsers').option('--dry-run', 'do not execute installation, only print information').option('--force', 'force reinstall of stable browser channels').action(async function (args, options) {
|
||||||
|
if ((0, _utils.isLikelyNpxGlobal)()) {
|
||||||
|
console.error((0, _utils.wrapInASCIIBox)([`WARNING: It looks like you are running 'npx playwright install' without first`, `installing your project's dependencies.`, ``, `To avoid unexpected behavior, please install your dependencies first, and`, `then run Playwright's install command:`, ``, ` npm install`, ` npx playwright install`, ``, `If your project does not yet depend on Playwright, first install the`, `applicable npm package (most commonly @playwright/test), and`, `then run Playwright's install command to download the browsers:`, ``, ` npm install @playwright/test`, ` npx playwright install`, ``].join('\n'), 1));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const hasNoArguments = !args.length;
|
||||||
|
const executables = hasNoArguments ? _server.registry.defaultExecutables() : checkBrowsersToInstall(args);
|
||||||
|
if (options.withDeps) await _server.registry.installDeps(executables, !!options.dryRun);
|
||||||
|
if (options.dryRun) {
|
||||||
|
for (const executable of executables) {
|
||||||
|
var _executable$directory, _executable$downloadU;
|
||||||
|
const version = executable.browserVersion ? `version ` + executable.browserVersion : '';
|
||||||
|
console.log(`browser: ${executable.name}${version ? ' ' + version : ''}`);
|
||||||
|
console.log(` Install location: ${(_executable$directory = executable.directory) !== null && _executable$directory !== void 0 ? _executable$directory : '<system>'}`);
|
||||||
|
if ((_executable$downloadU = executable.downloadURLs) !== null && _executable$downloadU !== void 0 && _executable$downloadU.length) {
|
||||||
|
const [url, ...fallbacks] = executable.downloadURLs;
|
||||||
|
console.log(` Download url: ${url}`);
|
||||||
|
for (let i = 0; i < fallbacks.length; ++i) console.log(` Download fallback ${i + 1}: ${fallbacks[i]}`);
|
||||||
|
}
|
||||||
|
console.log(``);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const forceReinstall = hasNoArguments ? false : !!options.force;
|
||||||
|
await _server.registry.install(executables, forceReinstall);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`Failed to install browsers\n${e}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- $ install
|
||||||
|
Install default browsers.
|
||||||
|
|
||||||
|
- $ install chrome firefox
|
||||||
|
Install custom browsers, supports ${suggestedBrowsersToInstall()}.`);
|
||||||
|
_utilsBundle.program.command('uninstall').description('Removes browsers used by this installation of Playwright from the system (chromium, firefox, webkit, ffmpeg). This does not include branded channels.').option('--all', 'Removes all browsers used by any Playwright installation from the system.').action(async options => {
|
||||||
|
await _server.registry.uninstall(!!options.all).then(({
|
||||||
|
numberOfBrowsersLeft
|
||||||
|
}) => {
|
||||||
|
if (!options.all && numberOfBrowsersLeft > 0) {
|
||||||
|
console.log('Successfully uninstalled Playwright browsers for the current Playwright installation.');
|
||||||
|
console.log(`There are still ${numberOfBrowsersLeft} browsers left, used by other Playwright installations.\nTo uninstall Playwright browsers for all installations, re-run with --all flag.`);
|
||||||
|
}
|
||||||
|
}).catch(logErrorAndExit);
|
||||||
|
});
|
||||||
|
_utilsBundle.program.command('install-deps [browser...]').description('install dependencies necessary to run browsers (will ask for sudo permissions)').option('--dry-run', 'Do not execute installation commands, only print them').action(async function (args, options) {
|
||||||
|
try {
|
||||||
|
if (!args.length) await _server.registry.installDeps(_server.registry.defaultExecutables(), !!options.dryRun);else await _server.registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`Failed to install browser dependencies\n${e}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
- $ install-deps
|
||||||
|
Install dependencies for default browsers.
|
||||||
|
|
||||||
|
- $ install-deps chrome firefox
|
||||||
|
Install dependencies for specific browsers, supports ${suggestedBrowsersToInstall()}.`);
|
||||||
|
const browsers = [{
|
||||||
|
alias: 'cr',
|
||||||
|
name: 'Chromium',
|
||||||
|
type: 'chromium'
|
||||||
|
}, {
|
||||||
|
alias: 'ff',
|
||||||
|
name: 'Firefox',
|
||||||
|
type: 'firefox'
|
||||||
|
}, {
|
||||||
|
alias: 'wk',
|
||||||
|
name: 'WebKit',
|
||||||
|
type: 'webkit'
|
||||||
|
}];
|
||||||
|
for (const {
|
||||||
|
alias,
|
||||||
|
name,
|
||||||
|
type
|
||||||
|
} of browsers) {
|
||||||
|
commandWithOpenOptions(`${alias} [url]`, `open page in ${name}`, []).action(function (url, options) {
|
||||||
|
open({
|
||||||
|
...options,
|
||||||
|
browser: type
|
||||||
|
}, url, options.target).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ ${alias} https://example.com`);
|
||||||
|
}
|
||||||
|
commandWithOpenOptions('screenshot <url> <filename>', 'capture a page screenshot', [['--wait-for-selector <selector>', 'wait for selector before taking a screenshot'], ['--wait-for-timeout <timeout>', 'wait for timeout in milliseconds before taking a screenshot'], ['--full-page', 'whether to take a full page screenshot (entire scrollable area)']]).action(function (url, filename, command) {
|
||||||
|
screenshot(command, command, url, filename).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ screenshot -b webkit https://example.com example.png`);
|
||||||
|
commandWithOpenOptions('pdf <url> <filename>', 'save page as pdf', [['--wait-for-selector <selector>', 'wait for given selector before saving as pdf'], ['--wait-for-timeout <timeout>', 'wait for given timeout in milliseconds before saving as pdf']]).action(function (url, filename, options) {
|
||||||
|
pdf(options, options, url, filename).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ pdf https://example.com example.pdf`);
|
||||||
|
_utilsBundle.program.command('run-driver', {
|
||||||
|
hidden: true
|
||||||
|
}).action(function (options) {
|
||||||
|
(0, _driver.runDriver)();
|
||||||
|
});
|
||||||
|
_utilsBundle.program.command('run-server', {
|
||||||
|
hidden: true
|
||||||
|
}).option('--port <port>', 'Server port').option('--path <path>', 'Endpoint Path', '/').option('--max-clients <maxClients>', 'Maximum clients').option('--mode <mode>', 'Server mode, either "default" or "extension"').action(function (options) {
|
||||||
|
(0, _driver.runServer)({
|
||||||
|
port: options.port ? +options.port : undefined,
|
||||||
|
path: options.path,
|
||||||
|
maxConnections: options.maxClients ? +options.maxClients : Infinity,
|
||||||
|
extension: options.mode === 'extension' || !!process.env.PW_EXTENSION_MODE
|
||||||
|
}).catch(logErrorAndExit);
|
||||||
|
});
|
||||||
|
_utilsBundle.program.command('print-api-json', {
|
||||||
|
hidden: true
|
||||||
|
}).action(function (options) {
|
||||||
|
(0, _driver.printApiJson)();
|
||||||
|
});
|
||||||
|
_utilsBundle.program.command('launch-server', {
|
||||||
|
hidden: true
|
||||||
|
}).requiredOption('--browser <browserName>', 'Browser name, one of "chromium", "firefox" or "webkit"').option('--config <path-to-config-file>', 'JSON file with launchServer options').action(function (options) {
|
||||||
|
(0, _driver.launchBrowserServer)(options.browser, options.config);
|
||||||
|
});
|
||||||
|
_utilsBundle.program.command('show-trace [trace...]').option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').option('-h, --host <host>', 'Host to serve trace on; specifying this option opens trace in a browser tab').option('-p, --port <port>', 'Port to serve trace on, 0 for any free port; specifying this option opens trace in a browser tab').option('--stdin', 'Accept trace URLs over stdin to update the viewer').description('show trace viewer').action(function (traces, options) {
|
||||||
|
if (options.browser === 'cr') options.browser = 'chromium';
|
||||||
|
if (options.browser === 'ff') options.browser = 'firefox';
|
||||||
|
if (options.browser === 'wk') options.browser = 'webkit';
|
||||||
|
const openOptions = {
|
||||||
|
headless: false,
|
||||||
|
host: options.host,
|
||||||
|
port: +options.port,
|
||||||
|
isServer: !!options.stdin,
|
||||||
|
openInBrowser: options.port !== undefined || options.host !== undefined
|
||||||
|
};
|
||||||
|
(0, _traceViewer.showTraceViewer)(traces, options.browser, openOptions).catch(logErrorAndExit);
|
||||||
|
}).addHelpText('afterAll', `
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
$ show-trace https://example.com/trace.zip`);
|
||||||
|
async function launchContext(options, headless, executablePath) {
|
||||||
|
validateOptions(options);
|
||||||
|
const browserType = lookupBrowserType(options);
|
||||||
|
const launchOptions = {
|
||||||
|
headless,
|
||||||
|
executablePath
|
||||||
|
};
|
||||||
|
if (options.channel) launchOptions.channel = options.channel;
|
||||||
|
launchOptions.handleSIGINT = false;
|
||||||
|
const contextOptions =
|
||||||
|
// Copy the device descriptor since we have to compare and modify the options.
|
||||||
|
options.device ? {
|
||||||
|
...playwright.devices[options.device]
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
// In headful mode, use host device scale factor for things to look nice.
|
||||||
|
// In headless, keep things the way it works in Playwright by default.
|
||||||
|
// Assume high-dpi on MacOS. TODO: this is not perfect.
|
||||||
|
if (!headless) contextOptions.deviceScaleFactor = _os.default.platform() === 'darwin' ? 2 : 1;
|
||||||
|
|
||||||
|
// Work around the WebKit GTK scrolling issue.
|
||||||
|
if (browserType.name() === 'webkit' && process.platform === 'linux') {
|
||||||
|
delete contextOptions.hasTouch;
|
||||||
|
delete contextOptions.isMobile;
|
||||||
|
}
|
||||||
|
if (contextOptions.isMobile && browserType.name() === 'firefox') contextOptions.isMobile = undefined;
|
||||||
|
if (options.blockServiceWorkers) contextOptions.serviceWorkers = 'block';
|
||||||
|
|
||||||
|
// Proxy
|
||||||
|
|
||||||
|
if (options.proxyServer) {
|
||||||
|
launchOptions.proxy = {
|
||||||
|
server: options.proxyServer
|
||||||
|
};
|
||||||
|
if (options.proxyBypass) launchOptions.proxy.bypass = options.proxyBypass;
|
||||||
|
}
|
||||||
|
const browser = await browserType.launch(launchOptions);
|
||||||
|
if (process.env.PWTEST_CLI_IS_UNDER_TEST) {
|
||||||
|
process._didSetSourcesForTest = text => {
|
||||||
|
process.stdout.write('\n-------------8<-------------\n');
|
||||||
|
process.stdout.write(text);
|
||||||
|
process.stdout.write('\n-------------8<-------------\n');
|
||||||
|
const autoExitCondition = process.env.PWTEST_CLI_AUTO_EXIT_WHEN;
|
||||||
|
if (autoExitCondition && text.includes(autoExitCondition)) Promise.all(context.pages().map(async p => p.close()));
|
||||||
|
};
|
||||||
|
// Make sure we exit abnormally when browser crashes.
|
||||||
|
const logs = [];
|
||||||
|
require('playwright-core/lib/utilsBundle').debug.log = (...args) => {
|
||||||
|
const line = require('util').format(...args) + '\n';
|
||||||
|
logs.push(line);
|
||||||
|
process.stderr.write(line);
|
||||||
|
};
|
||||||
|
browser.on('disconnected', () => {
|
||||||
|
const hasCrashLine = logs.some(line => line.includes('process did exit:') && !line.includes('process did exit: exitCode=0, signal=null'));
|
||||||
|
if (hasCrashLine) {
|
||||||
|
process.stderr.write('Detected browser crash.\n');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Viewport size
|
||||||
|
if (options.viewportSize) {
|
||||||
|
try {
|
||||||
|
const [width, height] = options.viewportSize.split(',').map(n => parseInt(n, 10));
|
||||||
|
contextOptions.viewport = {
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Invalid window size format: use "width, height", for example --window-size=800,600');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geolocation
|
||||||
|
|
||||||
|
if (options.geolocation) {
|
||||||
|
try {
|
||||||
|
const [latitude, longitude] = options.geolocation.split(',').map(n => parseFloat(n.trim()));
|
||||||
|
contextOptions.geolocation = {
|
||||||
|
latitude,
|
||||||
|
longitude
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Invalid geolocation format: user lat, long, for example --geolocation="37.819722,-122.478611"');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
contextOptions.permissions = ['geolocation'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// User agent
|
||||||
|
|
||||||
|
if (options.userAgent) contextOptions.userAgent = options.userAgent;
|
||||||
|
|
||||||
|
// Lang
|
||||||
|
|
||||||
|
if (options.lang) contextOptions.locale = options.lang;
|
||||||
|
|
||||||
|
// Color scheme
|
||||||
|
|
||||||
|
if (options.colorScheme) contextOptions.colorScheme = options.colorScheme;
|
||||||
|
|
||||||
|
// Timezone
|
||||||
|
|
||||||
|
if (options.timezone) contextOptions.timezoneId = options.timezone;
|
||||||
|
|
||||||
|
// Storage
|
||||||
|
|
||||||
|
if (options.loadStorage) contextOptions.storageState = options.loadStorage;
|
||||||
|
if (options.ignoreHttpsErrors) contextOptions.ignoreHTTPSErrors = true;
|
||||||
|
|
||||||
|
// HAR
|
||||||
|
|
||||||
|
if (options.saveHar) {
|
||||||
|
contextOptions.recordHar = {
|
||||||
|
path: _path.default.resolve(process.cwd(), options.saveHar),
|
||||||
|
mode: 'minimal'
|
||||||
|
};
|
||||||
|
if (options.saveHarGlob) contextOptions.recordHar.urlFilter = options.saveHarGlob;
|
||||||
|
contextOptions.serviceWorkers = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close app when the last window closes.
|
||||||
|
|
||||||
|
const context = await browser.newContext(contextOptions);
|
||||||
|
let closingBrowser = false;
|
||||||
|
async function closeBrowser() {
|
||||||
|
// We can come here multiple times. For example, saving storage creates
|
||||||
|
// a temporary page and we call closeBrowser again when that page closes.
|
||||||
|
if (closingBrowser) return;
|
||||||
|
closingBrowser = true;
|
||||||
|
if (options.saveTrace) await context.tracing.stop({
|
||||||
|
path: options.saveTrace
|
||||||
|
});
|
||||||
|
if (options.saveStorage) await context.storageState({
|
||||||
|
path: options.saveStorage
|
||||||
|
}).catch(e => null);
|
||||||
|
if (options.saveHar) await context.close();
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
context.on('page', page => {
|
||||||
|
page.on('dialog', () => {}); // Prevent dialogs from being automatically dismissed.
|
||||||
|
page.on('close', () => {
|
||||||
|
const hasPage = browser.contexts().some(context => context.pages().length > 0);
|
||||||
|
if (hasPage) return;
|
||||||
|
// Avoid the error when the last page is closed because the browser has been closed.
|
||||||
|
closeBrowser().catch(e => null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
process.on('SIGINT', async () => {
|
||||||
|
await closeBrowser();
|
||||||
|
process.exit(130);
|
||||||
|
});
|
||||||
|
const timeout = options.timeout ? parseInt(options.timeout, 10) : 0;
|
||||||
|
context.setDefaultTimeout(timeout);
|
||||||
|
context.setDefaultNavigationTimeout(timeout);
|
||||||
|
if (options.saveTrace) await context.tracing.start({
|
||||||
|
screenshots: true,
|
||||||
|
snapshots: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Omit options that we add automatically for presentation purpose.
|
||||||
|
delete launchOptions.headless;
|
||||||
|
delete launchOptions.executablePath;
|
||||||
|
delete launchOptions.handleSIGINT;
|
||||||
|
delete contextOptions.deviceScaleFactor;
|
||||||
|
return {
|
||||||
|
browser,
|
||||||
|
browserName: browserType.name(),
|
||||||
|
context,
|
||||||
|
contextOptions,
|
||||||
|
launchOptions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function openPage(context, url) {
|
||||||
|
const page = await context.newPage();
|
||||||
|
if (url) {
|
||||||
|
if (_fs.default.existsSync(url)) url = 'file://' + _path.default.resolve(url);else if (!url.startsWith('http') && !url.startsWith('file://') && !url.startsWith('about:') && !url.startsWith('data:')) url = 'http://' + url;
|
||||||
|
await page.goto(url).catch(error => {
|
||||||
|
if (process.env.PWTEST_CLI_AUTO_EXIT_WHEN && error.message.includes('Navigation failed because page was closed')) {
|
||||||
|
// Tests with PWTEST_CLI_AUTO_EXIT_WHEN might close page too fast, resulting
|
||||||
|
// in a stray navigation aborted error. We should ignore it.
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
async function open(options, url, language) {
|
||||||
|
const {
|
||||||
|
context,
|
||||||
|
launchOptions,
|
||||||
|
contextOptions
|
||||||
|
} = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);
|
||||||
|
await context._enableRecorder({
|
||||||
|
language,
|
||||||
|
launchOptions,
|
||||||
|
contextOptions,
|
||||||
|
device: options.device,
|
||||||
|
saveStorage: options.saveStorage
|
||||||
|
});
|
||||||
|
await openPage(context, url);
|
||||||
|
}
|
||||||
|
async function codegen(options, url) {
|
||||||
|
const {
|
||||||
|
target: language,
|
||||||
|
output: outputFile,
|
||||||
|
testIdAttribute: testIdAttributeName
|
||||||
|
} = options;
|
||||||
|
const {
|
||||||
|
context,
|
||||||
|
launchOptions,
|
||||||
|
contextOptions
|
||||||
|
} = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);
|
||||||
|
await context._enableRecorder({
|
||||||
|
language,
|
||||||
|
launchOptions,
|
||||||
|
contextOptions,
|
||||||
|
device: options.device,
|
||||||
|
saveStorage: options.saveStorage,
|
||||||
|
mode: 'recording',
|
||||||
|
testIdAttributeName,
|
||||||
|
outputFile: outputFile ? _path.default.resolve(outputFile) : undefined,
|
||||||
|
handleSIGINT: false
|
||||||
|
});
|
||||||
|
await openPage(context, url);
|
||||||
|
}
|
||||||
|
async function waitForPage(page, captureOptions) {
|
||||||
|
if (captureOptions.waitForSelector) {
|
||||||
|
console.log(`Waiting for selector ${captureOptions.waitForSelector}...`);
|
||||||
|
await page.waitForSelector(captureOptions.waitForSelector);
|
||||||
|
}
|
||||||
|
if (captureOptions.waitForTimeout) {
|
||||||
|
console.log(`Waiting for timeout ${captureOptions.waitForTimeout}...`);
|
||||||
|
await page.waitForTimeout(parseInt(captureOptions.waitForTimeout, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function screenshot(options, captureOptions, url, path) {
|
||||||
|
const {
|
||||||
|
context
|
||||||
|
} = await launchContext(options, true);
|
||||||
|
console.log('Navigating to ' + url);
|
||||||
|
const page = await openPage(context, url);
|
||||||
|
await waitForPage(page, captureOptions);
|
||||||
|
console.log('Capturing screenshot into ' + path);
|
||||||
|
await page.screenshot({
|
||||||
|
path,
|
||||||
|
fullPage: !!captureOptions.fullPage
|
||||||
|
});
|
||||||
|
// launchContext takes care of closing the browser.
|
||||||
|
await page.close();
|
||||||
|
}
|
||||||
|
async function pdf(options, captureOptions, url, path) {
|
||||||
|
if (options.browser !== 'chromium') {
|
||||||
|
console.error('PDF creation is only working with Chromium');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
context
|
||||||
|
} = await launchContext({
|
||||||
|
...options,
|
||||||
|
browser: 'chromium'
|
||||||
|
}, true);
|
||||||
|
console.log('Navigating to ' + url);
|
||||||
|
const page = await openPage(context, url);
|
||||||
|
await waitForPage(page, captureOptions);
|
||||||
|
console.log('Saving as pdf into ' + path);
|
||||||
|
await page.pdf({
|
||||||
|
path
|
||||||
|
});
|
||||||
|
// launchContext takes care of closing the browser.
|
||||||
|
await page.close();
|
||||||
|
}
|
||||||
|
function lookupBrowserType(options) {
|
||||||
|
let name = options.browser;
|
||||||
|
if (options.device) {
|
||||||
|
const device = playwright.devices[options.device];
|
||||||
|
name = device.defaultBrowserType;
|
||||||
|
}
|
||||||
|
let browserType;
|
||||||
|
switch (name) {
|
||||||
|
case 'chromium':
|
||||||
|
browserType = playwright.chromium;
|
||||||
|
break;
|
||||||
|
case 'webkit':
|
||||||
|
browserType = playwright.webkit;
|
||||||
|
break;
|
||||||
|
case 'firefox':
|
||||||
|
browserType = playwright.firefox;
|
||||||
|
break;
|
||||||
|
case 'cr':
|
||||||
|
browserType = playwright.chromium;
|
||||||
|
break;
|
||||||
|
case 'wk':
|
||||||
|
browserType = playwright.webkit;
|
||||||
|
break;
|
||||||
|
case 'ff':
|
||||||
|
browserType = playwright.firefox;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (browserType) return browserType;
|
||||||
|
_utilsBundle.program.help();
|
||||||
|
}
|
||||||
|
function validateOptions(options) {
|
||||||
|
if (options.device && !(options.device in playwright.devices)) {
|
||||||
|
console.log(`Device descriptor not found: '${options.device}', available devices are:`);
|
||||||
|
for (const name in playwright.devices) console.log(` "${name}"`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
if (options.colorScheme && !['light', 'dark'].includes(options.colorScheme)) {
|
||||||
|
console.log('Invalid color scheme, should be one of "light", "dark"');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function logErrorAndExit(e) {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
function codegenId() {
|
||||||
|
return process.env.PW_LANG_NAME || 'playwright-test';
|
||||||
|
}
|
||||||
|
function commandWithOpenOptions(command, description, options) {
|
||||||
|
let result = _utilsBundle.program.command(command).description(description);
|
||||||
|
for (const option of options) result = result.option(option[0], ...option.slice(1));
|
||||||
|
return result.option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').option('--block-service-workers', 'block service workers').option('--channel <channel>', 'Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc').option('--color-scheme <scheme>', 'emulate preferred color scheme, "light" or "dark"').option('--device <deviceName>', 'emulate device, for example "iPhone 11"').option('--geolocation <coordinates>', 'specify geolocation coordinates, for example "37.819722,-122.478611"').option('--ignore-https-errors', 'ignore https errors').option('--load-storage <filename>', 'load context storage state from the file, previously saved with --save-storage').option('--lang <language>', 'specify language / locale, for example "en-GB"').option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"').option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"').option('--save-har <filename>', 'save HAR file with all network activity at the end').option('--save-har-glob <glob pattern>', 'filter entries in the HAR by matching url against this glob pattern').option('--save-storage <filename>', 'save context storage state at the end, for later use with --load-storage').option('--timezone <time zone>', 'time zone to emulate, for example "Europe/Rome"').option('--timeout <timeout>', 'timeout for Playwright actions in milliseconds, no timeout by default').option('--user-agent <ua string>', 'specify user agent string').option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"');
|
||||||
|
}
|
||||||
|
function buildBasePlaywrightCLICommand(cliTargetLang) {
|
||||||
|
switch (cliTargetLang) {
|
||||||
|
case 'python':
|
||||||
|
return `playwright`;
|
||||||
|
case 'java':
|
||||||
|
return `mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="...options.."`;
|
||||||
|
case 'csharp':
|
||||||
|
return `pwsh bin/Debug/netX/playwright.ps1`;
|
||||||
|
default:
|
||||||
|
return `npx playwright`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var _default = _utilsBundle.program;
|
||||||
|
exports.default = _default;
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Accessibility = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function axNodeFromProtocol(axNode) {
|
||||||
|
const result = {
|
||||||
|
...axNode,
|
||||||
|
value: axNode.valueNumber !== undefined ? axNode.valueNumber : axNode.valueString,
|
||||||
|
checked: axNode.checked === 'checked' ? true : axNode.checked === 'unchecked' ? false : axNode.checked,
|
||||||
|
pressed: axNode.pressed === 'pressed' ? true : axNode.pressed === 'released' ? false : axNode.pressed,
|
||||||
|
children: axNode.children ? axNode.children.map(axNodeFromProtocol) : undefined
|
||||||
|
};
|
||||||
|
delete result.valueNumber;
|
||||||
|
delete result.valueString;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
class Accessibility {
|
||||||
|
constructor(channel) {
|
||||||
|
this._channel = void 0;
|
||||||
|
this._channel = channel;
|
||||||
|
}
|
||||||
|
async snapshot(options = {}) {
|
||||||
|
const root = options.root ? options.root._elementChannel : undefined;
|
||||||
|
const result = await this._channel.accessibilitySnapshot({
|
||||||
|
interestingOnly: options.interestingOnly,
|
||||||
|
root
|
||||||
|
});
|
||||||
|
return result.rootAXNode ? axNodeFromProtocol(result.rootAXNode) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Accessibility = Accessibility;
|
||||||
466
bin/pac/tools/.playwright/package/lib/client/android.js
Normal file
466
bin/pac/tools/.playwright/package/lib/client/android.js
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.AndroidWebView = exports.AndroidSocket = exports.AndroidInput = exports.AndroidDevice = exports.Android = void 0;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _timeoutSettings = require("../common/timeoutSettings");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
var _events2 = require("events");
|
||||||
|
var _connection = require("./connection");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _timeoutRunner = require("../utils/timeoutRunner");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Android extends _channelOwner.ChannelOwner {
|
||||||
|
static from(android) {
|
||||||
|
return android._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._timeoutSettings = void 0;
|
||||||
|
this._serverLauncher = void 0;
|
||||||
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings();
|
||||||
|
}
|
||||||
|
setDefaultTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
|
this._channel.setDefaultTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async devices(options = {}) {
|
||||||
|
const {
|
||||||
|
devices
|
||||||
|
} = await this._channel.devices(options);
|
||||||
|
return devices.map(d => AndroidDevice.from(d));
|
||||||
|
}
|
||||||
|
async launchServer(options = {}) {
|
||||||
|
if (!this._serverLauncher) throw new Error('Launching server is not supported');
|
||||||
|
return this._serverLauncher.launchServer(options);
|
||||||
|
}
|
||||||
|
async connect(wsEndpoint, options = {}) {
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const deadline = options.timeout ? (0, _utils.monotonicTime)() + options.timeout : 0;
|
||||||
|
const headers = {
|
||||||
|
'x-playwright-browser': 'android',
|
||||||
|
...options.headers
|
||||||
|
};
|
||||||
|
const localUtils = this._connection.localUtils();
|
||||||
|
const connectParams = {
|
||||||
|
wsEndpoint,
|
||||||
|
headers,
|
||||||
|
slowMo: options.slowMo,
|
||||||
|
timeout: options.timeout
|
||||||
|
};
|
||||||
|
const {
|
||||||
|
pipe
|
||||||
|
} = await localUtils._channel.connect(connectParams);
|
||||||
|
const closePipe = () => pipe.close().catch(() => {});
|
||||||
|
const connection = new _connection.Connection(localUtils, this._instrumentation);
|
||||||
|
connection.markAsRemote();
|
||||||
|
connection.on('close', closePipe);
|
||||||
|
let device;
|
||||||
|
let closeError;
|
||||||
|
const onPipeClosed = () => {
|
||||||
|
var _device;
|
||||||
|
(_device = device) === null || _device === void 0 ? void 0 : _device._didClose();
|
||||||
|
connection.close(closeError || _errors.kBrowserClosedError);
|
||||||
|
};
|
||||||
|
pipe.on('closed', onPipeClosed);
|
||||||
|
connection.onmessage = message => pipe.send({
|
||||||
|
message
|
||||||
|
}).catch(onPipeClosed);
|
||||||
|
pipe.on('message', ({
|
||||||
|
message
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
connection.dispatch(message);
|
||||||
|
} catch (e) {
|
||||||
|
closeError = e.toString();
|
||||||
|
closePipe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const result = await (0, _timeoutRunner.raceAgainstTimeout)(async () => {
|
||||||
|
const playwright = await connection.initializePlaywright();
|
||||||
|
if (!playwright._initializer.preConnectedAndroidDevice) {
|
||||||
|
closePipe();
|
||||||
|
throw new Error('Malformed endpoint. Did you use Android.launchServer method?');
|
||||||
|
}
|
||||||
|
device = AndroidDevice.from(playwright._initializer.preConnectedAndroidDevice);
|
||||||
|
device._shouldCloseConnectionOnClose = true;
|
||||||
|
device.on(_events.Events.AndroidDevice.Close, closePipe);
|
||||||
|
return device;
|
||||||
|
}, deadline ? deadline - (0, _utils.monotonicTime)() : 0);
|
||||||
|
if (!result.timedOut) {
|
||||||
|
return result.result;
|
||||||
|
} else {
|
||||||
|
closePipe();
|
||||||
|
throw new Error(`Timeout ${options.timeout}ms exceeded`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Android = Android;
|
||||||
|
class AndroidDevice extends _channelOwner.ChannelOwner {
|
||||||
|
static from(androidDevice) {
|
||||||
|
return androidDevice._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._timeoutSettings = void 0;
|
||||||
|
this._webViews = new Map();
|
||||||
|
this._shouldCloseConnectionOnClose = false;
|
||||||
|
this.input = void 0;
|
||||||
|
this.input = new AndroidInput(this);
|
||||||
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings(parent._timeoutSettings);
|
||||||
|
this._channel.on('webViewAdded', ({
|
||||||
|
webView
|
||||||
|
}) => this._onWebViewAdded(webView));
|
||||||
|
this._channel.on('webViewRemoved', ({
|
||||||
|
socketName
|
||||||
|
}) => this._onWebViewRemoved(socketName));
|
||||||
|
this._channel.on('close', () => this._didClose());
|
||||||
|
}
|
||||||
|
_onWebViewAdded(webView) {
|
||||||
|
const view = new AndroidWebView(this, webView);
|
||||||
|
this._webViews.set(webView.socketName, view);
|
||||||
|
this.emit(_events.Events.AndroidDevice.WebView, view);
|
||||||
|
}
|
||||||
|
_onWebViewRemoved(socketName) {
|
||||||
|
const view = this._webViews.get(socketName);
|
||||||
|
this._webViews.delete(socketName);
|
||||||
|
if (view) view.emit(_events.Events.AndroidWebView.Close);
|
||||||
|
}
|
||||||
|
setDefaultTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
|
this._channel.setDefaultTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
}
|
||||||
|
serial() {
|
||||||
|
return this._initializer.serial;
|
||||||
|
}
|
||||||
|
model() {
|
||||||
|
return this._initializer.model;
|
||||||
|
}
|
||||||
|
webViews() {
|
||||||
|
return [...this._webViews.values()];
|
||||||
|
}
|
||||||
|
async webView(selector, options) {
|
||||||
|
const predicate = v => {
|
||||||
|
if (selector.pkg) return v.pkg() === selector.pkg;
|
||||||
|
if (selector.socketName) return v._socketName() === selector.socketName;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const webView = [...this._webViews.values()].find(predicate);
|
||||||
|
if (webView) return webView;
|
||||||
|
return this.waitForEvent('webview', {
|
||||||
|
...options,
|
||||||
|
predicate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async wait(selector, options) {
|
||||||
|
await this._channel.wait({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async fill(selector, text, options) {
|
||||||
|
await this._channel.fill({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
text,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(selector, key, options) {
|
||||||
|
await this.tap(selector, options);
|
||||||
|
await this.input.press(key);
|
||||||
|
}
|
||||||
|
async tap(selector, options) {
|
||||||
|
await this._channel.tap({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async drag(selector, dest, options) {
|
||||||
|
await this._channel.drag({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
dest,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async fling(selector, direction, options) {
|
||||||
|
await this._channel.fling({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
direction,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async longTap(selector, options) {
|
||||||
|
await this._channel.longTap({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async pinchClose(selector, percent, options) {
|
||||||
|
await this._channel.pinchClose({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
percent,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async pinchOpen(selector, percent, options) {
|
||||||
|
await this._channel.pinchOpen({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
percent,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async scroll(selector, direction, percent, options) {
|
||||||
|
await this._channel.scroll({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
direction,
|
||||||
|
percent,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async swipe(selector, direction, percent, options) {
|
||||||
|
await this._channel.swipe({
|
||||||
|
selector: toSelectorChannel(selector),
|
||||||
|
direction,
|
||||||
|
percent,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async info(selector) {
|
||||||
|
return (await this._channel.info({
|
||||||
|
selector: toSelectorChannel(selector)
|
||||||
|
})).info;
|
||||||
|
}
|
||||||
|
async screenshot(options = {}) {
|
||||||
|
const {
|
||||||
|
binary
|
||||||
|
} = await this._channel.screenshot();
|
||||||
|
if (options.path) await _fs.default.promises.writeFile(options.path, binary);
|
||||||
|
return binary;
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
try {
|
||||||
|
if (this._shouldCloseConnectionOnClose) this._connection.close(_errors.kBrowserClosedError);else await this._channel.close();
|
||||||
|
} catch (e) {
|
||||||
|
if ((0, _errors.isSafeCloseError)(e)) return;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_didClose() {
|
||||||
|
this.emit(_events.Events.AndroidDevice.Close, this);
|
||||||
|
}
|
||||||
|
async shell(command) {
|
||||||
|
const {
|
||||||
|
result
|
||||||
|
} = await this._channel.shell({
|
||||||
|
command
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
async open(command) {
|
||||||
|
return AndroidSocket.from((await this._channel.open({
|
||||||
|
command
|
||||||
|
})).socket);
|
||||||
|
}
|
||||||
|
async installApk(file, options) {
|
||||||
|
await this._channel.installApk({
|
||||||
|
file: await loadFile(file),
|
||||||
|
args: options && options.args
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async push(file, path, options) {
|
||||||
|
await this._channel.push({
|
||||||
|
file: await loadFile(file),
|
||||||
|
path,
|
||||||
|
mode: options ? options.mode : undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async launchBrowser(options = {}) {
|
||||||
|
const contextOptions = await (0, _browserContext.prepareBrowserContextParams)(options);
|
||||||
|
const {
|
||||||
|
context
|
||||||
|
} = await this._channel.launchBrowser(contextOptions);
|
||||||
|
return _browserContext.BrowserContext.from(context);
|
||||||
|
}
|
||||||
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||||
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||||
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||||
|
if (event !== _events.Events.AndroidDevice.Close) waiter.rejectOnEvent(this, _events.Events.AndroidDevice.Close, new Error('Device closed'));
|
||||||
|
const result = await waiter.waitForEvent(this, event, predicate);
|
||||||
|
waiter.dispose();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.AndroidDevice = AndroidDevice;
|
||||||
|
class AndroidSocket extends _channelOwner.ChannelOwner {
|
||||||
|
static from(androidDevice) {
|
||||||
|
return androidDevice._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._channel.on('data', ({
|
||||||
|
data
|
||||||
|
}) => this.emit(_events.Events.AndroidSocket.Data, data));
|
||||||
|
this._channel.on('close', () => this.emit(_events.Events.AndroidSocket.Close));
|
||||||
|
}
|
||||||
|
async write(data) {
|
||||||
|
await this._channel.write({
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
await this._channel.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.AndroidSocket = AndroidSocket;
|
||||||
|
async function loadFile(file) {
|
||||||
|
if ((0, _utils.isString)(file)) return _fs.default.promises.readFile(file);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
class AndroidInput {
|
||||||
|
constructor(device) {
|
||||||
|
this._device = void 0;
|
||||||
|
this._device = device;
|
||||||
|
}
|
||||||
|
async type(text) {
|
||||||
|
await this._device._channel.inputType({
|
||||||
|
text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(key) {
|
||||||
|
await this._device._channel.inputPress({
|
||||||
|
key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async tap(point) {
|
||||||
|
await this._device._channel.inputTap({
|
||||||
|
point
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async swipe(from, segments, steps) {
|
||||||
|
await this._device._channel.inputSwipe({
|
||||||
|
segments,
|
||||||
|
steps
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async drag(from, to, steps) {
|
||||||
|
await this._device._channel.inputDrag({
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
steps
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.AndroidInput = AndroidInput;
|
||||||
|
function toSelectorChannel(selector) {
|
||||||
|
const {
|
||||||
|
checkable,
|
||||||
|
checked,
|
||||||
|
clazz,
|
||||||
|
clickable,
|
||||||
|
depth,
|
||||||
|
desc,
|
||||||
|
enabled,
|
||||||
|
focusable,
|
||||||
|
focused,
|
||||||
|
hasChild,
|
||||||
|
hasDescendant,
|
||||||
|
longClickable,
|
||||||
|
pkg,
|
||||||
|
res,
|
||||||
|
scrollable,
|
||||||
|
selected,
|
||||||
|
text
|
||||||
|
} = selector;
|
||||||
|
const toRegex = value => {
|
||||||
|
if (value === undefined) return undefined;
|
||||||
|
if ((0, _utils.isRegExp)(value)) return value.source;
|
||||||
|
return '^' + value.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d') + '$';
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
checkable,
|
||||||
|
checked,
|
||||||
|
clazz: toRegex(clazz),
|
||||||
|
pkg: toRegex(pkg),
|
||||||
|
desc: toRegex(desc),
|
||||||
|
res: toRegex(res),
|
||||||
|
text: toRegex(text),
|
||||||
|
clickable,
|
||||||
|
depth,
|
||||||
|
enabled,
|
||||||
|
focusable,
|
||||||
|
focused,
|
||||||
|
hasChild: hasChild ? {
|
||||||
|
selector: toSelectorChannel(hasChild.selector)
|
||||||
|
} : undefined,
|
||||||
|
hasDescendant: hasDescendant ? {
|
||||||
|
selector: toSelectorChannel(hasDescendant.selector),
|
||||||
|
maxDepth: hasDescendant.maxDepth
|
||||||
|
} : undefined,
|
||||||
|
longClickable,
|
||||||
|
scrollable,
|
||||||
|
selected
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class AndroidWebView extends _events2.EventEmitter {
|
||||||
|
constructor(device, data) {
|
||||||
|
super();
|
||||||
|
this._device = void 0;
|
||||||
|
this._data = void 0;
|
||||||
|
this._pagePromise = void 0;
|
||||||
|
this._device = device;
|
||||||
|
this._data = data;
|
||||||
|
}
|
||||||
|
pid() {
|
||||||
|
return this._data.pid;
|
||||||
|
}
|
||||||
|
pkg() {
|
||||||
|
return this._data.pkg;
|
||||||
|
}
|
||||||
|
_socketName() {
|
||||||
|
return this._data.socketName;
|
||||||
|
}
|
||||||
|
async page() {
|
||||||
|
if (!this._pagePromise) this._pagePromise = this._fetchPage();
|
||||||
|
return this._pagePromise;
|
||||||
|
}
|
||||||
|
async _fetchPage() {
|
||||||
|
const {
|
||||||
|
context
|
||||||
|
} = await this._device._channel.connectToWebView({
|
||||||
|
socketName: this._data.socketName
|
||||||
|
});
|
||||||
|
return _browserContext.BrowserContext.from(context).pages()[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.AndroidWebView = AndroidWebView;
|
||||||
265
bin/pac/tools/.playwright/package/lib/client/api.js
Normal file
265
bin/pac/tools/.playwright/package/lib/client/api.js
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "APIRequest", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _fetch.APIRequest;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "APIRequestContext", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _fetch.APIRequestContext;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "APIResponse", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _fetch.APIResponse;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Accessibility", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _accessibility.Accessibility;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Android", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _android.Android;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "AndroidDevice", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _android.AndroidDevice;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "AndroidInput", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _android.AndroidInput;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "AndroidSocket", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _android.AndroidSocket;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "AndroidWebView", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _android.AndroidWebView;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Browser", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _browser.Browser;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "BrowserContext", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _browserContext.BrowserContext;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "BrowserType", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _browserType.BrowserType;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "CDPSession", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _cdpSession.CDPSession;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "ConsoleMessage", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _consoleMessage.ConsoleMessage;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Coverage", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _coverage.Coverage;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Dialog", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _dialog.Dialog;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Download", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _download.Download;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Electron", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _electron.Electron;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "ElectronApplication", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _electron.ElectronApplication;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "ElementHandle", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _elementHandle.ElementHandle;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "FileChooser", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _fileChooser.FileChooser;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Frame", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _frame.Frame;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "FrameLocator", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _locator.FrameLocator;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "JSHandle", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _jsHandle.JSHandle;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Keyboard", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _input.Keyboard;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Locator", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _locator.Locator;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Mouse", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _input.Mouse;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Page", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _page.Page;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Playwright", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _playwright.Playwright;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Request", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _network.Request;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Response", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _network.Response;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Route", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _network.Route;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Selectors", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _selectors.Selectors;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "TimeoutError", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _errors.TimeoutError;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Touchscreen", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _input.Touchscreen;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Tracing", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _tracing.Tracing;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Video", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _video.Video;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "WebSocket", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _network.WebSocket;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(exports, "Worker", {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _worker.Worker;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var _accessibility = require("./accessibility");
|
||||||
|
var _android = require("./android");
|
||||||
|
var _browser = require("./browser");
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _browserType = require("./browserType");
|
||||||
|
var _consoleMessage = require("./consoleMessage");
|
||||||
|
var _coverage = require("./coverage");
|
||||||
|
var _dialog = require("./dialog");
|
||||||
|
var _download = require("./download");
|
||||||
|
var _electron = require("./electron");
|
||||||
|
var _locator = require("./locator");
|
||||||
|
var _elementHandle = require("./elementHandle");
|
||||||
|
var _fileChooser = require("./fileChooser");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var _input = require("./input");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _network = require("./network");
|
||||||
|
var _fetch = require("./fetch");
|
||||||
|
var _page = require("./page");
|
||||||
|
var _selectors = require("./selectors");
|
||||||
|
var _tracing = require("./tracing");
|
||||||
|
var _video = require("./video");
|
||||||
|
var _worker = require("./worker");
|
||||||
|
var _cdpSession = require("./cdpSession");
|
||||||
|
var _playwright = require("./playwright");
|
||||||
67
bin/pac/tools/.playwright/package/lib/client/artifact.js
Normal file
67
bin/pac/tools/.playwright/package/lib/client/artifact.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Artifact = void 0;
|
||||||
|
var fs = _interopRequireWildcard(require("fs"));
|
||||||
|
var _stream = require("./stream");
|
||||||
|
var _fileUtils = require("../utils/fileUtils");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Artifact extends _channelOwner.ChannelOwner {
|
||||||
|
static from(channel) {
|
||||||
|
return channel._object;
|
||||||
|
}
|
||||||
|
async pathAfterFinished() {
|
||||||
|
if (this._connection.isRemote()) throw new Error(`Path is not available when connecting remotely. Use saveAs() to save a local copy.`);
|
||||||
|
return (await this._channel.pathAfterFinished()).value || null;
|
||||||
|
}
|
||||||
|
async saveAs(path) {
|
||||||
|
if (!this._connection.isRemote()) {
|
||||||
|
await this._channel.saveAs({
|
||||||
|
path
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await this._channel.saveAsStream();
|
||||||
|
const stream = _stream.Stream.from(result.stream);
|
||||||
|
await (0, _fileUtils.mkdirIfNeeded)(path);
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
stream.stream().pipe(fs.createWriteStream(path)).on('finish', resolve).on('error', reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async failure() {
|
||||||
|
return (await this._channel.failure()).error || null;
|
||||||
|
}
|
||||||
|
async createReadStream() {
|
||||||
|
const result = await this._channel.stream();
|
||||||
|
if (!result.stream) return null;
|
||||||
|
const stream = _stream.Stream.from(result.stream);
|
||||||
|
return stream.stream();
|
||||||
|
}
|
||||||
|
async cancel() {
|
||||||
|
return this._channel.cancel();
|
||||||
|
}
|
||||||
|
async delete() {
|
||||||
|
return this._channel.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Artifact = Artifact;
|
||||||
119
bin/pac/tools/.playwright/package/lib/client/browser.js
Normal file
119
bin/pac/tools/.playwright/package/lib/client/browser.js
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Browser = void 0;
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _cdpSession = require("./cdpSession");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Browser extends _channelOwner.ChannelOwner {
|
||||||
|
// Used from @playwright/test fixtures.
|
||||||
|
|
||||||
|
static from(browser) {
|
||||||
|
return browser._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._contexts = new Set();
|
||||||
|
this._isConnected = true;
|
||||||
|
this._closedPromise = void 0;
|
||||||
|
this._shouldCloseConnectionOnClose = false;
|
||||||
|
this._browserType = void 0;
|
||||||
|
this._options = {};
|
||||||
|
this._name = void 0;
|
||||||
|
this._connectHeaders = void 0;
|
||||||
|
this._name = initializer.name;
|
||||||
|
this._channel.on('close', () => this._didClose());
|
||||||
|
this._closedPromise = new Promise(f => this.once(_events.Events.Browser.Disconnected, f));
|
||||||
|
}
|
||||||
|
browserType() {
|
||||||
|
return this._browserType;
|
||||||
|
}
|
||||||
|
async newContext(options = {}) {
|
||||||
|
return await this._innerNewContext(options, false);
|
||||||
|
}
|
||||||
|
async _newContextForReuse(options = {}) {
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
for (const context of this._contexts) {
|
||||||
|
await this._browserType._willCloseContext(context);
|
||||||
|
for (const page of context.pages()) page._onClose();
|
||||||
|
context._onClose();
|
||||||
|
}
|
||||||
|
return await this._innerNewContext(options, true);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
async _innerNewContext(options = {}, forReuse) {
|
||||||
|
options = {
|
||||||
|
...this._browserType._defaultContextOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
const contextOptions = await (0, _browserContext.prepareBrowserContextParams)(options);
|
||||||
|
const response = forReuse ? await this._channel.newContextForReuse(contextOptions) : await this._channel.newContext(contextOptions);
|
||||||
|
const context = _browserContext.BrowserContext.from(response.context);
|
||||||
|
await this._browserType._didCreateContext(context, contextOptions, this._options, options.logger || this._logger);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
contexts() {
|
||||||
|
return [...this._contexts];
|
||||||
|
}
|
||||||
|
version() {
|
||||||
|
return this._initializer.version;
|
||||||
|
}
|
||||||
|
async newPage(options = {}) {
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const context = await this.newContext(options);
|
||||||
|
const page = await context.newPage();
|
||||||
|
page._ownedContext = context;
|
||||||
|
context._ownerPage = page;
|
||||||
|
return page;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
isConnected() {
|
||||||
|
return this._isConnected;
|
||||||
|
}
|
||||||
|
async newBrowserCDPSession() {
|
||||||
|
return _cdpSession.CDPSession.from((await this._channel.newBrowserCDPSession()).session);
|
||||||
|
}
|
||||||
|
async startTracing(page, options = {}) {
|
||||||
|
await this._channel.startTracing({
|
||||||
|
...options,
|
||||||
|
page: page ? page._channel : undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async stopTracing() {
|
||||||
|
return (await this._channel.stopTracing()).binary;
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
try {
|
||||||
|
if (this._shouldCloseConnectionOnClose) this._connection.close(_errors.kBrowserClosedError);else await this._channel.close();
|
||||||
|
await this._closedPromise;
|
||||||
|
} catch (e) {
|
||||||
|
if ((0, _errors.isSafeCloseError)(e)) return;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_didClose() {
|
||||||
|
this._isConnected = false;
|
||||||
|
this.emit(_events.Events.Browser.Disconnected, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Browser = Browser;
|
||||||
452
bin/pac/tools/.playwright/package/lib/client/browserContext.js
Normal file
452
bin/pac/tools/.playwright/package/lib/client/browserContext.js
Normal file
@@ -0,0 +1,452 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.BrowserContext = void 0;
|
||||||
|
exports.prepareBrowserContextParams = prepareBrowserContextParams;
|
||||||
|
var _page = require("./page");
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var network = _interopRequireWildcard(require("./network"));
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _clientHelper = require("./clientHelper");
|
||||||
|
var _browser = require("./browser");
|
||||||
|
var _worker = require("./worker");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _timeoutSettings = require("../common/timeoutSettings");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _fileUtils = require("../utils/fileUtils");
|
||||||
|
var _cdpSession = require("./cdpSession");
|
||||||
|
var _tracing = require("./tracing");
|
||||||
|
var _artifact = require("./artifact");
|
||||||
|
var _fetch = require("./fetch");
|
||||||
|
var _stackTrace = require("../utils/stackTrace");
|
||||||
|
var _harRouter = require("./harRouter");
|
||||||
|
var _consoleMessage = require("./consoleMessage");
|
||||||
|
var _dialog = require("./dialog");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BrowserContext extends _channelOwner.ChannelOwner {
|
||||||
|
static from(context) {
|
||||||
|
return context._object;
|
||||||
|
}
|
||||||
|
static fromNullable(context) {
|
||||||
|
return context ? BrowserContext.from(context) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
var _this$_browser, _this$_browser2;
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._pages = new Set();
|
||||||
|
this._routes = [];
|
||||||
|
this._browser = null;
|
||||||
|
this._browserType = void 0;
|
||||||
|
this._bindings = new Map();
|
||||||
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings();
|
||||||
|
this._ownerPage = void 0;
|
||||||
|
this._closedPromise = void 0;
|
||||||
|
this._options = {};
|
||||||
|
this.request = void 0;
|
||||||
|
this.tracing = void 0;
|
||||||
|
this._backgroundPages = new Set();
|
||||||
|
this._serviceWorkers = new Set();
|
||||||
|
this._isChromium = void 0;
|
||||||
|
this._harRecorders = new Map();
|
||||||
|
this._closeWasCalled = false;
|
||||||
|
if (parent instanceof _browser.Browser) this._browser = parent;
|
||||||
|
(_this$_browser = this._browser) === null || _this$_browser === void 0 ? void 0 : _this$_browser._contexts.add(this);
|
||||||
|
this._isChromium = ((_this$_browser2 = this._browser) === null || _this$_browser2 === void 0 ? void 0 : _this$_browser2._name) === 'chromium';
|
||||||
|
this.tracing = _tracing.Tracing.from(initializer.tracing);
|
||||||
|
this.request = _fetch.APIRequestContext.from(initializer.requestContext);
|
||||||
|
this._channel.on('bindingCall', ({
|
||||||
|
binding
|
||||||
|
}) => this._onBinding(_page.BindingCall.from(binding)));
|
||||||
|
this._channel.on('close', () => this._onClose());
|
||||||
|
this._channel.on('page', ({
|
||||||
|
page
|
||||||
|
}) => this._onPage(_page.Page.from(page)));
|
||||||
|
this._channel.on('route', ({
|
||||||
|
route
|
||||||
|
}) => this._onRoute(network.Route.from(route)));
|
||||||
|
this._channel.on('backgroundPage', ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
const backgroundPage = _page.Page.from(page);
|
||||||
|
this._backgroundPages.add(backgroundPage);
|
||||||
|
this.emit(_events.Events.BrowserContext.BackgroundPage, backgroundPage);
|
||||||
|
});
|
||||||
|
this._channel.on('serviceWorker', ({
|
||||||
|
worker
|
||||||
|
}) => {
|
||||||
|
const serviceWorker = _worker.Worker.from(worker);
|
||||||
|
serviceWorker._context = this;
|
||||||
|
this._serviceWorkers.add(serviceWorker);
|
||||||
|
this.emit(_events.Events.BrowserContext.ServiceWorker, serviceWorker);
|
||||||
|
});
|
||||||
|
this._channel.on('console', ({
|
||||||
|
message
|
||||||
|
}) => {
|
||||||
|
const consoleMessage = _consoleMessage.ConsoleMessage.from(message);
|
||||||
|
this.emit(_events.Events.BrowserContext.Console, consoleMessage);
|
||||||
|
const page = consoleMessage.page();
|
||||||
|
if (page) page.emit(_events.Events.Page.Console, consoleMessage);
|
||||||
|
});
|
||||||
|
this._channel.on('dialog', ({
|
||||||
|
dialog
|
||||||
|
}) => {
|
||||||
|
const dialogObject = _dialog.Dialog.from(dialog);
|
||||||
|
let hasListeners = this.emit(_events.Events.BrowserContext.Dialog, dialogObject);
|
||||||
|
const page = dialogObject.page();
|
||||||
|
if (page) hasListeners = page.emit(_events.Events.Page.Dialog, dialogObject) || hasListeners;
|
||||||
|
if (!hasListeners) {
|
||||||
|
// Although we do similar handling on the server side, we still need this logic
|
||||||
|
// on the client side due to a possible race condition between two async calls:
|
||||||
|
// a) removing "dialog" listener subscription (client->server)
|
||||||
|
// b) actual "dialog" event (server->client)
|
||||||
|
if (dialogObject.type() === 'beforeunload') dialog.accept({}).catch(() => {});else dialog.dismiss().catch(() => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._channel.on('request', ({
|
||||||
|
request,
|
||||||
|
page
|
||||||
|
}) => this._onRequest(network.Request.from(request), _page.Page.fromNullable(page)));
|
||||||
|
this._channel.on('requestFailed', ({
|
||||||
|
request,
|
||||||
|
failureText,
|
||||||
|
responseEndTiming,
|
||||||
|
page
|
||||||
|
}) => this._onRequestFailed(network.Request.from(request), responseEndTiming, failureText, _page.Page.fromNullable(page)));
|
||||||
|
this._channel.on('requestFinished', params => this._onRequestFinished(params));
|
||||||
|
this._channel.on('response', ({
|
||||||
|
response,
|
||||||
|
page
|
||||||
|
}) => this._onResponse(network.Response.from(response), _page.Page.fromNullable(page)));
|
||||||
|
this._closedPromise = new Promise(f => this.once(_events.Events.BrowserContext.Close, f));
|
||||||
|
this._setEventToSubscriptionMapping(new Map([[_events.Events.BrowserContext.Console, 'console'], [_events.Events.BrowserContext.Dialog, 'dialog'], [_events.Events.BrowserContext.Request, 'request'], [_events.Events.BrowserContext.Response, 'response'], [_events.Events.BrowserContext.RequestFinished, 'requestFinished'], [_events.Events.BrowserContext.RequestFailed, 'requestFailed']]));
|
||||||
|
}
|
||||||
|
_setOptions(contextOptions, browserOptions) {
|
||||||
|
this._options = contextOptions;
|
||||||
|
if (this._options.recordHar) this._harRecorders.set('', {
|
||||||
|
path: this._options.recordHar.path,
|
||||||
|
content: this._options.recordHar.content
|
||||||
|
});
|
||||||
|
this.tracing._tracesDir = browserOptions.tracesDir;
|
||||||
|
}
|
||||||
|
_onPage(page) {
|
||||||
|
this._pages.add(page);
|
||||||
|
this.emit(_events.Events.BrowserContext.Page, page);
|
||||||
|
if (page._opener && !page._opener.isClosed()) page._opener.emit(_events.Events.Page.Popup, page);
|
||||||
|
}
|
||||||
|
_onRequest(request, page) {
|
||||||
|
this.emit(_events.Events.BrowserContext.Request, request);
|
||||||
|
if (page) page.emit(_events.Events.Page.Request, request);
|
||||||
|
}
|
||||||
|
_onResponse(response, page) {
|
||||||
|
this.emit(_events.Events.BrowserContext.Response, response);
|
||||||
|
if (page) page.emit(_events.Events.Page.Response, response);
|
||||||
|
}
|
||||||
|
_onRequestFailed(request, responseEndTiming, failureText, page) {
|
||||||
|
request._failureText = failureText || null;
|
||||||
|
request._setResponseEndTiming(responseEndTiming);
|
||||||
|
this.emit(_events.Events.BrowserContext.RequestFailed, request);
|
||||||
|
if (page) page.emit(_events.Events.Page.RequestFailed, request);
|
||||||
|
}
|
||||||
|
_onRequestFinished(params) {
|
||||||
|
const {
|
||||||
|
responseEndTiming
|
||||||
|
} = params;
|
||||||
|
const request = network.Request.from(params.request);
|
||||||
|
const response = network.Response.fromNullable(params.response);
|
||||||
|
const page = _page.Page.fromNullable(params.page);
|
||||||
|
request._setResponseEndTiming(responseEndTiming);
|
||||||
|
this.emit(_events.Events.BrowserContext.RequestFinished, request);
|
||||||
|
if (page) page.emit(_events.Events.Page.RequestFinished, request);
|
||||||
|
if (response) response._finishedPromise.resolve(null);
|
||||||
|
}
|
||||||
|
async _onRoute(route) {
|
||||||
|
const routeHandlers = this._routes.slice();
|
||||||
|
for (const routeHandler of routeHandlers) {
|
||||||
|
if (!routeHandler.matches(route.request().url())) continue;
|
||||||
|
if (routeHandler.willExpire()) this._routes.splice(this._routes.indexOf(routeHandler), 1);
|
||||||
|
const handled = await routeHandler.handle(route);
|
||||||
|
if (!this._routes.length) this._wrapApiCall(() => this._updateInterceptionPatterns(), true).catch(() => {});
|
||||||
|
if (handled) return;
|
||||||
|
}
|
||||||
|
await route._innerContinue(true);
|
||||||
|
}
|
||||||
|
async _onBinding(bindingCall) {
|
||||||
|
const func = this._bindings.get(bindingCall._initializer.name);
|
||||||
|
if (!func) return;
|
||||||
|
await bindingCall.call(func);
|
||||||
|
}
|
||||||
|
setDefaultNavigationTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||||
|
this._wrapApiCall(async () => {
|
||||||
|
this._channel.setDefaultNavigationTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
}).catch(() => {});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
setDefaultTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
|
this._wrapApiCall(async () => {
|
||||||
|
this._channel.setDefaultTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
}).catch(() => {});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
browser() {
|
||||||
|
return this._browser;
|
||||||
|
}
|
||||||
|
pages() {
|
||||||
|
return [...this._pages];
|
||||||
|
}
|
||||||
|
async newPage() {
|
||||||
|
if (this._ownerPage) throw new Error('Please use browser.newContext()');
|
||||||
|
return _page.Page.from((await this._channel.newPage()).page);
|
||||||
|
}
|
||||||
|
async cookies(urls) {
|
||||||
|
if (!urls) urls = [];
|
||||||
|
if (urls && typeof urls === 'string') urls = [urls];
|
||||||
|
return (await this._channel.cookies({
|
||||||
|
urls: urls
|
||||||
|
})).cookies;
|
||||||
|
}
|
||||||
|
async addCookies(cookies) {
|
||||||
|
await this._channel.addCookies({
|
||||||
|
cookies
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async clearCookies() {
|
||||||
|
await this._channel.clearCookies();
|
||||||
|
}
|
||||||
|
async grantPermissions(permissions, options) {
|
||||||
|
await this._channel.grantPermissions({
|
||||||
|
permissions,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async clearPermissions() {
|
||||||
|
await this._channel.clearPermissions();
|
||||||
|
}
|
||||||
|
async setGeolocation(geolocation) {
|
||||||
|
await this._channel.setGeolocation({
|
||||||
|
geolocation: geolocation || undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async setExtraHTTPHeaders(headers) {
|
||||||
|
network.validateHeaders(headers);
|
||||||
|
await this._channel.setExtraHTTPHeaders({
|
||||||
|
headers: (0, _utils.headersObjectToArray)(headers)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async setOffline(offline) {
|
||||||
|
await this._channel.setOffline({
|
||||||
|
offline
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async setHTTPCredentials(httpCredentials) {
|
||||||
|
await this._channel.setHTTPCredentials({
|
||||||
|
httpCredentials: httpCredentials || undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async addInitScript(script, arg) {
|
||||||
|
const source = await (0, _clientHelper.evaluationScript)(script, arg);
|
||||||
|
await this._channel.addInitScript({
|
||||||
|
source
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async exposeBinding(name, callback, options = {}) {
|
||||||
|
await this._channel.exposeBinding({
|
||||||
|
name,
|
||||||
|
needsHandle: options.handle
|
||||||
|
});
|
||||||
|
this._bindings.set(name, callback);
|
||||||
|
}
|
||||||
|
async exposeFunction(name, callback) {
|
||||||
|
await this._channel.exposeBinding({
|
||||||
|
name
|
||||||
|
});
|
||||||
|
const binding = (source, ...args) => callback(...args);
|
||||||
|
this._bindings.set(name, binding);
|
||||||
|
}
|
||||||
|
async route(url, handler, options = {}) {
|
||||||
|
this._routes.unshift(new network.RouteHandler(this._options.baseURL, url, handler, options.times));
|
||||||
|
await this._updateInterceptionPatterns();
|
||||||
|
}
|
||||||
|
async _recordIntoHAR(har, page, options = {}) {
|
||||||
|
var _options$updateConten, _options$updateMode, _options$updateConten2;
|
||||||
|
const {
|
||||||
|
harId
|
||||||
|
} = await this._channel.harStart({
|
||||||
|
page: page === null || page === void 0 ? void 0 : page._channel,
|
||||||
|
options: prepareRecordHarOptions({
|
||||||
|
path: har,
|
||||||
|
content: (_options$updateConten = options.updateContent) !== null && _options$updateConten !== void 0 ? _options$updateConten : 'attach',
|
||||||
|
mode: (_options$updateMode = options.updateMode) !== null && _options$updateMode !== void 0 ? _options$updateMode : 'minimal',
|
||||||
|
urlFilter: options.url
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this._harRecorders.set(harId, {
|
||||||
|
path: har,
|
||||||
|
content: (_options$updateConten2 = options.updateContent) !== null && _options$updateConten2 !== void 0 ? _options$updateConten2 : 'attach'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async routeFromHAR(har, options = {}) {
|
||||||
|
if (options.update) {
|
||||||
|
await this._recordIntoHAR(har, null, options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const harRouter = await _harRouter.HarRouter.create(this._connection.localUtils(), har, options.notFound || 'abort', {
|
||||||
|
urlMatch: options.url
|
||||||
|
});
|
||||||
|
harRouter.addContextRoute(this);
|
||||||
|
}
|
||||||
|
async unroute(url, handler) {
|
||||||
|
this._routes = this._routes.filter(route => !(0, _utils.urlMatchesEqual)(route.url, url) || handler && route.handler !== handler);
|
||||||
|
await this._updateInterceptionPatterns();
|
||||||
|
}
|
||||||
|
async _updateInterceptionPatterns() {
|
||||||
|
const patterns = network.RouteHandler.prepareInterceptionPatterns(this._routes);
|
||||||
|
await this._channel.setNetworkInterceptionPatterns({
|
||||||
|
patterns
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||||
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||||
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||||
|
if (event !== _events.Events.BrowserContext.Close) waiter.rejectOnEvent(this, _events.Events.BrowserContext.Close, new Error('Context closed'));
|
||||||
|
const result = await waiter.waitForEvent(this, event, predicate);
|
||||||
|
waiter.dispose();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async storageState(options = {}) {
|
||||||
|
const state = await this._channel.storageState();
|
||||||
|
if (options.path) {
|
||||||
|
await (0, _fileUtils.mkdirIfNeeded)(options.path);
|
||||||
|
await _fs.default.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
backgroundPages() {
|
||||||
|
return [...this._backgroundPages];
|
||||||
|
}
|
||||||
|
serviceWorkers() {
|
||||||
|
return [...this._serviceWorkers];
|
||||||
|
}
|
||||||
|
async newCDPSession(page) {
|
||||||
|
// channelOwner.ts's validation messages don't handle the pseudo-union type, so we're explicit here
|
||||||
|
if (!(page instanceof _page.Page) && !(page instanceof _frame.Frame)) throw new Error('page: expected Page or Frame');
|
||||||
|
const result = await this._channel.newCDPSession(page instanceof _page.Page ? {
|
||||||
|
page: page._channel
|
||||||
|
} : {
|
||||||
|
frame: page._channel
|
||||||
|
});
|
||||||
|
return _cdpSession.CDPSession.from(result.session);
|
||||||
|
}
|
||||||
|
_onClose() {
|
||||||
|
var _this$_browserType, _this$_browserType$_c;
|
||||||
|
if (this._browser) this._browser._contexts.delete(this);
|
||||||
|
(_this$_browserType = this._browserType) === null || _this$_browserType === void 0 ? void 0 : (_this$_browserType$_c = _this$_browserType._contexts) === null || _this$_browserType$_c === void 0 ? void 0 : _this$_browserType$_c.delete(this);
|
||||||
|
this.emit(_events.Events.BrowserContext.Close, this);
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
if (this._closeWasCalled) return;
|
||||||
|
this._closeWasCalled = true;
|
||||||
|
await this._wrapApiCall(async () => {
|
||||||
|
var _this$_browserType2;
|
||||||
|
await ((_this$_browserType2 = this._browserType) === null || _this$_browserType2 === void 0 ? void 0 : _this$_browserType2._willCloseContext(this));
|
||||||
|
for (const [harId, harParams] of this._harRecorders) {
|
||||||
|
const har = await this._channel.harExport({
|
||||||
|
harId
|
||||||
|
});
|
||||||
|
const artifact = _artifact.Artifact.from(har.artifact);
|
||||||
|
// Server side will compress artifact if content is attach or if file is .zip.
|
||||||
|
const isCompressed = harParams.content === 'attach' || harParams.path.endsWith('.zip');
|
||||||
|
const needCompressed = harParams.path.endsWith('.zip');
|
||||||
|
if (isCompressed && !needCompressed) {
|
||||||
|
await artifact.saveAs(harParams.path + '.tmp');
|
||||||
|
await this._connection.localUtils()._channel.harUnzip({
|
||||||
|
zipFile: harParams.path + '.tmp',
|
||||||
|
harFile: harParams.path
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await artifact.saveAs(harParams.path);
|
||||||
|
}
|
||||||
|
await artifact.delete();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
await this._channel.close();
|
||||||
|
await this._closedPromise;
|
||||||
|
}
|
||||||
|
async _enableRecorder(params) {
|
||||||
|
await this._channel.recorderSupplementEnable(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BrowserContext = BrowserContext;
|
||||||
|
async function prepareStorageState(options) {
|
||||||
|
if (typeof options.storageState !== 'string') return options.storageState;
|
||||||
|
try {
|
||||||
|
return JSON.parse(await _fs.default.promises.readFile(options.storageState, 'utf8'));
|
||||||
|
} catch (e) {
|
||||||
|
(0, _stackTrace.rewriteErrorMessage)(e, `Error reading storage state from ${options.storageState}:\n` + e.message);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function prepareRecordHarOptions(options) {
|
||||||
|
if (!options) return;
|
||||||
|
return {
|
||||||
|
path: options.path,
|
||||||
|
content: options.content || (options.omitContent ? 'omit' : undefined),
|
||||||
|
urlGlob: (0, _utils.isString)(options.urlFilter) ? options.urlFilter : undefined,
|
||||||
|
urlRegexSource: (0, _utils.isRegExp)(options.urlFilter) ? options.urlFilter.source : undefined,
|
||||||
|
urlRegexFlags: (0, _utils.isRegExp)(options.urlFilter) ? options.urlFilter.flags : undefined,
|
||||||
|
mode: options.mode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function prepareBrowserContextParams(options) {
|
||||||
|
if (options.videoSize && !options.videosPath) throw new Error(`"videoSize" option requires "videosPath" to be specified`);
|
||||||
|
if (options.extraHTTPHeaders) network.validateHeaders(options.extraHTTPHeaders);
|
||||||
|
const contextParams = {
|
||||||
|
...options,
|
||||||
|
viewport: options.viewport === null ? undefined : options.viewport,
|
||||||
|
noDefaultViewport: options.viewport === null,
|
||||||
|
extraHTTPHeaders: options.extraHTTPHeaders ? (0, _utils.headersObjectToArray)(options.extraHTTPHeaders) : undefined,
|
||||||
|
storageState: await prepareStorageState(options),
|
||||||
|
serviceWorkers: options.serviceWorkers,
|
||||||
|
recordHar: prepareRecordHarOptions(options.recordHar),
|
||||||
|
colorScheme: options.colorScheme === null ? 'no-override' : options.colorScheme,
|
||||||
|
reducedMotion: options.reducedMotion === null ? 'no-override' : options.reducedMotion,
|
||||||
|
forcedColors: options.forcedColors === null ? 'no-override' : options.forcedColors
|
||||||
|
};
|
||||||
|
if (!contextParams.recordVideo && options.videosPath) {
|
||||||
|
contextParams.recordVideo = {
|
||||||
|
dir: options.videosPath,
|
||||||
|
size: options.videoSize
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return contextParams;
|
||||||
|
}
|
||||||
252
bin/pac/tools/.playwright/package/lib/client/browserType.js
Normal file
252
bin/pac/tools/.playwright/package/lib/client/browserType.js
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.BrowserType = void 0;
|
||||||
|
var _browser3 = require("./browser");
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _connection = require("./connection");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _clientHelper = require("./clientHelper");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _timeoutRunner = require("../utils/timeoutRunner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This is here just for api generation and checking.
|
||||||
|
|
||||||
|
class BrowserType extends _channelOwner.ChannelOwner {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
this._serverLauncher = void 0;
|
||||||
|
this._contexts = new Set();
|
||||||
|
this._playwright = void 0;
|
||||||
|
// Instrumentation.
|
||||||
|
this._defaultContextOptions = void 0;
|
||||||
|
this._defaultContextTimeout = void 0;
|
||||||
|
this._defaultContextNavigationTimeout = void 0;
|
||||||
|
this._defaultLaunchOptions = void 0;
|
||||||
|
this._defaultConnectOptions = void 0;
|
||||||
|
}
|
||||||
|
static from(browserType) {
|
||||||
|
return browserType._object;
|
||||||
|
}
|
||||||
|
executablePath() {
|
||||||
|
if (!this._initializer.executablePath) throw new Error('Browser is not supported on current platform');
|
||||||
|
return this._initializer.executablePath;
|
||||||
|
}
|
||||||
|
name() {
|
||||||
|
return this._initializer.name;
|
||||||
|
}
|
||||||
|
async launch(options = {}) {
|
||||||
|
var _this$_defaultLaunchO;
|
||||||
|
(0, _utils.assert)(!options.userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
||||||
|
(0, _utils.assert)(!options.port, 'Cannot specify a port without launching as a server.');
|
||||||
|
if (this._defaultConnectOptions) return await this._connectInsteadOfLaunching(this._defaultConnectOptions, options);
|
||||||
|
const logger = options.logger || ((_this$_defaultLaunchO = this._defaultLaunchOptions) === null || _this$_defaultLaunchO === void 0 ? void 0 : _this$_defaultLaunchO.logger);
|
||||||
|
options = {
|
||||||
|
...this._defaultLaunchOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
const launchOptions = {
|
||||||
|
...options,
|
||||||
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
|
env: options.env ? (0, _clientHelper.envObjectToArray)(options.env) : undefined
|
||||||
|
};
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const browser = _browser3.Browser.from((await this._channel.launch(launchOptions)).browser);
|
||||||
|
this._didLaunchBrowser(browser, options, logger);
|
||||||
|
return browser;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _connectInsteadOfLaunching(connectOptions, launchOptions) {
|
||||||
|
var _connectOptions$timeo;
|
||||||
|
return this._connect({
|
||||||
|
wsEndpoint: connectOptions.wsEndpoint,
|
||||||
|
headers: {
|
||||||
|
'x-playwright-launch-options': JSON.stringify({
|
||||||
|
...this._defaultLaunchOptions,
|
||||||
|
...launchOptions
|
||||||
|
}),
|
||||||
|
...connectOptions.headers
|
||||||
|
},
|
||||||
|
_exposeNetwork: connectOptions._exposeNetwork,
|
||||||
|
slowMo: connectOptions.slowMo,
|
||||||
|
timeout: (_connectOptions$timeo = connectOptions.timeout) !== null && _connectOptions$timeo !== void 0 ? _connectOptions$timeo : 3 * 60 * 1000 // 3 minutes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async launchServer(options = {}) {
|
||||||
|
if (!this._serverLauncher) throw new Error('Launching server is not supported');
|
||||||
|
options = {
|
||||||
|
...this._defaultLaunchOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
return this._serverLauncher.launchServer(options);
|
||||||
|
}
|
||||||
|
async launchPersistentContext(userDataDir, options = {}) {
|
||||||
|
var _this$_defaultLaunchO2;
|
||||||
|
const logger = options.logger || ((_this$_defaultLaunchO2 = this._defaultLaunchOptions) === null || _this$_defaultLaunchO2 === void 0 ? void 0 : _this$_defaultLaunchO2.logger);
|
||||||
|
(0, _utils.assert)(!options.port, 'Cannot specify a port without launching as a server.');
|
||||||
|
options = {
|
||||||
|
...this._defaultLaunchOptions,
|
||||||
|
...this._defaultContextOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
const contextParams = await (0, _browserContext.prepareBrowserContextParams)(options);
|
||||||
|
const persistentParams = {
|
||||||
|
...contextParams,
|
||||||
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
|
env: options.env ? (0, _clientHelper.envObjectToArray)(options.env) : undefined,
|
||||||
|
channel: options.channel,
|
||||||
|
userDataDir
|
||||||
|
};
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const result = await this._channel.launchPersistentContext(persistentParams);
|
||||||
|
const context = _browserContext.BrowserContext.from(result.context);
|
||||||
|
await this._didCreateContext(context, contextParams, options, logger);
|
||||||
|
return context;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async connect(optionsOrWsEndpoint, options) {
|
||||||
|
if (typeof optionsOrWsEndpoint === 'string') return this._connect({
|
||||||
|
...options,
|
||||||
|
wsEndpoint: optionsOrWsEndpoint
|
||||||
|
});
|
||||||
|
(0, _utils.assert)(optionsOrWsEndpoint.wsEndpoint, 'options.wsEndpoint is required');
|
||||||
|
return this._connect(optionsOrWsEndpoint);
|
||||||
|
}
|
||||||
|
async _connect(params) {
|
||||||
|
const logger = params.logger;
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const deadline = params.timeout ? (0, _utils.monotonicTime)() + params.timeout : 0;
|
||||||
|
const headers = {
|
||||||
|
'x-playwright-browser': this.name(),
|
||||||
|
...params.headers
|
||||||
|
};
|
||||||
|
const localUtils = this._connection.localUtils();
|
||||||
|
const connectParams = {
|
||||||
|
wsEndpoint: params.wsEndpoint,
|
||||||
|
headers,
|
||||||
|
exposeNetwork: params._exposeNetwork,
|
||||||
|
slowMo: params.slowMo,
|
||||||
|
timeout: params.timeout
|
||||||
|
};
|
||||||
|
if (params.__testHookRedirectPortForwarding) connectParams.socksProxyRedirectPortForTest = params.__testHookRedirectPortForwarding;
|
||||||
|
const {
|
||||||
|
pipe,
|
||||||
|
headers: connectHeaders
|
||||||
|
} = await localUtils._channel.connect(connectParams);
|
||||||
|
const closePipe = () => pipe.close().catch(() => {});
|
||||||
|
const connection = new _connection.Connection(localUtils, this._instrumentation);
|
||||||
|
connection.markAsRemote();
|
||||||
|
connection.on('close', closePipe);
|
||||||
|
let browser;
|
||||||
|
let closeError;
|
||||||
|
const onPipeClosed = () => {
|
||||||
|
var _browser2;
|
||||||
|
// Emulate all pages, contexts and the browser closing upon disconnect.
|
||||||
|
for (const context of ((_browser = browser) === null || _browser === void 0 ? void 0 : _browser.contexts()) || []) {
|
||||||
|
var _browser;
|
||||||
|
for (const page of context.pages()) page._onClose();
|
||||||
|
context._onClose();
|
||||||
|
}
|
||||||
|
(_browser2 = browser) === null || _browser2 === void 0 ? void 0 : _browser2._didClose();
|
||||||
|
connection.close(closeError || _errors.kBrowserClosedError);
|
||||||
|
};
|
||||||
|
pipe.on('closed', onPipeClosed);
|
||||||
|
connection.onmessage = message => pipe.send({
|
||||||
|
message
|
||||||
|
}).catch(onPipeClosed);
|
||||||
|
pipe.on('message', ({
|
||||||
|
message
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
connection.dispatch(message);
|
||||||
|
} catch (e) {
|
||||||
|
closeError = e.toString();
|
||||||
|
closePipe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const result = await (0, _timeoutRunner.raceAgainstTimeout)(async () => {
|
||||||
|
// For tests.
|
||||||
|
if (params.__testHookBeforeCreateBrowser) await params.__testHookBeforeCreateBrowser();
|
||||||
|
const playwright = await connection.initializePlaywright();
|
||||||
|
if (!playwright._initializer.preLaunchedBrowser) {
|
||||||
|
closePipe();
|
||||||
|
throw new Error('Malformed endpoint. Did you use BrowserType.launchServer method?');
|
||||||
|
}
|
||||||
|
playwright._setSelectors(this._playwright.selectors);
|
||||||
|
browser = _browser3.Browser.from(playwright._initializer.preLaunchedBrowser);
|
||||||
|
this._didLaunchBrowser(browser, {}, logger);
|
||||||
|
browser._shouldCloseConnectionOnClose = true;
|
||||||
|
browser._connectHeaders = connectHeaders;
|
||||||
|
browser.on(_events.Events.Browser.Disconnected, closePipe);
|
||||||
|
return browser;
|
||||||
|
}, deadline ? deadline - (0, _utils.monotonicTime)() : 0);
|
||||||
|
if (!result.timedOut) {
|
||||||
|
return result.result;
|
||||||
|
} else {
|
||||||
|
closePipe();
|
||||||
|
throw new Error(`Timeout ${params.timeout}ms exceeded`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
connectOverCDP(endpointURLOrOptions, options) {
|
||||||
|
if (typeof endpointURLOrOptions === 'string') return this._connectOverCDP(endpointURLOrOptions, options);
|
||||||
|
const endpointURL = 'endpointURL' in endpointURLOrOptions ? endpointURLOrOptions.endpointURL : endpointURLOrOptions.wsEndpoint;
|
||||||
|
(0, _utils.assert)(endpointURL, 'Cannot connect over CDP without wsEndpoint.');
|
||||||
|
return this.connectOverCDP(endpointURL, endpointURLOrOptions);
|
||||||
|
}
|
||||||
|
async _connectOverCDP(endpointURL, params = {}) {
|
||||||
|
if (this.name() !== 'chromium') throw new Error('Connecting over CDP is only supported in Chromium.');
|
||||||
|
const headers = params.headers ? (0, _utils.headersObjectToArray)(params.headers) : undefined;
|
||||||
|
const result = await this._channel.connectOverCDP({
|
||||||
|
endpointURL,
|
||||||
|
headers,
|
||||||
|
slowMo: params.slowMo,
|
||||||
|
timeout: params.timeout
|
||||||
|
});
|
||||||
|
const browser = _browser3.Browser.from(result.browser);
|
||||||
|
this._didLaunchBrowser(browser, {}, params.logger);
|
||||||
|
if (result.defaultContext) await this._didCreateContext(_browserContext.BrowserContext.from(result.defaultContext), {}, {}, undefined);
|
||||||
|
return browser;
|
||||||
|
}
|
||||||
|
_didLaunchBrowser(browser, browserOptions, logger) {
|
||||||
|
browser._browserType = this;
|
||||||
|
browser._options = browserOptions;
|
||||||
|
browser._logger = logger;
|
||||||
|
}
|
||||||
|
async _didCreateContext(context, contextOptions, browserOptions, logger) {
|
||||||
|
context._logger = logger;
|
||||||
|
context._browserType = this;
|
||||||
|
this._contexts.add(context);
|
||||||
|
context._setOptions(contextOptions, browserOptions);
|
||||||
|
if (this._defaultContextTimeout !== undefined) context.setDefaultTimeout(this._defaultContextTimeout);
|
||||||
|
if (this._defaultContextNavigationTimeout !== undefined) context.setDefaultNavigationTimeout(this._defaultContextNavigationTimeout);
|
||||||
|
await this._instrumentation.onDidCreateBrowserContext(context);
|
||||||
|
}
|
||||||
|
async _willCloseContext(context) {
|
||||||
|
this._contexts.delete(context);
|
||||||
|
await this._instrumentation.onWillCloseBrowserContext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BrowserType = BrowserType;
|
||||||
53
bin/pac/tools/.playwright/package/lib/client/cdpSession.js
Normal file
53
bin/pac/tools/.playwright/package/lib/client/cdpSession.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.CDPSession = void 0;
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CDPSession extends _channelOwner.ChannelOwner {
|
||||||
|
static from(cdpSession) {
|
||||||
|
return cdpSession._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._channel.on('event', ({
|
||||||
|
method,
|
||||||
|
params
|
||||||
|
}) => {
|
||||||
|
this.emit(method, params);
|
||||||
|
});
|
||||||
|
this.on = super.on;
|
||||||
|
this.addListener = super.addListener;
|
||||||
|
this.off = super.removeListener;
|
||||||
|
this.removeListener = super.removeListener;
|
||||||
|
this.once = super.once;
|
||||||
|
}
|
||||||
|
async send(method, params) {
|
||||||
|
const result = await this._channel.send({
|
||||||
|
method,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
return result.result;
|
||||||
|
}
|
||||||
|
async detach() {
|
||||||
|
return this._channel.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CDPSession = CDPSession;
|
||||||
223
bin/pac/tools/.playwright/package/lib/client/channelOwner.js
Normal file
223
bin/pac/tools/.playwright/package/lib/client/channelOwner.js
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.ChannelOwner = void 0;
|
||||||
|
var _events = require("events");
|
||||||
|
var _validator = require("../protocol/validator");
|
||||||
|
var _debugLogger = require("../common/debugLogger");
|
||||||
|
var _stackTrace = require("../utils/stackTrace");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _zones = require("../utils/zones");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ChannelOwner extends _events.EventEmitter {
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super();
|
||||||
|
this._connection = void 0;
|
||||||
|
this._parent = void 0;
|
||||||
|
this._objects = new Map();
|
||||||
|
this._type = void 0;
|
||||||
|
this._guid = void 0;
|
||||||
|
this._channel = void 0;
|
||||||
|
this._initializer = void 0;
|
||||||
|
this._logger = void 0;
|
||||||
|
this._instrumentation = void 0;
|
||||||
|
this._eventToSubscriptionMapping = new Map();
|
||||||
|
this.setMaxListeners(0);
|
||||||
|
this._connection = parent instanceof ChannelOwner ? parent._connection : parent;
|
||||||
|
this._type = type;
|
||||||
|
this._guid = guid;
|
||||||
|
this._parent = parent instanceof ChannelOwner ? parent : undefined;
|
||||||
|
this._instrumentation = this._connection._instrumentation;
|
||||||
|
this._connection._objects.set(guid, this);
|
||||||
|
if (this._parent) {
|
||||||
|
this._parent._objects.set(guid, this);
|
||||||
|
this._logger = this._parent._logger;
|
||||||
|
}
|
||||||
|
this._channel = this._createChannel(new _events.EventEmitter());
|
||||||
|
this._initializer = initializer;
|
||||||
|
}
|
||||||
|
_setEventToSubscriptionMapping(mapping) {
|
||||||
|
this._eventToSubscriptionMapping = mapping;
|
||||||
|
}
|
||||||
|
_updateSubscription(event, enabled) {
|
||||||
|
const protocolEvent = this._eventToSubscriptionMapping.get(String(event));
|
||||||
|
if (protocolEvent) {
|
||||||
|
this._wrapApiCall(async () => {
|
||||||
|
await this._channel.updateSubscription({
|
||||||
|
event: protocolEvent,
|
||||||
|
enabled
|
||||||
|
});
|
||||||
|
}, true).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
if (!this.listenerCount(event)) this._updateSubscription(event, true);
|
||||||
|
super.on(event, listener);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
addListener(event, listener) {
|
||||||
|
if (!this.listenerCount(event)) this._updateSubscription(event, true);
|
||||||
|
super.addListener(event, listener);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
prependListener(event, listener) {
|
||||||
|
if (!this.listenerCount(event)) this._updateSubscription(event, true);
|
||||||
|
super.prependListener(event, listener);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
off(event, listener) {
|
||||||
|
super.off(event, listener);
|
||||||
|
if (!this.listenerCount(event)) this._updateSubscription(event, false);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
removeListener(event, listener) {
|
||||||
|
super.removeListener(event, listener);
|
||||||
|
if (!this.listenerCount(event)) this._updateSubscription(event, false);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
_adopt(child) {
|
||||||
|
child._parent._objects.delete(child._guid);
|
||||||
|
this._objects.set(child._guid, child);
|
||||||
|
child._parent = this;
|
||||||
|
}
|
||||||
|
_dispose() {
|
||||||
|
// Clean up from parent and connection.
|
||||||
|
if (this._parent) this._parent._objects.delete(this._guid);
|
||||||
|
this._connection._objects.delete(this._guid);
|
||||||
|
|
||||||
|
// Dispose all children.
|
||||||
|
for (const object of [...this._objects.values()]) object._dispose();
|
||||||
|
this._objects.clear();
|
||||||
|
}
|
||||||
|
_debugScopeState() {
|
||||||
|
return {
|
||||||
|
_guid: this._guid,
|
||||||
|
objects: Array.from(this._objects.values()).map(o => o._debugScopeState())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_createChannel(base) {
|
||||||
|
const channel = new Proxy(base, {
|
||||||
|
get: (obj, prop) => {
|
||||||
|
if (typeof prop === 'string') {
|
||||||
|
const validator = (0, _validator.maybeFindValidator)(this._type, prop, 'Params');
|
||||||
|
if (validator) {
|
||||||
|
return params => {
|
||||||
|
return this._wrapApiCall(apiZone => {
|
||||||
|
const {
|
||||||
|
stackTrace,
|
||||||
|
csi,
|
||||||
|
callCookie,
|
||||||
|
wallTime
|
||||||
|
} = apiZone.reported ? {
|
||||||
|
csi: undefined,
|
||||||
|
callCookie: undefined,
|
||||||
|
stackTrace: null,
|
||||||
|
wallTime: undefined
|
||||||
|
} : apiZone;
|
||||||
|
apiZone.reported = true;
|
||||||
|
if (csi && stackTrace && stackTrace.apiName) csi.onApiCallBegin(stackTrace.apiName, params, stackTrace, wallTime, callCookie);
|
||||||
|
return this._connection.sendMessageToServer(this, this._type, prop, validator(params, '', {
|
||||||
|
tChannelImpl: tChannelImplToWire,
|
||||||
|
binary: this._connection.isRemote() ? 'toBase64' : 'buffer'
|
||||||
|
}), stackTrace, wallTime);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj[prop];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
channel._object = this;
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
async _wrapApiCall(func, isInternal = false) {
|
||||||
|
const logger = this._logger;
|
||||||
|
const stack = (0, _stackTrace.captureRawStack)();
|
||||||
|
const apiZone = _zones.zones.zoneData('apiZone', stack);
|
||||||
|
if (apiZone) return func(apiZone);
|
||||||
|
const stackTrace = (0, _stackTrace.captureLibraryStackTrace)(stack);
|
||||||
|
isInternal = isInternal || this._type === 'LocalUtils';
|
||||||
|
if (isInternal) delete stackTrace.apiName;
|
||||||
|
|
||||||
|
// Enclosing zone could have provided the apiName and wallTime.
|
||||||
|
const expectZone = _zones.zones.zoneData('expectZone', stack);
|
||||||
|
const wallTime = expectZone ? expectZone.wallTime : Date.now();
|
||||||
|
if (!isInternal && expectZone) stackTrace.apiName = expectZone.title;
|
||||||
|
const csi = isInternal ? undefined : this._instrumentation;
|
||||||
|
const callCookie = {};
|
||||||
|
const {
|
||||||
|
apiName,
|
||||||
|
frameTexts
|
||||||
|
} = stackTrace;
|
||||||
|
try {
|
||||||
|
logApiCall(logger, `=> ${apiName} started`, isInternal);
|
||||||
|
const apiZone = {
|
||||||
|
stackTrace,
|
||||||
|
isInternal,
|
||||||
|
reported: false,
|
||||||
|
csi,
|
||||||
|
callCookie,
|
||||||
|
wallTime
|
||||||
|
};
|
||||||
|
const result = await _zones.zones.run('apiZone', apiZone, async () => {
|
||||||
|
return await func(apiZone);
|
||||||
|
});
|
||||||
|
csi === null || csi === void 0 ? void 0 : csi.onApiCallEnd(callCookie);
|
||||||
|
logApiCall(logger, `<= ${apiName} succeeded`, isInternal);
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
const innerError = (process.env.PWDEBUGIMPL || (0, _utils.isUnderTest)()) && e.stack ? '\n<inner error>\n' + e.stack : '';
|
||||||
|
if (apiName && !apiName.includes('<anonymous>')) e.message = apiName + ': ' + e.message;
|
||||||
|
const stackFrames = '\n' + frameTexts.join('\n') + innerError;
|
||||||
|
if (stackFrames.trim()) e.stack = e.message + stackFrames;else e.stack = '';
|
||||||
|
csi === null || csi === void 0 ? void 0 : csi.onApiCallEnd(callCookie, e);
|
||||||
|
logApiCall(logger, `<= ${apiName} failed`, isInternal);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_toImpl() {
|
||||||
|
var _this$_connection$toI, _this$_connection;
|
||||||
|
return (_this$_connection$toI = (_this$_connection = this._connection).toImpl) === null || _this$_connection$toI === void 0 ? void 0 : _this$_connection$toI.call(_this$_connection, this);
|
||||||
|
}
|
||||||
|
toJSON() {
|
||||||
|
// Jest's expect library tries to print objects sometimes.
|
||||||
|
// RPC objects can contain links to lots of other objects,
|
||||||
|
// which can cause jest to crash. Let's help it out
|
||||||
|
// by just returning the important values.
|
||||||
|
return {
|
||||||
|
_type: this._type,
|
||||||
|
_guid: this._guid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelOwner = ChannelOwner;
|
||||||
|
function logApiCall(logger, message, isNested) {
|
||||||
|
if (isNested) return;
|
||||||
|
if (logger && logger.isEnabled('api', 'info')) logger.log('api', 'info', message, [], {
|
||||||
|
color: 'cyan'
|
||||||
|
});
|
||||||
|
_debugLogger.debugLogger.log('api', message);
|
||||||
|
}
|
||||||
|
function tChannelImplToWire(names, arg, path, context) {
|
||||||
|
if (arg._object instanceof ChannelOwner && (names === '*' || names.includes(arg._object._type))) return {
|
||||||
|
guid: arg._object._guid
|
||||||
|
};
|
||||||
|
throw new _validator.ValidationError(`${path}: expected channel ${names.toString()}`);
|
||||||
|
}
|
||||||
53
bin/pac/tools/.playwright/package/lib/client/clientHelper.js
Normal file
53
bin/pac/tools/.playwright/package/lib/client/clientHelper.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.envObjectToArray = envObjectToArray;
|
||||||
|
exports.evaluationScript = evaluationScript;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _utils = require("../utils");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function envObjectToArray(env) {
|
||||||
|
const result = [];
|
||||||
|
for (const name in env) {
|
||||||
|
if (!Object.is(env[name], undefined)) result.push({
|
||||||
|
name,
|
||||||
|
value: String(env[name])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
async function evaluationScript(fun, arg, addSourceUrl = true) {
|
||||||
|
if (typeof fun === 'function') {
|
||||||
|
const source = fun.toString();
|
||||||
|
const argString = Object.is(arg, undefined) ? 'undefined' : JSON.stringify(arg);
|
||||||
|
return `(${source})(${argString})`;
|
||||||
|
}
|
||||||
|
if (arg !== undefined) throw new Error('Cannot evaluate a string with arguments');
|
||||||
|
if ((0, _utils.isString)(fun)) return fun;
|
||||||
|
if (fun.content !== undefined) return fun.content;
|
||||||
|
if (fun.path !== undefined) {
|
||||||
|
let source = await _fs.default.promises.readFile(fun.path, 'utf8');
|
||||||
|
if (addSourceUrl) source += '\n//# sourceURL=' + fun.path.replace(/\n/g, '');
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
throw new Error('Either path or content property must be present');
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.createInstrumentation = createInstrumentation;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createInstrumentation() {
|
||||||
|
const listeners = [];
|
||||||
|
return new Proxy({}, {
|
||||||
|
get: (obj, prop) => {
|
||||||
|
if (typeof prop !== 'string') return obj[prop];
|
||||||
|
if (prop === 'addListener') return listener => listeners.push(listener);
|
||||||
|
if (prop === 'removeListener') return listener => listeners.splice(listeners.indexOf(listener), 1);
|
||||||
|
if (prop === 'removeAllListeners') return () => listeners.splice(0, listeners.length);
|
||||||
|
if (!prop.startsWith('on')) return obj[prop];
|
||||||
|
return async (...params) => {
|
||||||
|
for (const listener of listeners) {
|
||||||
|
var _prop, _ref;
|
||||||
|
await ((_prop = (_ref = listener)[prop]) === null || _prop === void 0 ? void 0 : _prop.call(_ref, ...params));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
330
bin/pac/tools/.playwright/package/lib/client/connection.js
Normal file
330
bin/pac/tools/.playwright/package/lib/client/connection.js
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Connection = void 0;
|
||||||
|
var _browser = require("./browser");
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _browserType = require("./browserType");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _elementHandle = require("./elementHandle");
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _network = require("./network");
|
||||||
|
var _page = require("./page");
|
||||||
|
var _worker = require("./worker");
|
||||||
|
var _consoleMessage = require("./consoleMessage");
|
||||||
|
var _dialog = require("./dialog");
|
||||||
|
var _serializers = require("../protocol/serializers");
|
||||||
|
var _cdpSession = require("./cdpSession");
|
||||||
|
var _playwright = require("./playwright");
|
||||||
|
var _electron = require("./electron");
|
||||||
|
var _stream = require("./stream");
|
||||||
|
var _writableStream = require("./writableStream");
|
||||||
|
var _debugLogger = require("../common/debugLogger");
|
||||||
|
var _selectors = require("./selectors");
|
||||||
|
var _android = require("./android");
|
||||||
|
var _stackTrace = require("../utils/stackTrace");
|
||||||
|
var _artifact = require("./artifact");
|
||||||
|
var _events = require("events");
|
||||||
|
var _jsonPipe = require("./jsonPipe");
|
||||||
|
var _fetch = require("./fetch");
|
||||||
|
var _localUtils = require("./localUtils");
|
||||||
|
var _tracing = require("./tracing");
|
||||||
|
var _validator = require("../protocol/validator");
|
||||||
|
var _clientInstrumentation = require("./clientInstrumentation");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Root extends _channelOwner.ChannelOwner {
|
||||||
|
constructor(connection) {
|
||||||
|
super(connection, 'Root', '', {});
|
||||||
|
}
|
||||||
|
async initialize() {
|
||||||
|
return _playwright.Playwright.from((await this._channel.initialize({
|
||||||
|
sdkLanguage: 'javascript'
|
||||||
|
})).playwright);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class DummyChannelOwner extends _channelOwner.ChannelOwner {}
|
||||||
|
class Connection extends _events.EventEmitter {
|
||||||
|
// Some connections allow resolving in-process dispatchers.
|
||||||
|
|
||||||
|
constructor(localUtils, instrumentation) {
|
||||||
|
super();
|
||||||
|
this._objects = new Map();
|
||||||
|
this.onmessage = message => {};
|
||||||
|
this._lastId = 0;
|
||||||
|
this._callbacks = new Map();
|
||||||
|
this._rootObject = void 0;
|
||||||
|
this._closedErrorMessage = void 0;
|
||||||
|
this._isRemote = false;
|
||||||
|
this._localUtils = void 0;
|
||||||
|
this.toImpl = void 0;
|
||||||
|
this._tracingCount = 0;
|
||||||
|
this._instrumentation = void 0;
|
||||||
|
this._rootObject = new Root(this);
|
||||||
|
this._localUtils = localUtils;
|
||||||
|
this._instrumentation = instrumentation || (0, _clientInstrumentation.createInstrumentation)();
|
||||||
|
}
|
||||||
|
markAsRemote() {
|
||||||
|
this._isRemote = true;
|
||||||
|
}
|
||||||
|
isRemote() {
|
||||||
|
return this._isRemote;
|
||||||
|
}
|
||||||
|
localUtils() {
|
||||||
|
return this._localUtils;
|
||||||
|
}
|
||||||
|
async initializePlaywright() {
|
||||||
|
return await this._rootObject.initialize();
|
||||||
|
}
|
||||||
|
pendingProtocolCalls() {
|
||||||
|
return Array.from(this._callbacks.values()).map(callback => callback.stackTrace).filter(Boolean);
|
||||||
|
}
|
||||||
|
getObjectWithKnownName(guid) {
|
||||||
|
return this._objects.get(guid);
|
||||||
|
}
|
||||||
|
async setIsTracing(isTracing) {
|
||||||
|
if (isTracing) this._tracingCount++;else this._tracingCount--;
|
||||||
|
}
|
||||||
|
async sendMessageToServer(object, type, method, params, stackTrace, wallTime) {
|
||||||
|
var _this$_localUtils;
|
||||||
|
if (this._closedErrorMessage) throw new Error(this._closedErrorMessage);
|
||||||
|
const {
|
||||||
|
apiName,
|
||||||
|
frames
|
||||||
|
} = stackTrace || {
|
||||||
|
apiName: '',
|
||||||
|
frames: []
|
||||||
|
};
|
||||||
|
const guid = object._guid;
|
||||||
|
const id = ++this._lastId;
|
||||||
|
const converted = {
|
||||||
|
id,
|
||||||
|
guid,
|
||||||
|
method,
|
||||||
|
params
|
||||||
|
};
|
||||||
|
// Do not include metadata in debug logs to avoid noise.
|
||||||
|
_debugLogger.debugLogger.log('channel:command', converted);
|
||||||
|
const location = frames[0] ? {
|
||||||
|
file: frames[0].file,
|
||||||
|
line: frames[0].line,
|
||||||
|
column: frames[0].column
|
||||||
|
} : undefined;
|
||||||
|
const metadata = {
|
||||||
|
wallTime,
|
||||||
|
apiName,
|
||||||
|
location,
|
||||||
|
internal: !apiName
|
||||||
|
};
|
||||||
|
this.onmessage({
|
||||||
|
...converted,
|
||||||
|
metadata
|
||||||
|
});
|
||||||
|
if (this._tracingCount && frames && type !== 'LocalUtils') (_this$_localUtils = this._localUtils) === null || _this$_localUtils === void 0 ? void 0 : _this$_localUtils._channel.addStackToTracingNoReply({
|
||||||
|
callData: {
|
||||||
|
stack: frames,
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
return await new Promise((resolve, reject) => this._callbacks.set(id, {
|
||||||
|
resolve,
|
||||||
|
reject,
|
||||||
|
stackTrace,
|
||||||
|
type,
|
||||||
|
method
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
dispatch(message) {
|
||||||
|
if (this._closedErrorMessage) return;
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
guid,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
result,
|
||||||
|
error
|
||||||
|
} = message;
|
||||||
|
if (id) {
|
||||||
|
_debugLogger.debugLogger.log('channel:response', message);
|
||||||
|
const callback = this._callbacks.get(id);
|
||||||
|
if (!callback) throw new Error(`Cannot find command to respond: ${id}`);
|
||||||
|
this._callbacks.delete(id);
|
||||||
|
if (error && !result) {
|
||||||
|
callback.reject((0, _serializers.parseError)(error));
|
||||||
|
} else {
|
||||||
|
const validator = (0, _validator.findValidator)(callback.type, callback.method, 'Result');
|
||||||
|
callback.resolve(validator(result, '', {
|
||||||
|
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||||
|
binary: this.isRemote() ? 'fromBase64' : 'buffer'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_debugLogger.debugLogger.log('channel:event', message);
|
||||||
|
if (method === '__create__') {
|
||||||
|
this._createRemoteObject(guid, params.type, params.guid, params.initializer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const object = this._objects.get(guid);
|
||||||
|
if (!object) throw new Error(`Cannot find object to "${method}": ${guid}`);
|
||||||
|
if (method === '__adopt__') {
|
||||||
|
const child = this._objects.get(params.guid);
|
||||||
|
if (!child) throw new Error(`Unknown new child: ${params.guid}`);
|
||||||
|
object._adopt(child);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (method === '__dispose__') {
|
||||||
|
object._dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const validator = (0, _validator.findValidator)(object._type, method, 'Event');
|
||||||
|
object._channel.emit(method, validator(params, '', {
|
||||||
|
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||||
|
binary: this.isRemote() ? 'fromBase64' : 'buffer'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
close(errorMessage = 'Connection closed') {
|
||||||
|
const stack = (0, _stackTrace.captureLibraryStackTrace)().frameTexts.join('\n');
|
||||||
|
if (stack) errorMessage += '\n ==== Closed by ====\n' + stack + '\n';
|
||||||
|
this._closedErrorMessage = errorMessage;
|
||||||
|
for (const callback of this._callbacks.values()) callback.reject(new Error(errorMessage));
|
||||||
|
this._callbacks.clear();
|
||||||
|
this.emit('close');
|
||||||
|
}
|
||||||
|
_tChannelImplFromWire(names, arg, path, context) {
|
||||||
|
if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {
|
||||||
|
const object = this._objects.get(arg.guid);
|
||||||
|
if (!object) throw new Error(`Object with guid ${arg.guid} was not bound in the connection`);
|
||||||
|
if (names !== '*' && !names.includes(object._type)) throw new _validator.ValidationError(`${path}: expected channel ${names.toString()}`);
|
||||||
|
return object._channel;
|
||||||
|
}
|
||||||
|
throw new _validator.ValidationError(`${path}: expected channel ${names.toString()}`);
|
||||||
|
}
|
||||||
|
_createRemoteObject(parentGuid, type, guid, initializer) {
|
||||||
|
const parent = this._objects.get(parentGuid);
|
||||||
|
if (!parent) throw new Error(`Cannot find parent object ${parentGuid} to create ${guid}`);
|
||||||
|
let result;
|
||||||
|
const validator = (0, _validator.findValidator)(type, '', 'Initializer');
|
||||||
|
initializer = validator(initializer, '', {
|
||||||
|
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||||
|
binary: this.isRemote() ? 'fromBase64' : 'buffer'
|
||||||
|
});
|
||||||
|
switch (type) {
|
||||||
|
case 'Android':
|
||||||
|
result = new _android.Android(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'AndroidSocket':
|
||||||
|
result = new _android.AndroidSocket(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'AndroidDevice':
|
||||||
|
result = new _android.AndroidDevice(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'APIRequestContext':
|
||||||
|
result = new _fetch.APIRequestContext(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Artifact':
|
||||||
|
result = new _artifact.Artifact(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'BindingCall':
|
||||||
|
result = new _page.BindingCall(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Browser':
|
||||||
|
result = new _browser.Browser(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'BrowserContext':
|
||||||
|
result = new _browserContext.BrowserContext(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'BrowserType':
|
||||||
|
result = new _browserType.BrowserType(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'CDPSession':
|
||||||
|
result = new _cdpSession.CDPSession(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'ConsoleMessage':
|
||||||
|
result = new _consoleMessage.ConsoleMessage(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Dialog':
|
||||||
|
result = new _dialog.Dialog(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Electron':
|
||||||
|
result = new _electron.Electron(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'ElectronApplication':
|
||||||
|
result = new _electron.ElectronApplication(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'ElementHandle':
|
||||||
|
result = new _elementHandle.ElementHandle(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Frame':
|
||||||
|
result = new _frame.Frame(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'JSHandle':
|
||||||
|
result = new _jsHandle.JSHandle(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'JsonPipe':
|
||||||
|
result = new _jsonPipe.JsonPipe(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'LocalUtils':
|
||||||
|
result = new _localUtils.LocalUtils(parent, type, guid, initializer);
|
||||||
|
if (!this._localUtils) this._localUtils = result;
|
||||||
|
break;
|
||||||
|
case 'Page':
|
||||||
|
result = new _page.Page(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Playwright':
|
||||||
|
result = new _playwright.Playwright(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Request':
|
||||||
|
result = new _network.Request(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Response':
|
||||||
|
result = new _network.Response(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Route':
|
||||||
|
result = new _network.Route(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Stream':
|
||||||
|
result = new _stream.Stream(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Selectors':
|
||||||
|
result = new _selectors.SelectorsOwner(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'SocksSupport':
|
||||||
|
result = new DummyChannelOwner(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Tracing':
|
||||||
|
result = new _tracing.Tracing(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'WebSocket':
|
||||||
|
result = new _network.WebSocket(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'Worker':
|
||||||
|
result = new _worker.Worker(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
case 'WritableStream':
|
||||||
|
result = new _writableStream.WritableStream(parent, type, guid, initializer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Missing type ' + type);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Connection = Connection;
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.ConsoleMessage = void 0;
|
||||||
|
var util = _interopRequireWildcard(require("util"));
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _page = require("./page");
|
||||||
|
let _util$inspect$custom;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
_util$inspect$custom = util.inspect.custom;
|
||||||
|
class ConsoleMessage extends _channelOwner.ChannelOwner {
|
||||||
|
static from(message) {
|
||||||
|
return message._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
// Note: currently, we only report console messages for pages and they always have a page.
|
||||||
|
// However, in the future we might report console messages for service workers or something else,
|
||||||
|
// where page() would be null.
|
||||||
|
this._page = void 0;
|
||||||
|
this._page = _page.Page.fromNullable(initializer.page);
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._page;
|
||||||
|
}
|
||||||
|
type() {
|
||||||
|
return this._initializer.type;
|
||||||
|
}
|
||||||
|
text() {
|
||||||
|
return this._initializer.text;
|
||||||
|
}
|
||||||
|
args() {
|
||||||
|
return this._initializer.args.map(_jsHandle.JSHandle.from);
|
||||||
|
}
|
||||||
|
location() {
|
||||||
|
return this._initializer.location;
|
||||||
|
}
|
||||||
|
[_util$inspect$custom]() {
|
||||||
|
return this.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ConsoleMessage = ConsoleMessage;
|
||||||
41
bin/pac/tools/.playwright/package/lib/client/coverage.js
Normal file
41
bin/pac/tools/.playwright/package/lib/client/coverage.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Coverage = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Coverage {
|
||||||
|
constructor(channel) {
|
||||||
|
this._channel = void 0;
|
||||||
|
this._channel = channel;
|
||||||
|
}
|
||||||
|
async startJSCoverage(options = {}) {
|
||||||
|
await this._channel.startJSCoverage(options);
|
||||||
|
}
|
||||||
|
async stopJSCoverage() {
|
||||||
|
return (await this._channel.stopJSCoverage()).entries;
|
||||||
|
}
|
||||||
|
async startCSSCoverage(options = {}) {
|
||||||
|
await this._channel.startCSSCoverage(options);
|
||||||
|
}
|
||||||
|
async stopCSSCoverage() {
|
||||||
|
return (await this._channel.stopCSSCoverage()).entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Coverage = Coverage;
|
||||||
57
bin/pac/tools/.playwright/package/lib/client/dialog.js
Normal file
57
bin/pac/tools/.playwright/package/lib/client/dialog.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Dialog = void 0;
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _page = require("./page");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Dialog extends _channelOwner.ChannelOwner {
|
||||||
|
static from(dialog) {
|
||||||
|
return dialog._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
// Note: dialogs that open early during page initialization block it.
|
||||||
|
// Therefore, we must report the dialog without a page to be able to handle it.
|
||||||
|
this._page = void 0;
|
||||||
|
this._page = _page.Page.fromNullable(initializer.page);
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._page;
|
||||||
|
}
|
||||||
|
type() {
|
||||||
|
return this._initializer.type;
|
||||||
|
}
|
||||||
|
message() {
|
||||||
|
return this._initializer.message;
|
||||||
|
}
|
||||||
|
defaultValue() {
|
||||||
|
return this._initializer.defaultValue;
|
||||||
|
}
|
||||||
|
async accept(promptText) {
|
||||||
|
await this._channel.accept({
|
||||||
|
promptText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dismiss() {
|
||||||
|
await this._channel.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Dialog = Dialog;
|
||||||
62
bin/pac/tools/.playwright/package/lib/client/download.js
Normal file
62
bin/pac/tools/.playwright/package/lib/client/download.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Download = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Download {
|
||||||
|
constructor(page, url, suggestedFilename, artifact) {
|
||||||
|
this._page = void 0;
|
||||||
|
this._url = void 0;
|
||||||
|
this._suggestedFilename = void 0;
|
||||||
|
this._artifact = void 0;
|
||||||
|
this._page = page;
|
||||||
|
this._url = url;
|
||||||
|
this._suggestedFilename = suggestedFilename;
|
||||||
|
this._artifact = artifact;
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._page;
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._url;
|
||||||
|
}
|
||||||
|
suggestedFilename() {
|
||||||
|
return this._suggestedFilename;
|
||||||
|
}
|
||||||
|
async path() {
|
||||||
|
return this._artifact.pathAfterFinished();
|
||||||
|
}
|
||||||
|
async saveAs(path) {
|
||||||
|
return this._artifact.saveAs(path);
|
||||||
|
}
|
||||||
|
async failure() {
|
||||||
|
return this._artifact.failure();
|
||||||
|
}
|
||||||
|
async createReadStream() {
|
||||||
|
return this._artifact.createReadStream();
|
||||||
|
}
|
||||||
|
async cancel() {
|
||||||
|
return this._artifact.cancel();
|
||||||
|
}
|
||||||
|
async delete() {
|
||||||
|
return this._artifact.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Download = Download;
|
||||||
124
bin/pac/tools/.playwright/package/lib/client/electron.js
Normal file
124
bin/pac/tools/.playwright/package/lib/client/electron.js
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.ElectronApplication = exports.Electron = void 0;
|
||||||
|
var _timeoutSettings = require("../common/timeoutSettings");
|
||||||
|
var _browserContext = require("./browserContext");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _clientHelper = require("./clientHelper");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Electron extends _channelOwner.ChannelOwner {
|
||||||
|
static from(electron) {
|
||||||
|
return electron._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
async launch(options = {}) {
|
||||||
|
const params = {
|
||||||
|
...(await (0, _browserContext.prepareBrowserContextParams)(options)),
|
||||||
|
env: (0, _clientHelper.envObjectToArray)(options.env ? options.env : process.env)
|
||||||
|
};
|
||||||
|
const app = ElectronApplication.from((await this._channel.launch(params)).electronApplication);
|
||||||
|
app._context._options = params;
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Electron = Electron;
|
||||||
|
class ElectronApplication extends _channelOwner.ChannelOwner {
|
||||||
|
static from(electronApplication) {
|
||||||
|
return electronApplication._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._context = void 0;
|
||||||
|
this._windows = new Set();
|
||||||
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings();
|
||||||
|
this._isClosed = false;
|
||||||
|
this._context = _browserContext.BrowserContext.from(initializer.context);
|
||||||
|
for (const page of this._context._pages) this._onPage(page);
|
||||||
|
this._context.on(_events.Events.BrowserContext.Page, page => this._onPage(page));
|
||||||
|
this._channel.on('close', () => {
|
||||||
|
this._isClosed = true;
|
||||||
|
this.emit(_events.Events.ElectronApplication.Close);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
process() {
|
||||||
|
return this._toImpl().process();
|
||||||
|
}
|
||||||
|
_onPage(page) {
|
||||||
|
this._windows.add(page);
|
||||||
|
this.emit(_events.Events.ElectronApplication.Window, page);
|
||||||
|
page.once(_events.Events.Page.Close, () => this._windows.delete(page));
|
||||||
|
}
|
||||||
|
windows() {
|
||||||
|
// TODO: add ElectronPage class inherting from Page.
|
||||||
|
return [...this._windows];
|
||||||
|
}
|
||||||
|
async firstWindow(options) {
|
||||||
|
if (this._windows.size) return this._windows.values().next().value;
|
||||||
|
return this.waitForEvent('window', options);
|
||||||
|
}
|
||||||
|
context() {
|
||||||
|
return this._context;
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
if (this._isClosed) return;
|
||||||
|
await this._channel.close().catch(() => {});
|
||||||
|
}
|
||||||
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||||
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||||
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||||
|
if (event !== _events.Events.ElectronApplication.Close) waiter.rejectOnEvent(this, _events.Events.ElectronApplication.Close, new Error('Electron application closed'));
|
||||||
|
const result = await waiter.waitForEvent(this, event, predicate);
|
||||||
|
waiter.dispose();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async browserWindow(page) {
|
||||||
|
const result = await this._channel.browserWindow({
|
||||||
|
page: page._channel
|
||||||
|
});
|
||||||
|
return _jsHandle.JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg) {
|
||||||
|
const result = await this._channel.evaluateExpression({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg) {
|
||||||
|
const result = await this._channel.evaluateExpressionHandle({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return _jsHandle.JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ElectronApplication = ElectronApplication;
|
||||||
312
bin/pac/tools/.playwright/package/lib/client/elementHandle.js
Normal file
312
bin/pac/tools/.playwright/package/lib/client/elementHandle.js
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.ElementHandle = void 0;
|
||||||
|
exports.convertInputFiles = convertInputFiles;
|
||||||
|
exports.convertSelectOptionValues = convertSelectOptionValues;
|
||||||
|
exports.determineScreenshotType = determineScreenshotType;
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _utilsBundle = require("../utilsBundle");
|
||||||
|
var _path = _interopRequireDefault(require("path"));
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _fileUtils = require("../utils/fileUtils");
|
||||||
|
var _writableStream = require("./writableStream");
|
||||||
|
var _stream = require("stream");
|
||||||
|
var _util = require("util");
|
||||||
|
var _debugLogger = require("../common/debugLogger");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const pipelineAsync = (0, _util.promisify)(_stream.pipeline);
|
||||||
|
class ElementHandle extends _jsHandle.JSHandle {
|
||||||
|
static from(handle) {
|
||||||
|
return handle._object;
|
||||||
|
}
|
||||||
|
static fromNullable(handle) {
|
||||||
|
return handle ? ElementHandle.from(handle) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._elementChannel = void 0;
|
||||||
|
this._elementChannel = this._channel;
|
||||||
|
}
|
||||||
|
asElement() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
async ownerFrame() {
|
||||||
|
return _frame.Frame.fromNullable((await this._elementChannel.ownerFrame()).frame);
|
||||||
|
}
|
||||||
|
async contentFrame() {
|
||||||
|
return _frame.Frame.fromNullable((await this._elementChannel.contentFrame()).frame);
|
||||||
|
}
|
||||||
|
async getAttribute(name) {
|
||||||
|
const value = (await this._elementChannel.getAttribute({
|
||||||
|
name
|
||||||
|
})).value;
|
||||||
|
return value === undefined ? null : value;
|
||||||
|
}
|
||||||
|
async inputValue() {
|
||||||
|
return (await this._elementChannel.inputValue()).value;
|
||||||
|
}
|
||||||
|
async textContent() {
|
||||||
|
const value = (await this._elementChannel.textContent()).value;
|
||||||
|
return value === undefined ? null : value;
|
||||||
|
}
|
||||||
|
async innerText() {
|
||||||
|
return (await this._elementChannel.innerText()).value;
|
||||||
|
}
|
||||||
|
async innerHTML() {
|
||||||
|
return (await this._elementChannel.innerHTML()).value;
|
||||||
|
}
|
||||||
|
async isChecked() {
|
||||||
|
return (await this._elementChannel.isChecked()).value;
|
||||||
|
}
|
||||||
|
async isDisabled() {
|
||||||
|
return (await this._elementChannel.isDisabled()).value;
|
||||||
|
}
|
||||||
|
async isEditable() {
|
||||||
|
return (await this._elementChannel.isEditable()).value;
|
||||||
|
}
|
||||||
|
async isEnabled() {
|
||||||
|
return (await this._elementChannel.isEnabled()).value;
|
||||||
|
}
|
||||||
|
async isHidden() {
|
||||||
|
return (await this._elementChannel.isHidden()).value;
|
||||||
|
}
|
||||||
|
async isVisible() {
|
||||||
|
return (await this._elementChannel.isVisible()).value;
|
||||||
|
}
|
||||||
|
async dispatchEvent(type, eventInit = {}) {
|
||||||
|
await this._elementChannel.dispatchEvent({
|
||||||
|
type,
|
||||||
|
eventInit: (0, _jsHandle.serializeArgument)(eventInit)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async scrollIntoViewIfNeeded(options = {}) {
|
||||||
|
await this._elementChannel.scrollIntoViewIfNeeded(options);
|
||||||
|
}
|
||||||
|
async hover(options = {}) {
|
||||||
|
await this._elementChannel.hover(options);
|
||||||
|
}
|
||||||
|
async click(options = {}) {
|
||||||
|
return await this._elementChannel.click(options);
|
||||||
|
}
|
||||||
|
async dblclick(options = {}) {
|
||||||
|
return await this._elementChannel.dblclick(options);
|
||||||
|
}
|
||||||
|
async tap(options = {}) {
|
||||||
|
return await this._elementChannel.tap(options);
|
||||||
|
}
|
||||||
|
async selectOption(values, options = {}) {
|
||||||
|
const result = await this._elementChannel.selectOption({
|
||||||
|
...convertSelectOptionValues(values),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
return result.values;
|
||||||
|
}
|
||||||
|
async fill(value, options = {}) {
|
||||||
|
return await this._elementChannel.fill({
|
||||||
|
value,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async selectText(options = {}) {
|
||||||
|
await this._elementChannel.selectText(options);
|
||||||
|
}
|
||||||
|
async setInputFiles(files, options = {}) {
|
||||||
|
const frame = await this.ownerFrame();
|
||||||
|
if (!frame) throw new Error('Cannot set input files to detached element');
|
||||||
|
const converted = await convertInputFiles(files, frame.page().context());
|
||||||
|
if (converted.files) {
|
||||||
|
await this._elementChannel.setInputFiles({
|
||||||
|
files: converted.files,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_debugLogger.debugLogger.log('api', 'switching to large files mode');
|
||||||
|
await this._elementChannel.setInputFilePaths({
|
||||||
|
...converted,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async focus() {
|
||||||
|
await this._elementChannel.focus();
|
||||||
|
}
|
||||||
|
async type(text, options = {}) {
|
||||||
|
await this._elementChannel.type({
|
||||||
|
text,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(key, options = {}) {
|
||||||
|
await this._elementChannel.press({
|
||||||
|
key,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async check(options = {}) {
|
||||||
|
return await this._elementChannel.check(options);
|
||||||
|
}
|
||||||
|
async uncheck(options = {}) {
|
||||||
|
return await this._elementChannel.uncheck(options);
|
||||||
|
}
|
||||||
|
async setChecked(checked, options) {
|
||||||
|
if (checked) await this.check(options);else await this.uncheck(options);
|
||||||
|
}
|
||||||
|
async boundingBox() {
|
||||||
|
const value = (await this._elementChannel.boundingBox()).value;
|
||||||
|
return value === undefined ? null : value;
|
||||||
|
}
|
||||||
|
async screenshot(options = {}) {
|
||||||
|
const copy = {
|
||||||
|
...options,
|
||||||
|
mask: undefined
|
||||||
|
};
|
||||||
|
if (!copy.type) copy.type = determineScreenshotType(options);
|
||||||
|
if (options.mask) {
|
||||||
|
copy.mask = options.mask.map(locator => ({
|
||||||
|
frame: locator._frame._channel,
|
||||||
|
selector: locator._selector
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const result = await this._elementChannel.screenshot(copy);
|
||||||
|
if (options.path) {
|
||||||
|
await (0, _fileUtils.mkdirIfNeeded)(options.path);
|
||||||
|
await _fs.default.promises.writeFile(options.path, result.binary);
|
||||||
|
}
|
||||||
|
return result.binary;
|
||||||
|
}
|
||||||
|
async $(selector) {
|
||||||
|
return ElementHandle.fromNullable((await this._elementChannel.querySelector({
|
||||||
|
selector
|
||||||
|
})).element);
|
||||||
|
}
|
||||||
|
async $$(selector) {
|
||||||
|
const result = await this._elementChannel.querySelectorAll({
|
||||||
|
selector
|
||||||
|
});
|
||||||
|
return result.elements.map(h => ElementHandle.from(h));
|
||||||
|
}
|
||||||
|
async $eval(selector, pageFunction, arg) {
|
||||||
|
const result = await this._elementChannel.evalOnSelector({
|
||||||
|
selector,
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async $$eval(selector, pageFunction, arg) {
|
||||||
|
const result = await this._elementChannel.evalOnSelectorAll({
|
||||||
|
selector,
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async waitForElementState(state, options = {}) {
|
||||||
|
return await this._elementChannel.waitForElementState({
|
||||||
|
state,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForSelector(selector, options = {}) {
|
||||||
|
const result = await this._elementChannel.waitForSelector({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
return ElementHandle.fromNullable(result.element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ElementHandle = ElementHandle;
|
||||||
|
function convertSelectOptionValues(values) {
|
||||||
|
if (values === null) return {};
|
||||||
|
if (!Array.isArray(values)) values = [values];
|
||||||
|
if (!values.length) return {};
|
||||||
|
for (let i = 0; i < values.length; i++) (0, _utils.assert)(values[i] !== null, `options[${i}]: expected object, got null`);
|
||||||
|
if (values[0] instanceof ElementHandle) return {
|
||||||
|
elements: values.map(v => v._elementChannel)
|
||||||
|
};
|
||||||
|
if ((0, _utils.isString)(values[0])) return {
|
||||||
|
options: values.map(valueOrLabel => ({
|
||||||
|
valueOrLabel
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
options: values
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function convertInputFiles(files, context) {
|
||||||
|
const items = Array.isArray(files) ? files.slice() : [files];
|
||||||
|
const sizeLimit = 50 * 1024 * 1024;
|
||||||
|
const totalBufferSizeExceedsLimit = items.reduce((size, item) => size + (typeof item === 'object' && item.buffer ? item.buffer.byteLength : 0), 0) > sizeLimit;
|
||||||
|
if (totalBufferSizeExceedsLimit) throw new Error('Cannot set buffer larger than 50Mb, please write it to a file and pass its path instead.');
|
||||||
|
const stats = await Promise.all(items.filter(_utils.isString).map(item => _fs.default.promises.stat(item)));
|
||||||
|
const totalFileSizeExceedsLimit = stats.reduce((acc, stat) => acc + stat.size, 0) > sizeLimit;
|
||||||
|
if (totalFileSizeExceedsLimit) {
|
||||||
|
if (context._connection.isRemote()) {
|
||||||
|
const streams = await Promise.all(items.map(async item => {
|
||||||
|
(0, _utils.assert)((0, _utils.isString)(item));
|
||||||
|
const {
|
||||||
|
writableStream: stream
|
||||||
|
} = await context._channel.createTempFile({
|
||||||
|
name: _path.default.basename(item)
|
||||||
|
});
|
||||||
|
const writable = _writableStream.WritableStream.from(stream);
|
||||||
|
await pipelineAsync(_fs.default.createReadStream(item), writable.stream());
|
||||||
|
return stream;
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
streams
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
localPaths: items.map(f => _path.default.resolve(f))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const filePayloads = await Promise.all(items.map(async item => {
|
||||||
|
if (typeof item === 'string') {
|
||||||
|
return {
|
||||||
|
name: _path.default.basename(item),
|
||||||
|
buffer: await _fs.default.promises.readFile(item)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
mimeType: item.mimeType,
|
||||||
|
buffer: item.buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
files: filePayloads
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function determineScreenshotType(options) {
|
||||||
|
if (options.path) {
|
||||||
|
const mimeType = _utilsBundle.mime.getType(options.path);
|
||||||
|
if (mimeType === 'image/png') return 'png';else if (mimeType === 'image/jpeg') return 'jpeg';
|
||||||
|
throw new Error(`path: unsupported mime type "${mimeType}"`);
|
||||||
|
}
|
||||||
|
return options.type;
|
||||||
|
}
|
||||||
91
bin/pac/tools/.playwright/package/lib/client/events.js
Normal file
91
bin/pac/tools/.playwright/package/lib/client/events.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Events = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright 2019 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Events = {
|
||||||
|
AndroidDevice: {
|
||||||
|
WebView: 'webview',
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
AndroidSocket: {
|
||||||
|
Data: 'data',
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
AndroidWebView: {
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
Browser: {
|
||||||
|
Disconnected: 'disconnected'
|
||||||
|
},
|
||||||
|
BrowserContext: {
|
||||||
|
Console: 'console',
|
||||||
|
Close: 'close',
|
||||||
|
Dialog: 'dialog',
|
||||||
|
Page: 'page',
|
||||||
|
BackgroundPage: 'backgroundpage',
|
||||||
|
ServiceWorker: 'serviceworker',
|
||||||
|
Request: 'request',
|
||||||
|
Response: 'response',
|
||||||
|
RequestFailed: 'requestfailed',
|
||||||
|
RequestFinished: 'requestfinished'
|
||||||
|
},
|
||||||
|
BrowserServer: {
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
Page: {
|
||||||
|
Close: 'close',
|
||||||
|
Crash: 'crash',
|
||||||
|
Console: 'console',
|
||||||
|
Dialog: 'dialog',
|
||||||
|
Download: 'download',
|
||||||
|
FileChooser: 'filechooser',
|
||||||
|
DOMContentLoaded: 'domcontentloaded',
|
||||||
|
// Can't use just 'error' due to node.js special treatment of error events.
|
||||||
|
// @see https://nodejs.org/api/events.html#events_error_events
|
||||||
|
PageError: 'pageerror',
|
||||||
|
Request: 'request',
|
||||||
|
Response: 'response',
|
||||||
|
RequestFailed: 'requestfailed',
|
||||||
|
RequestFinished: 'requestfinished',
|
||||||
|
FrameAttached: 'frameattached',
|
||||||
|
FrameDetached: 'framedetached',
|
||||||
|
FrameNavigated: 'framenavigated',
|
||||||
|
Load: 'load',
|
||||||
|
Popup: 'popup',
|
||||||
|
WebSocket: 'websocket',
|
||||||
|
Worker: 'worker'
|
||||||
|
},
|
||||||
|
WebSocket: {
|
||||||
|
Close: 'close',
|
||||||
|
Error: 'socketerror',
|
||||||
|
FrameReceived: 'framereceived',
|
||||||
|
FrameSent: 'framesent'
|
||||||
|
},
|
||||||
|
Worker: {
|
||||||
|
Close: 'close'
|
||||||
|
},
|
||||||
|
ElectronApplication: {
|
||||||
|
Close: 'close',
|
||||||
|
Window: 'window'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.Events = Events;
|
||||||
327
bin/pac/tools/.playwright/package/lib/client/fetch.js
Normal file
327
bin/pac/tools/.playwright/package/lib/client/fetch.js
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.APIResponse = exports.APIRequestContext = exports.APIRequest = void 0;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _path = _interopRequireDefault(require("path"));
|
||||||
|
var util = _interopRequireWildcard(require("util"));
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _fileUtils = require("../utils/fileUtils");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _network = require("./network");
|
||||||
|
var _tracing = require("./tracing");
|
||||||
|
let _util$inspect$custom;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
class APIRequest {
|
||||||
|
// Instrumentation.
|
||||||
|
|
||||||
|
constructor(playwright) {
|
||||||
|
this._playwright = void 0;
|
||||||
|
this._contexts = new Set();
|
||||||
|
this._defaultContextOptions = void 0;
|
||||||
|
this._playwright = playwright;
|
||||||
|
}
|
||||||
|
async newContext(options = {}) {
|
||||||
|
var _this$_defaultContext;
|
||||||
|
options = {
|
||||||
|
...this._defaultContextOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
const storageState = typeof options.storageState === 'string' ? JSON.parse(await _fs.default.promises.readFile(options.storageState, 'utf8')) : options.storageState;
|
||||||
|
// We do not expose tracesDir in the API, so do not allow options to accidentally override it.
|
||||||
|
const tracesDir = (_this$_defaultContext = this._defaultContextOptions) === null || _this$_defaultContext === void 0 ? void 0 : _this$_defaultContext.tracesDir;
|
||||||
|
const context = APIRequestContext.from((await this._playwright._channel.newRequest({
|
||||||
|
...options,
|
||||||
|
extraHTTPHeaders: options.extraHTTPHeaders ? (0, _utils.headersObjectToArray)(options.extraHTTPHeaders) : undefined,
|
||||||
|
storageState,
|
||||||
|
tracesDir
|
||||||
|
})).request);
|
||||||
|
this._contexts.add(context);
|
||||||
|
context._request = this;
|
||||||
|
context._tracing._tracesDir = tracesDir;
|
||||||
|
await context._instrumentation.onDidCreateRequestContext(context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.APIRequest = APIRequest;
|
||||||
|
class APIRequestContext extends _channelOwner.ChannelOwner {
|
||||||
|
static from(channel) {
|
||||||
|
return channel._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._request = void 0;
|
||||||
|
this._tracing = void 0;
|
||||||
|
this._tracing = _tracing.Tracing.from(initializer.tracing);
|
||||||
|
}
|
||||||
|
async dispose() {
|
||||||
|
var _this$_request;
|
||||||
|
await this._instrumentation.onWillCloseRequestContext(this);
|
||||||
|
await this._channel.dispose();
|
||||||
|
(_this$_request = this._request) === null || _this$_request === void 0 ? void 0 : _this$_request._contexts.delete(this);
|
||||||
|
}
|
||||||
|
async delete(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async head(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'HEAD'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async get(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'GET'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async patch(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async post(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async put(url, options) {
|
||||||
|
return this.fetch(url, {
|
||||||
|
...options,
|
||||||
|
method: 'PUT'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async fetch(urlOrRequest, options = {}) {
|
||||||
|
const url = (0, _utils.isString)(urlOrRequest) ? urlOrRequest : undefined;
|
||||||
|
const request = (0, _utils.isString)(urlOrRequest) ? undefined : urlOrRequest;
|
||||||
|
return this._innerFetch({
|
||||||
|
url,
|
||||||
|
request,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _innerFetch(options = {}) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
var _options$request, _options$request2, _options$request3;
|
||||||
|
(0, _utils.assert)(options.request || typeof options.url === 'string', 'First argument must be either URL string or Request');
|
||||||
|
(0, _utils.assert)((options.data === undefined ? 0 : 1) + (options.form === undefined ? 0 : 1) + (options.multipart === undefined ? 0 : 1) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`);
|
||||||
|
(0, _utils.assert)(options.maxRedirects === undefined || options.maxRedirects >= 0, `'maxRedirects' should be greater than or equal to '0'`);
|
||||||
|
const url = options.url !== undefined ? options.url : options.request.url();
|
||||||
|
const params = objectToArray(options.params);
|
||||||
|
const method = options.method || ((_options$request = options.request) === null || _options$request === void 0 ? void 0 : _options$request.method());
|
||||||
|
const maxRedirects = options.maxRedirects;
|
||||||
|
// Cannot call allHeaders() here as the request may be paused inside route handler.
|
||||||
|
const headersObj = options.headers || ((_options$request2 = options.request) === null || _options$request2 === void 0 ? void 0 : _options$request2.headers());
|
||||||
|
const headers = headersObj ? (0, _utils.headersObjectToArray)(headersObj) : undefined;
|
||||||
|
let jsonData;
|
||||||
|
let formData;
|
||||||
|
let multipartData;
|
||||||
|
let postDataBuffer;
|
||||||
|
if (options.data !== undefined) {
|
||||||
|
if ((0, _utils.isString)(options.data)) {
|
||||||
|
if (isJsonContentType(headers)) jsonData = options.data;else postDataBuffer = Buffer.from(options.data, 'utf8');
|
||||||
|
} else if (Buffer.isBuffer(options.data)) {
|
||||||
|
postDataBuffer = options.data;
|
||||||
|
} else if (typeof options.data === 'object' || typeof options.data === 'number' || typeof options.data === 'boolean') {
|
||||||
|
jsonData = options.data;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unexpected 'data' type`);
|
||||||
|
}
|
||||||
|
} else if (options.form) {
|
||||||
|
formData = objectToArray(options.form);
|
||||||
|
} else if (options.multipart) {
|
||||||
|
multipartData = [];
|
||||||
|
// Convert file-like values to ServerFilePayload structs.
|
||||||
|
for (const [name, value] of Object.entries(options.multipart)) {
|
||||||
|
if (isFilePayload(value)) {
|
||||||
|
const payload = value;
|
||||||
|
if (!Buffer.isBuffer(payload.buffer)) throw new Error(`Unexpected buffer type of 'data.${name}'`);
|
||||||
|
multipartData.push({
|
||||||
|
name,
|
||||||
|
file: filePayloadToJson(payload)
|
||||||
|
});
|
||||||
|
} else if (value instanceof _fs.default.ReadStream) {
|
||||||
|
multipartData.push({
|
||||||
|
name,
|
||||||
|
file: await readStreamToJson(value)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
multipartData.push({
|
||||||
|
name,
|
||||||
|
value: String(value)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (postDataBuffer === undefined && jsonData === undefined && formData === undefined && multipartData === undefined) postDataBuffer = ((_options$request3 = options.request) === null || _options$request3 === void 0 ? void 0 : _options$request3.postDataBuffer()) || undefined;
|
||||||
|
const fixtures = {
|
||||||
|
__testHookLookup: options.__testHookLookup
|
||||||
|
};
|
||||||
|
const result = await this._channel.fetch({
|
||||||
|
url,
|
||||||
|
params,
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
postData: postDataBuffer,
|
||||||
|
jsonData,
|
||||||
|
formData,
|
||||||
|
multipartData,
|
||||||
|
timeout: options.timeout,
|
||||||
|
failOnStatusCode: options.failOnStatusCode,
|
||||||
|
ignoreHTTPSErrors: options.ignoreHTTPSErrors,
|
||||||
|
maxRedirects: maxRedirects,
|
||||||
|
...fixtures
|
||||||
|
});
|
||||||
|
return new APIResponse(this, result.response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async storageState(options = {}) {
|
||||||
|
const state = await this._channel.storageState();
|
||||||
|
if (options.path) {
|
||||||
|
await (0, _fileUtils.mkdirIfNeeded)(options.path);
|
||||||
|
await _fs.default.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.APIRequestContext = APIRequestContext;
|
||||||
|
_util$inspect$custom = util.inspect.custom;
|
||||||
|
class APIResponse {
|
||||||
|
constructor(context, initializer) {
|
||||||
|
this._initializer = void 0;
|
||||||
|
this._headers = void 0;
|
||||||
|
this._request = void 0;
|
||||||
|
this._request = context;
|
||||||
|
this._initializer = initializer;
|
||||||
|
this._headers = new _network.RawHeaders(this._initializer.headers);
|
||||||
|
}
|
||||||
|
ok() {
|
||||||
|
return this._initializer.status >= 200 && this._initializer.status <= 299;
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._initializer.url;
|
||||||
|
}
|
||||||
|
status() {
|
||||||
|
return this._initializer.status;
|
||||||
|
}
|
||||||
|
statusText() {
|
||||||
|
return this._initializer.statusText;
|
||||||
|
}
|
||||||
|
headers() {
|
||||||
|
return this._headers.headers();
|
||||||
|
}
|
||||||
|
headersArray() {
|
||||||
|
return this._headers.headersArray();
|
||||||
|
}
|
||||||
|
async body() {
|
||||||
|
try {
|
||||||
|
const result = await this._request._channel.fetchResponseBody({
|
||||||
|
fetchUid: this._fetchUid()
|
||||||
|
});
|
||||||
|
if (result.binary === undefined) throw new Error('Response has been disposed');
|
||||||
|
return result.binary;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.includes(_errors.kBrowserOrContextClosedError)) throw new Error('Response has been disposed');
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async text() {
|
||||||
|
const content = await this.body();
|
||||||
|
return content.toString('utf8');
|
||||||
|
}
|
||||||
|
async json() {
|
||||||
|
const content = await this.text();
|
||||||
|
return JSON.parse(content);
|
||||||
|
}
|
||||||
|
async dispose() {
|
||||||
|
await this._request._channel.disposeAPIResponse({
|
||||||
|
fetchUid: this._fetchUid()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
[_util$inspect$custom]() {
|
||||||
|
const headers = this.headersArray().map(({
|
||||||
|
name,
|
||||||
|
value
|
||||||
|
}) => ` ${name}: ${value}`);
|
||||||
|
return `APIResponse: ${this.status()} ${this.statusText()}\n${headers.join('\n')}`;
|
||||||
|
}
|
||||||
|
_fetchUid() {
|
||||||
|
return this._initializer.fetchUid;
|
||||||
|
}
|
||||||
|
async _fetchLog() {
|
||||||
|
const {
|
||||||
|
log
|
||||||
|
} = await this._request._channel.fetchLog({
|
||||||
|
fetchUid: this._fetchUid()
|
||||||
|
});
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.APIResponse = APIResponse;
|
||||||
|
function filePayloadToJson(payload) {
|
||||||
|
return {
|
||||||
|
name: payload.name,
|
||||||
|
mimeType: payload.mimeType,
|
||||||
|
buffer: payload.buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function readStreamToJson(stream) {
|
||||||
|
const buffer = await new Promise((resolve, reject) => {
|
||||||
|
const chunks = [];
|
||||||
|
stream.on('data', chunk => chunks.push(chunk));
|
||||||
|
stream.on('end', () => resolve(Buffer.concat(chunks)));
|
||||||
|
stream.on('error', err => reject(err));
|
||||||
|
});
|
||||||
|
const streamPath = Buffer.isBuffer(stream.path) ? stream.path.toString('utf8') : stream.path;
|
||||||
|
return {
|
||||||
|
name: _path.default.basename(streamPath),
|
||||||
|
buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function isJsonContentType(headers) {
|
||||||
|
if (!headers) return false;
|
||||||
|
for (const {
|
||||||
|
name,
|
||||||
|
value
|
||||||
|
} of headers) {
|
||||||
|
if (name.toLocaleLowerCase() === 'content-type') return value === 'application/json';
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function objectToArray(map) {
|
||||||
|
if (!map) return undefined;
|
||||||
|
const result = [];
|
||||||
|
for (const [name, value] of Object.entries(map)) result.push({
|
||||||
|
name,
|
||||||
|
value: String(value)
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
function isFilePayload(value) {
|
||||||
|
return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer'];
|
||||||
|
}
|
||||||
45
bin/pac/tools/.playwright/package/lib/client/fileChooser.js
Normal file
45
bin/pac/tools/.playwright/package/lib/client/fileChooser.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.FileChooser = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class FileChooser {
|
||||||
|
constructor(page, elementHandle, isMultiple) {
|
||||||
|
this._page = void 0;
|
||||||
|
this._elementHandle = void 0;
|
||||||
|
this._isMultiple = void 0;
|
||||||
|
this._page = page;
|
||||||
|
this._elementHandle = elementHandle;
|
||||||
|
this._isMultiple = isMultiple;
|
||||||
|
}
|
||||||
|
element() {
|
||||||
|
return this._elementHandle;
|
||||||
|
}
|
||||||
|
isMultiple() {
|
||||||
|
return this._isMultiple;
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._page;
|
||||||
|
}
|
||||||
|
async setFiles(files, options) {
|
||||||
|
return this._elementHandle.setInputFiles(files, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FileChooser = FileChooser;
|
||||||
515
bin/pac/tools/.playwright/package/lib/client/frame.js
Normal file
515
bin/pac/tools/.playwright/package/lib/client/frame.js
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Frame = void 0;
|
||||||
|
exports.verifyLoadState = verifyLoadState;
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _locator = require("./locator");
|
||||||
|
var _locatorUtils = require("../utils/isomorphic/locatorUtils");
|
||||||
|
var _elementHandle = require("./elementHandle");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var network = _interopRequireWildcard(require("./network"));
|
||||||
|
var _events = require("events");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
var _events2 = require("./events");
|
||||||
|
var _types = require("./types");
|
||||||
|
var _network2 = require("../utils/network");
|
||||||
|
var _debugLogger = require("../common/debugLogger");
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Frame extends _channelOwner.ChannelOwner {
|
||||||
|
static from(frame) {
|
||||||
|
return frame._object;
|
||||||
|
}
|
||||||
|
static fromNullable(frame) {
|
||||||
|
return frame ? Frame.from(frame) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._eventEmitter = void 0;
|
||||||
|
this._loadStates = void 0;
|
||||||
|
this._parentFrame = null;
|
||||||
|
this._url = '';
|
||||||
|
this._name = '';
|
||||||
|
this._detached = false;
|
||||||
|
this._childFrames = new Set();
|
||||||
|
this._page = void 0;
|
||||||
|
this._eventEmitter = new _events.EventEmitter();
|
||||||
|
this._eventEmitter.setMaxListeners(0);
|
||||||
|
this._parentFrame = Frame.fromNullable(initializer.parentFrame);
|
||||||
|
if (this._parentFrame) this._parentFrame._childFrames.add(this);
|
||||||
|
this._name = initializer.name;
|
||||||
|
this._url = initializer.url;
|
||||||
|
this._loadStates = new Set(initializer.loadStates);
|
||||||
|
this._channel.on('loadstate', event => {
|
||||||
|
if (event.add) {
|
||||||
|
this._loadStates.add(event.add);
|
||||||
|
this._eventEmitter.emit('loadstate', event.add);
|
||||||
|
}
|
||||||
|
if (event.remove) this._loadStates.delete(event.remove);
|
||||||
|
if (!this._parentFrame && event.add === 'load' && this._page) this._page.emit(_events2.Events.Page.Load, this._page);
|
||||||
|
if (!this._parentFrame && event.add === 'domcontentloaded' && this._page) this._page.emit(_events2.Events.Page.DOMContentLoaded, this._page);
|
||||||
|
});
|
||||||
|
this._channel.on('navigated', event => {
|
||||||
|
this._url = event.url;
|
||||||
|
this._name = event.name;
|
||||||
|
this._eventEmitter.emit('navigated', event);
|
||||||
|
if (!event.error && this._page) this._page.emit(_events2.Events.Page.FrameNavigated, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._page;
|
||||||
|
}
|
||||||
|
async goto(url, options = {}) {
|
||||||
|
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
return network.Response.fromNullable((await this._channel.goto({
|
||||||
|
url,
|
||||||
|
...options,
|
||||||
|
waitUntil
|
||||||
|
})).response);
|
||||||
|
}
|
||||||
|
_setupNavigationWaiter(options) {
|
||||||
|
const waiter = new _waiter.Waiter(this._page, '');
|
||||||
|
if (this._page.isClosed()) waiter.rejectImmediately(new Error('Navigation failed because page was closed!'));
|
||||||
|
waiter.rejectOnEvent(this._page, _events2.Events.Page.Close, new Error('Navigation failed because page was closed!'));
|
||||||
|
waiter.rejectOnEvent(this._page, _events2.Events.Page.Crash, new Error('Navigation failed because page crashed!'));
|
||||||
|
waiter.rejectOnEvent(this._page, _events2.Events.Page.FrameDetached, new Error('Navigating frame was detached!'), frame => frame === this);
|
||||||
|
const timeout = this._page._timeoutSettings.navigationTimeout(options);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded.`);
|
||||||
|
return waiter;
|
||||||
|
}
|
||||||
|
async waitForNavigation(options = {}) {
|
||||||
|
return this._page._wrapApiCall(async () => {
|
||||||
|
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
const waiter = this._setupNavigationWaiter(options);
|
||||||
|
const toUrl = typeof options.url === 'string' ? ` to "${options.url}"` : '';
|
||||||
|
waiter.log(`waiting for navigation${toUrl} until "${waitUntil}"`);
|
||||||
|
const navigatedEvent = await waiter.waitForEvent(this._eventEmitter, 'navigated', event => {
|
||||||
|
var _this$_page;
|
||||||
|
// Any failed navigation results in a rejection.
|
||||||
|
if (event.error) return true;
|
||||||
|
waiter.log(` navigated to "${event.url}"`);
|
||||||
|
return (0, _network2.urlMatches)((_this$_page = this._page) === null || _this$_page === void 0 ? void 0 : _this$_page.context()._options.baseURL, event.url, options.url);
|
||||||
|
});
|
||||||
|
if (navigatedEvent.error) {
|
||||||
|
const e = new Error(navigatedEvent.error);
|
||||||
|
e.stack = '';
|
||||||
|
await waiter.waitForPromise(Promise.reject(e));
|
||||||
|
}
|
||||||
|
if (!this._loadStates.has(waitUntil)) {
|
||||||
|
await waiter.waitForEvent(this._eventEmitter, 'loadstate', s => {
|
||||||
|
waiter.log(` "${s}" event fired`);
|
||||||
|
return s === waitUntil;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const request = navigatedEvent.newDocument ? network.Request.fromNullable(navigatedEvent.newDocument.request) : null;
|
||||||
|
const response = request ? await waiter.waitForPromise(request._finalRequest()._internalResponse()) : null;
|
||||||
|
waiter.dispose();
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForLoadState(state = 'load', options = {}) {
|
||||||
|
state = verifyLoadState('state', state);
|
||||||
|
return this._page._wrapApiCall(async () => {
|
||||||
|
const waiter = this._setupNavigationWaiter(options);
|
||||||
|
if (this._loadStates.has(state)) {
|
||||||
|
waiter.log(` not waiting, "${state}" event already fired`);
|
||||||
|
} else {
|
||||||
|
await waiter.waitForEvent(this._eventEmitter, 'loadstate', s => {
|
||||||
|
waiter.log(` "${s}" event fired`);
|
||||||
|
return s === state;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
waiter.dispose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForURL(url, options = {}) {
|
||||||
|
var _this$_page2;
|
||||||
|
if ((0, _network2.urlMatches)((_this$_page2 = this._page) === null || _this$_page2 === void 0 ? void 0 : _this$_page2.context()._options.baseURL, this.url(), url)) return await this.waitForLoadState(options.waitUntil, options);
|
||||||
|
await this.waitForNavigation({
|
||||||
|
url,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async frameElement() {
|
||||||
|
return _elementHandle.ElementHandle.from((await this._channel.frameElement()).element);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
const result = await this._channel.evaluateExpressionHandle({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return _jsHandle.JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
const result = await this._channel.evaluateExpression({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async _evaluateExposeUtilityScript(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
const result = await this._channel.evaluateExpression({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
exposeUtilityScript: true,
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async $(selector, options) {
|
||||||
|
const result = await this._channel.querySelector({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
return _elementHandle.ElementHandle.fromNullable(result.element);
|
||||||
|
}
|
||||||
|
async waitForSelector(selector, options = {}) {
|
||||||
|
if (options.visibility) throw new Error('options.visibility is not supported, did you mean options.state?');
|
||||||
|
if (options.waitFor && options.waitFor !== 'visible') throw new Error('options.waitFor is not supported, did you mean options.state?');
|
||||||
|
const result = await this._channel.waitForSelector({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
return _elementHandle.ElementHandle.fromNullable(result.element);
|
||||||
|
}
|
||||||
|
async dispatchEvent(selector, type, eventInit, options = {}) {
|
||||||
|
await this._channel.dispatchEvent({
|
||||||
|
selector,
|
||||||
|
type,
|
||||||
|
eventInit: (0, _jsHandle.serializeArgument)(eventInit),
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async $eval(selector, pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
||||||
|
const result = await this._channel.evalOnSelector({
|
||||||
|
selector,
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async $$eval(selector, pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
||||||
|
const result = await this._channel.evalOnSelectorAll({
|
||||||
|
selector,
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async $$(selector) {
|
||||||
|
const result = await this._channel.querySelectorAll({
|
||||||
|
selector
|
||||||
|
});
|
||||||
|
return result.elements.map(e => _elementHandle.ElementHandle.from(e));
|
||||||
|
}
|
||||||
|
async _queryCount(selector) {
|
||||||
|
return (await this._channel.queryCount({
|
||||||
|
selector
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async content() {
|
||||||
|
return (await this._channel.content()).value;
|
||||||
|
}
|
||||||
|
async setContent(html, options = {}) {
|
||||||
|
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
await this._channel.setContent({
|
||||||
|
html,
|
||||||
|
...options,
|
||||||
|
waitUntil
|
||||||
|
});
|
||||||
|
}
|
||||||
|
name() {
|
||||||
|
return this._name || '';
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._url;
|
||||||
|
}
|
||||||
|
parentFrame() {
|
||||||
|
return this._parentFrame;
|
||||||
|
}
|
||||||
|
childFrames() {
|
||||||
|
return Array.from(this._childFrames);
|
||||||
|
}
|
||||||
|
isDetached() {
|
||||||
|
return this._detached;
|
||||||
|
}
|
||||||
|
async addScriptTag(options = {}) {
|
||||||
|
const copy = {
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
if (copy.path) {
|
||||||
|
copy.content = (await _fs.default.promises.readFile(copy.path)).toString();
|
||||||
|
copy.content += '//# sourceURL=' + copy.path.replace(/\n/g, '');
|
||||||
|
}
|
||||||
|
return _elementHandle.ElementHandle.from((await this._channel.addScriptTag({
|
||||||
|
...copy
|
||||||
|
})).element);
|
||||||
|
}
|
||||||
|
async addStyleTag(options = {}) {
|
||||||
|
const copy = {
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
if (copy.path) {
|
||||||
|
copy.content = (await _fs.default.promises.readFile(copy.path)).toString();
|
||||||
|
copy.content += '/*# sourceURL=' + copy.path.replace(/\n/g, '') + '*/';
|
||||||
|
}
|
||||||
|
return _elementHandle.ElementHandle.from((await this._channel.addStyleTag({
|
||||||
|
...copy
|
||||||
|
})).element);
|
||||||
|
}
|
||||||
|
async click(selector, options = {}) {
|
||||||
|
return await this._channel.click({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dblclick(selector, options = {}) {
|
||||||
|
return await this._channel.dblclick({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dragAndDrop(source, target, options = {}) {
|
||||||
|
return await this._channel.dragAndDrop({
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async tap(selector, options = {}) {
|
||||||
|
return await this._channel.tap({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async fill(selector, value, options = {}) {
|
||||||
|
return await this._channel.fill({
|
||||||
|
selector,
|
||||||
|
value,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _highlight(selector) {
|
||||||
|
return await this._channel.highlight({
|
||||||
|
selector
|
||||||
|
});
|
||||||
|
}
|
||||||
|
locator(selector, options) {
|
||||||
|
return new _locator.Locator(this, selector, options);
|
||||||
|
}
|
||||||
|
getByTestId(testId) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTestIdSelector)((0, _locator.testIdAttributeName)(), testId));
|
||||||
|
}
|
||||||
|
getByAltText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByAltTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByLabel(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByLabelSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByPlaceholder(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByPlaceholderSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByTitle(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTitleSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByRole(role, options = {}) {
|
||||||
|
return this.locator((0, _locatorUtils.getByRoleSelector)(role, options));
|
||||||
|
}
|
||||||
|
frameLocator(selector) {
|
||||||
|
return new _locator.FrameLocator(this, selector);
|
||||||
|
}
|
||||||
|
async focus(selector, options = {}) {
|
||||||
|
await this._channel.focus({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async textContent(selector, options = {}) {
|
||||||
|
const value = (await this._channel.textContent({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
return value === undefined ? null : value;
|
||||||
|
}
|
||||||
|
async innerText(selector, options = {}) {
|
||||||
|
return (await this._channel.innerText({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async innerHTML(selector, options = {}) {
|
||||||
|
return (await this._channel.innerHTML({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async getAttribute(selector, name, options = {}) {
|
||||||
|
const value = (await this._channel.getAttribute({
|
||||||
|
selector,
|
||||||
|
name,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
return value === undefined ? null : value;
|
||||||
|
}
|
||||||
|
async inputValue(selector, options = {}) {
|
||||||
|
return (await this._channel.inputValue({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isChecked(selector, options = {}) {
|
||||||
|
return (await this._channel.isChecked({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isDisabled(selector, options = {}) {
|
||||||
|
return (await this._channel.isDisabled({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isEditable(selector, options = {}) {
|
||||||
|
return (await this._channel.isEditable({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isEnabled(selector, options = {}) {
|
||||||
|
return (await this._channel.isEnabled({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isHidden(selector, options = {}) {
|
||||||
|
return (await this._channel.isHidden({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async isVisible(selector, options = {}) {
|
||||||
|
return (await this._channel.isVisible({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
})).value;
|
||||||
|
}
|
||||||
|
async hover(selector, options = {}) {
|
||||||
|
await this._channel.hover({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async selectOption(selector, values, options = {}) {
|
||||||
|
return (await this._channel.selectOption({
|
||||||
|
selector,
|
||||||
|
...(0, _elementHandle.convertSelectOptionValues)(values),
|
||||||
|
...options
|
||||||
|
})).values;
|
||||||
|
}
|
||||||
|
async setInputFiles(selector, files, options = {}) {
|
||||||
|
const converted = await (0, _elementHandle.convertInputFiles)(files, this.page().context());
|
||||||
|
if (converted.files) {
|
||||||
|
await this._channel.setInputFiles({
|
||||||
|
selector,
|
||||||
|
files: converted.files,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_debugLogger.debugLogger.log('api', 'switching to large files mode');
|
||||||
|
await this._channel.setInputFilePaths({
|
||||||
|
selector,
|
||||||
|
...converted,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async type(selector, text, options = {}) {
|
||||||
|
await this._channel.type({
|
||||||
|
selector,
|
||||||
|
text,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(selector, key, options = {}) {
|
||||||
|
await this._channel.press({
|
||||||
|
selector,
|
||||||
|
key,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async check(selector, options = {}) {
|
||||||
|
await this._channel.check({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async uncheck(selector, options = {}) {
|
||||||
|
await this._channel.uncheck({
|
||||||
|
selector,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async setChecked(selector, checked, options) {
|
||||||
|
if (checked) await this.check(selector, options);else await this.uncheck(selector, options);
|
||||||
|
}
|
||||||
|
async waitForTimeout(timeout) {
|
||||||
|
await this._channel.waitForTimeout({
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForFunction(pageFunction, arg, options = {}) {
|
||||||
|
if (typeof options.polling === 'string') (0, _utils.assert)(options.polling === 'raf', 'Unknown polling option: ' + options.polling);
|
||||||
|
const result = await this._channel.waitForFunction({
|
||||||
|
...options,
|
||||||
|
pollingInterval: options.polling === 'raf' ? undefined : options.polling,
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return _jsHandle.JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
async title() {
|
||||||
|
return (await this._channel.title()).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Frame = Frame;
|
||||||
|
function verifyLoadState(name, waitUntil) {
|
||||||
|
if (waitUntil === 'networkidle0') waitUntil = 'networkidle';
|
||||||
|
if (!_types.kLifecycleEvents.has(waitUntil)) throw new Error(`${name}: expected one of (load|domcontentloaded|networkidle|commit)`);
|
||||||
|
return waitUntil;
|
||||||
|
}
|
||||||
92
bin/pac/tools/.playwright/package/lib/client/harRouter.js
Normal file
92
bin/pac/tools/.playwright/package/lib/client/harRouter.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.HarRouter = void 0;
|
||||||
|
var _debugLogger = require("../common/debugLogger");
|
||||||
|
var _events = require("./events");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class HarRouter {
|
||||||
|
static async create(localUtils, file, notFoundAction, options) {
|
||||||
|
const {
|
||||||
|
harId,
|
||||||
|
error
|
||||||
|
} = await localUtils._channel.harOpen({
|
||||||
|
file
|
||||||
|
});
|
||||||
|
if (error) throw new Error(error);
|
||||||
|
return new HarRouter(localUtils, harId, notFoundAction, options);
|
||||||
|
}
|
||||||
|
constructor(localUtils, harId, notFoundAction, options) {
|
||||||
|
this._localUtils = void 0;
|
||||||
|
this._harId = void 0;
|
||||||
|
this._notFoundAction = void 0;
|
||||||
|
this._options = void 0;
|
||||||
|
this._localUtils = localUtils;
|
||||||
|
this._harId = harId;
|
||||||
|
this._options = options;
|
||||||
|
this._notFoundAction = notFoundAction;
|
||||||
|
}
|
||||||
|
async _handle(route) {
|
||||||
|
const request = route.request();
|
||||||
|
const response = await this._localUtils._channel.harLookup({
|
||||||
|
harId: this._harId,
|
||||||
|
url: request.url(),
|
||||||
|
method: request.method(),
|
||||||
|
headers: await request.headersArray(),
|
||||||
|
postData: request.postDataBuffer() || undefined,
|
||||||
|
isNavigationRequest: request.isNavigationRequest()
|
||||||
|
});
|
||||||
|
if (response.action === 'redirect') {
|
||||||
|
_debugLogger.debugLogger.log('api', `HAR: ${route.request().url()} redirected to ${response.redirectURL}`);
|
||||||
|
await route._redirectNavigationRequest(response.redirectURL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.action === 'fulfill') {
|
||||||
|
await route.fulfill({
|
||||||
|
status: response.status,
|
||||||
|
headers: Object.fromEntries(response.headers.map(h => [h.name, h.value])),
|
||||||
|
body: response.body
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.action === 'error') _debugLogger.debugLogger.log('api', 'HAR: ' + response.message);
|
||||||
|
// Report the error, but fall through to the default handler.
|
||||||
|
|
||||||
|
if (this._notFoundAction === 'abort') {
|
||||||
|
await route.abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await route.fallback();
|
||||||
|
}
|
||||||
|
async addContextRoute(context) {
|
||||||
|
await context.route(this._options.urlMatch || '**/*', route => this._handle(route));
|
||||||
|
context.once(_events.Events.BrowserContext.Close, () => this.dispose());
|
||||||
|
}
|
||||||
|
async addPageRoute(page) {
|
||||||
|
await page.route(this._options.urlMatch || '**/*', route => this._handle(route));
|
||||||
|
page.once(_events.Events.Page.Close, () => this.dispose());
|
||||||
|
}
|
||||||
|
dispose() {
|
||||||
|
this._localUtils._channel.harClose({
|
||||||
|
harId: this._harId
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.HarRouter = HarRouter;
|
||||||
111
bin/pac/tools/.playwright/package/lib/client/input.js
Normal file
111
bin/pac/tools/.playwright/package/lib/client/input.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Touchscreen = exports.Mouse = exports.Keyboard = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Keyboard {
|
||||||
|
constructor(page) {
|
||||||
|
this._page = void 0;
|
||||||
|
this._page = page;
|
||||||
|
}
|
||||||
|
async down(key) {
|
||||||
|
await this._page._channel.keyboardDown({
|
||||||
|
key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async up(key) {
|
||||||
|
await this._page._channel.keyboardUp({
|
||||||
|
key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async insertText(text) {
|
||||||
|
await this._page._channel.keyboardInsertText({
|
||||||
|
text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async type(text, options = {}) {
|
||||||
|
await this._page._channel.keyboardType({
|
||||||
|
text,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(key, options = {}) {
|
||||||
|
await this._page._channel.keyboardPress({
|
||||||
|
key,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Keyboard = Keyboard;
|
||||||
|
class Mouse {
|
||||||
|
constructor(page) {
|
||||||
|
this._page = void 0;
|
||||||
|
this._page = page;
|
||||||
|
}
|
||||||
|
async move(x, y, options = {}) {
|
||||||
|
await this._page._channel.mouseMove({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async down(options = {}) {
|
||||||
|
await this._page._channel.mouseDown({
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async up(options = {}) {
|
||||||
|
await this._page._channel.mouseUp(options);
|
||||||
|
}
|
||||||
|
async click(x, y, options = {}) {
|
||||||
|
await this._page._channel.mouseClick({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dblclick(x, y, options = {}) {
|
||||||
|
await this.click(x, y, {
|
||||||
|
...options,
|
||||||
|
clickCount: 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async wheel(deltaX, deltaY) {
|
||||||
|
await this._page._channel.mouseWheel({
|
||||||
|
deltaX,
|
||||||
|
deltaY
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Mouse = Mouse;
|
||||||
|
class Touchscreen {
|
||||||
|
constructor(page) {
|
||||||
|
this._page = void 0;
|
||||||
|
this._page = page;
|
||||||
|
}
|
||||||
|
async tap(x, y) {
|
||||||
|
await this._page._channel.touchscreenTap({
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Touchscreen = Touchscreen;
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.JoiningEventEmitter = void 0;
|
||||||
|
var _events = require("events");
|
||||||
|
var _multimap = require("../utils/multimap");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const originalListener = Symbol('originalListener');
|
||||||
|
const wrapperListener = Symbol('wrapperListener');
|
||||||
|
class JoiningEventEmitter {
|
||||||
|
constructor() {
|
||||||
|
this._emitterDelegate = new _events.EventEmitter();
|
||||||
|
this._pendingPromises = new _multimap.MultiMap();
|
||||||
|
}
|
||||||
|
addListener(event, listener) {
|
||||||
|
this._emitterDelegate.addListener(event, this._wrap(event, listener));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
this._emitterDelegate.on(event, this._wrap(event, listener));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
once(event, listener) {
|
||||||
|
const onceWrapper = (...args) => {
|
||||||
|
listener(...args);
|
||||||
|
this.off(event, onceWrapper);
|
||||||
|
};
|
||||||
|
this.on(event, onceWrapper);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
removeListener(event, listener) {
|
||||||
|
this._emitterDelegate.removeListener(event, this._wrapper(listener));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
off(event, listener) {
|
||||||
|
this._emitterDelegate.off(event, this._wrapper(listener));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
removeAllListeners(event) {
|
||||||
|
this._emitterDelegate.removeAllListeners(event);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
setMaxListeners(n) {
|
||||||
|
this._emitterDelegate.setMaxListeners(n);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
getMaxListeners() {
|
||||||
|
return this._emitterDelegate.getMaxListeners();
|
||||||
|
}
|
||||||
|
listeners(event) {
|
||||||
|
return this._emitterDelegate.listeners(event).map(f => this._original(f));
|
||||||
|
}
|
||||||
|
rawListeners(event) {
|
||||||
|
return this._emitterDelegate.rawListeners(event).map(f => this._original(f));
|
||||||
|
}
|
||||||
|
emit(event, ...args) {
|
||||||
|
return this._emitterDelegate.emit(event, ...args);
|
||||||
|
}
|
||||||
|
listenerCount(event) {
|
||||||
|
return this._emitterDelegate.listenerCount(event);
|
||||||
|
}
|
||||||
|
prependListener(event, listener) {
|
||||||
|
this._emitterDelegate.prependListener(event, this._wrap(event, listener));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
prependOnceListener(event, listener) {
|
||||||
|
const onceWrapper = (...args) => {
|
||||||
|
listener(...args);
|
||||||
|
this.off(event, onceWrapper);
|
||||||
|
};
|
||||||
|
this.prependListener(event, onceWrapper);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
eventNames() {
|
||||||
|
return this._emitterDelegate.eventNames();
|
||||||
|
}
|
||||||
|
async _joinPendingEventHandlers() {
|
||||||
|
await Promise.all([...this._pendingPromises.values()]);
|
||||||
|
}
|
||||||
|
_wrap(event, listener) {
|
||||||
|
const wrapper = (...args) => {
|
||||||
|
const result = listener(...args);
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
this._pendingPromises.set(event, result);
|
||||||
|
result.finally(() => this._pendingPromises.delete(event, result));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wrapper[originalListener] = listener;
|
||||||
|
listener[wrapperListener] = wrapper;
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
_wrapper(listener) {
|
||||||
|
var _wrapperListener;
|
||||||
|
// Fallback to original listener if not wrapped to ensure backwards compatibility Node.js's event emitter
|
||||||
|
return (_wrapperListener = listener[wrapperListener]) !== null && _wrapperListener !== void 0 ? _wrapperListener : listener;
|
||||||
|
}
|
||||||
|
_original(wrapper) {
|
||||||
|
return wrapper[originalListener];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.JoiningEventEmitter = JoiningEventEmitter;
|
||||||
119
bin/pac/tools/.playwright/package/lib/client/jsHandle.js
Normal file
119
bin/pac/tools/.playwright/package/lib/client/jsHandle.js
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.JSHandle = void 0;
|
||||||
|
exports.assertMaxArguments = assertMaxArguments;
|
||||||
|
exports.parseResult = parseResult;
|
||||||
|
exports.serializeArgument = serializeArgument;
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _serializers = require("../protocol/serializers");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class JSHandle extends _channelOwner.ChannelOwner {
|
||||||
|
static from(handle) {
|
||||||
|
return handle._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._preview = void 0;
|
||||||
|
this._preview = this._initializer.preview;
|
||||||
|
this._channel.on('previewUpdated', ({
|
||||||
|
preview
|
||||||
|
}) => this._preview = preview);
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg) {
|
||||||
|
const result = await this._channel.evaluateExpression({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: serializeArgument(arg)
|
||||||
|
});
|
||||||
|
return parseResult(result.value);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg) {
|
||||||
|
const result = await this._channel.evaluateExpressionHandle({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: serializeArgument(arg)
|
||||||
|
});
|
||||||
|
return JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
async getProperty(propertyName) {
|
||||||
|
const result = await this._channel.getProperty({
|
||||||
|
name: propertyName
|
||||||
|
});
|
||||||
|
return JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
async getProperties() {
|
||||||
|
const map = new Map();
|
||||||
|
for (const {
|
||||||
|
name,
|
||||||
|
value
|
||||||
|
} of (await this._channel.getPropertyList()).properties) map.set(name, JSHandle.from(value));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
async jsonValue() {
|
||||||
|
return parseResult((await this._channel.jsonValue()).value);
|
||||||
|
}
|
||||||
|
asElement() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
async dispose() {
|
||||||
|
return await this._channel.dispose();
|
||||||
|
}
|
||||||
|
async _objectCount() {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const {
|
||||||
|
count
|
||||||
|
} = await this._channel.objectCount();
|
||||||
|
return count;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return this._preview;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function takes care of converting all JSHandles to their channels,
|
||||||
|
// so that generic channel serializer converts them to guids.
|
||||||
|
exports.JSHandle = JSHandle;
|
||||||
|
function serializeArgument(arg) {
|
||||||
|
const handles = [];
|
||||||
|
const pushHandle = channel => {
|
||||||
|
handles.push(channel);
|
||||||
|
return handles.length - 1;
|
||||||
|
};
|
||||||
|
const value = (0, _serializers.serializeValue)(arg, value => {
|
||||||
|
if (value instanceof JSHandle) return {
|
||||||
|
h: pushHandle(value._channel)
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
fallThrough: value
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
handles
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function parseResult(value) {
|
||||||
|
return (0, _serializers.parseSerializedValue)(value, undefined);
|
||||||
|
}
|
||||||
|
function assertMaxArguments(count, max) {
|
||||||
|
if (count > max) throw new Error('Too many arguments. If you need to pass more than 1 argument to the function wrap them in an object.');
|
||||||
|
}
|
||||||
35
bin/pac/tools/.playwright/package/lib/client/jsonPipe.js
Normal file
35
bin/pac/tools/.playwright/package/lib/client/jsonPipe.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.JsonPipe = void 0;
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class JsonPipe extends _channelOwner.ChannelOwner {
|
||||||
|
static from(jsonPipe) {
|
||||||
|
return jsonPipe._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
channel() {
|
||||||
|
return this._channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.JsonPipe = JsonPipe;
|
||||||
29
bin/pac/tools/.playwright/package/lib/client/localUtils.js
Normal file
29
bin/pac/tools/.playwright/package/lib/client/localUtils.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.LocalUtils = void 0;
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LocalUtils extends _channelOwner.ChannelOwner {
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.LocalUtils = LocalUtils;
|
||||||
429
bin/pac/tools/.playwright/package/lib/client/locator.js
Normal file
429
bin/pac/tools/.playwright/package/lib/client/locator.js
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Locator = exports.FrameLocator = void 0;
|
||||||
|
exports.setTestIdAttribute = setTestIdAttribute;
|
||||||
|
exports.testIdAttributeName = testIdAttributeName;
|
||||||
|
var util = _interopRequireWildcard(require("util"));
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _elementHandle = require("./elementHandle");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _stringUtils = require("../utils/isomorphic/stringUtils");
|
||||||
|
var _locatorUtils = require("../utils/isomorphic/locatorUtils");
|
||||||
|
let _util$inspect$custom;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||||
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||||
|
_util$inspect$custom = util.inspect.custom;
|
||||||
|
class Locator {
|
||||||
|
constructor(frame, selector, options) {
|
||||||
|
this._frame = void 0;
|
||||||
|
this._selector = void 0;
|
||||||
|
this._frame = frame;
|
||||||
|
this._selector = selector;
|
||||||
|
if (options !== null && options !== void 0 && options.hasText) this._selector += ` >> internal:has-text=${(0, _stringUtils.escapeForTextSelector)(options.hasText, false)}`;
|
||||||
|
if (options !== null && options !== void 0 && options.hasNotText) this._selector += ` >> internal:has-not-text=${(0, _stringUtils.escapeForTextSelector)(options.hasNotText, false)}`;
|
||||||
|
if (options !== null && options !== void 0 && options.has) {
|
||||||
|
const locator = options.has;
|
||||||
|
if (locator._frame !== frame) throw new Error(`Inner "has" locator must belong to the same frame.`);
|
||||||
|
this._selector += ` >> internal:has=` + JSON.stringify(locator._selector);
|
||||||
|
}
|
||||||
|
if (options !== null && options !== void 0 && options.hasNot) {
|
||||||
|
const locator = options.hasNot;
|
||||||
|
if (locator._frame !== frame) throw new Error(`Inner "hasNot" locator must belong to the same frame.`);
|
||||||
|
this._selector += ` >> internal:has-not=` + JSON.stringify(locator._selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async _withElement(task, timeout) {
|
||||||
|
timeout = this._frame.page()._timeoutSettings.timeout({
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
const deadline = timeout ? (0, _utils.monotonicTime)() + timeout : 0;
|
||||||
|
return this._frame._wrapApiCall(async () => {
|
||||||
|
const result = await this._frame._channel.waitForSelector({
|
||||||
|
selector: this._selector,
|
||||||
|
strict: true,
|
||||||
|
state: 'attached',
|
||||||
|
timeout
|
||||||
|
});
|
||||||
|
const handle = _elementHandle.ElementHandle.fromNullable(result.element);
|
||||||
|
if (!handle) throw new Error(`Could not resolve ${this._selector} to DOM Element`);
|
||||||
|
try {
|
||||||
|
return await task(handle, deadline ? deadline - (0, _utils.monotonicTime)() : 0);
|
||||||
|
} finally {
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
page() {
|
||||||
|
return this._frame.page();
|
||||||
|
}
|
||||||
|
async boundingBox(options) {
|
||||||
|
return this._withElement(h => h.boundingBox(), options === null || options === void 0 ? void 0 : options.timeout);
|
||||||
|
}
|
||||||
|
async check(options = {}) {
|
||||||
|
return this._frame.check(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async click(options = {}) {
|
||||||
|
return this._frame.click(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dblclick(options = {}) {
|
||||||
|
return this._frame.dblclick(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dispatchEvent(type, eventInit = {}, options) {
|
||||||
|
return this._frame.dispatchEvent(this._selector, type, eventInit, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async dragTo(target, options = {}) {
|
||||||
|
return this._frame.dragAndDrop(this._selector, target._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg, options) {
|
||||||
|
return this._withElement(h => h.evaluate(pageFunction, arg), options === null || options === void 0 ? void 0 : options.timeout);
|
||||||
|
}
|
||||||
|
async evaluateAll(pageFunction, arg) {
|
||||||
|
return this._frame.$$eval(this._selector, pageFunction, arg);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg, options) {
|
||||||
|
return this._withElement(h => h.evaluateHandle(pageFunction, arg), options === null || options === void 0 ? void 0 : options.timeout);
|
||||||
|
}
|
||||||
|
async fill(value, options = {}) {
|
||||||
|
return this._frame.fill(this._selector, value, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async clear(options = {}) {
|
||||||
|
return this.fill('', options);
|
||||||
|
}
|
||||||
|
async _highlight() {
|
||||||
|
// VS Code extension uses this one, keep it for now.
|
||||||
|
return this._frame._highlight(this._selector);
|
||||||
|
}
|
||||||
|
async highlight() {
|
||||||
|
return this._frame._highlight(this._selector);
|
||||||
|
}
|
||||||
|
locator(selectorOrLocator, options) {
|
||||||
|
if ((0, _utils.isString)(selectorOrLocator)) return new Locator(this._frame, this._selector + ' >> ' + selectorOrLocator, options);
|
||||||
|
if (selectorOrLocator._frame !== this._frame) throw new Error(`Locators must belong to the same frame.`);
|
||||||
|
return new Locator(this._frame, this._selector + ' >> ' + selectorOrLocator._selector, options);
|
||||||
|
}
|
||||||
|
getByTestId(testId) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTestIdSelector)(testIdAttributeName(), testId));
|
||||||
|
}
|
||||||
|
getByAltText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByAltTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByLabel(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByLabelSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByPlaceholder(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByPlaceholderSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByTitle(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTitleSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByRole(role, options = {}) {
|
||||||
|
return this.locator((0, _locatorUtils.getByRoleSelector)(role, options));
|
||||||
|
}
|
||||||
|
frameLocator(selector) {
|
||||||
|
return new FrameLocator(this._frame, this._selector + ' >> ' + selector);
|
||||||
|
}
|
||||||
|
filter(options) {
|
||||||
|
return new Locator(this._frame, this._selector, options);
|
||||||
|
}
|
||||||
|
async elementHandle(options) {
|
||||||
|
return await this._frame.waitForSelector(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
state: 'attached',
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async elementHandles() {
|
||||||
|
return this._frame.$$(this._selector);
|
||||||
|
}
|
||||||
|
first() {
|
||||||
|
return new Locator(this._frame, this._selector + ' >> nth=0');
|
||||||
|
}
|
||||||
|
last() {
|
||||||
|
return new Locator(this._frame, this._selector + ` >> nth=-1`);
|
||||||
|
}
|
||||||
|
nth(index) {
|
||||||
|
return new Locator(this._frame, this._selector + ` >> nth=${index}`);
|
||||||
|
}
|
||||||
|
and(locator) {
|
||||||
|
if (locator._frame !== this._frame) throw new Error(`Locators must belong to the same frame.`);
|
||||||
|
return new Locator(this._frame, this._selector + ` >> internal:and=` + JSON.stringify(locator._selector));
|
||||||
|
}
|
||||||
|
or(locator) {
|
||||||
|
if (locator._frame !== this._frame) throw new Error(`Locators must belong to the same frame.`);
|
||||||
|
return new Locator(this._frame, this._selector + ` >> internal:or=` + JSON.stringify(locator._selector));
|
||||||
|
}
|
||||||
|
async focus(options) {
|
||||||
|
return this._frame.focus(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async blur(options) {
|
||||||
|
await this._frame._channel.blur({
|
||||||
|
selector: this._selector,
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async count() {
|
||||||
|
return this._frame._queryCount(this._selector);
|
||||||
|
}
|
||||||
|
async getAttribute(name, options) {
|
||||||
|
return this._frame.getAttribute(this._selector, name, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async hover(options = {}) {
|
||||||
|
return this._frame.hover(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async innerHTML(options) {
|
||||||
|
return this._frame.innerHTML(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async innerText(options) {
|
||||||
|
return this._frame.innerText(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async inputValue(options) {
|
||||||
|
return this._frame.inputValue(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isChecked(options) {
|
||||||
|
return this._frame.isChecked(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isDisabled(options) {
|
||||||
|
return this._frame.isDisabled(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isEditable(options) {
|
||||||
|
return this._frame.isEditable(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isEnabled(options) {
|
||||||
|
return this._frame.isEnabled(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isHidden(options) {
|
||||||
|
return this._frame.isHidden(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async isVisible(options) {
|
||||||
|
return this._frame.isVisible(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async press(key, options = {}) {
|
||||||
|
return this._frame.press(this._selector, key, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async screenshot(options = {}) {
|
||||||
|
return this._withElement((h, timeout) => h.screenshot({
|
||||||
|
...options,
|
||||||
|
timeout
|
||||||
|
}), options.timeout);
|
||||||
|
}
|
||||||
|
async scrollIntoViewIfNeeded(options = {}) {
|
||||||
|
return this._withElement((h, timeout) => h.scrollIntoViewIfNeeded({
|
||||||
|
...options,
|
||||||
|
timeout
|
||||||
|
}), options.timeout);
|
||||||
|
}
|
||||||
|
async selectOption(values, options = {}) {
|
||||||
|
return this._frame.selectOption(this._selector, values, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async selectText(options = {}) {
|
||||||
|
return this._withElement((h, timeout) => h.selectText({
|
||||||
|
...options,
|
||||||
|
timeout
|
||||||
|
}), options.timeout);
|
||||||
|
}
|
||||||
|
async setChecked(checked, options) {
|
||||||
|
if (checked) await this.check(options);else await this.uncheck(options);
|
||||||
|
}
|
||||||
|
async setInputFiles(files, options = {}) {
|
||||||
|
return this._frame.setInputFiles(this._selector, files, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async tap(options = {}) {
|
||||||
|
return this._frame.tap(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async textContent(options) {
|
||||||
|
return this._frame.textContent(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async type(text, options = {}) {
|
||||||
|
return this._frame.type(this._selector, text, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async uncheck(options = {}) {
|
||||||
|
return this._frame.uncheck(this._selector, {
|
||||||
|
strict: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async all() {
|
||||||
|
return new Array(await this.count()).fill(0).map((e, i) => this.nth(i));
|
||||||
|
}
|
||||||
|
async allInnerTexts() {
|
||||||
|
return this._frame.$$eval(this._selector, ee => ee.map(e => e.innerText));
|
||||||
|
}
|
||||||
|
async allTextContents() {
|
||||||
|
return this._frame.$$eval(this._selector, ee => ee.map(e => e.textContent || ''));
|
||||||
|
}
|
||||||
|
async waitFor(options) {
|
||||||
|
await this._frame._channel.waitForSelector({
|
||||||
|
selector: this._selector,
|
||||||
|
strict: true,
|
||||||
|
omitReturnValue: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _expect(expression, options) {
|
||||||
|
const params = {
|
||||||
|
selector: this._selector,
|
||||||
|
expression,
|
||||||
|
...options,
|
||||||
|
isNot: !!options.isNot
|
||||||
|
};
|
||||||
|
params.expectedValue = (0, _jsHandle.serializeArgument)(options.expectedValue);
|
||||||
|
const result = await this._frame._channel.expect(params);
|
||||||
|
if (result.received !== undefined) result.received = (0, _jsHandle.parseResult)(result.received);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
[_util$inspect$custom]() {
|
||||||
|
return this.toString();
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return `Locator@${this._selector}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Locator = Locator;
|
||||||
|
class FrameLocator {
|
||||||
|
constructor(frame, selector) {
|
||||||
|
this._frame = void 0;
|
||||||
|
this._frameSelector = void 0;
|
||||||
|
this._frame = frame;
|
||||||
|
this._frameSelector = selector;
|
||||||
|
}
|
||||||
|
locator(selectorOrLocator, options) {
|
||||||
|
if ((0, _utils.isString)(selectorOrLocator)) return new Locator(this._frame, this._frameSelector + ' >> internal:control=enter-frame >> ' + selectorOrLocator, options);
|
||||||
|
if (selectorOrLocator._frame !== this._frame) throw new Error(`Locators must belong to the same frame.`);
|
||||||
|
return new Locator(this._frame, this._frameSelector + ' >> internal:control=enter-frame >> ' + selectorOrLocator._selector, options);
|
||||||
|
}
|
||||||
|
getByTestId(testId) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTestIdSelector)(testIdAttributeName(), testId));
|
||||||
|
}
|
||||||
|
getByAltText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByAltTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByLabel(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByLabelSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByPlaceholder(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByPlaceholderSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByText(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTextSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByTitle(text, options) {
|
||||||
|
return this.locator((0, _locatorUtils.getByTitleSelector)(text, options));
|
||||||
|
}
|
||||||
|
getByRole(role, options = {}) {
|
||||||
|
return this.locator((0, _locatorUtils.getByRoleSelector)(role, options));
|
||||||
|
}
|
||||||
|
frameLocator(selector) {
|
||||||
|
return new FrameLocator(this._frame, this._frameSelector + ' >> internal:control=enter-frame >> ' + selector);
|
||||||
|
}
|
||||||
|
first() {
|
||||||
|
return new FrameLocator(this._frame, this._frameSelector + ' >> nth=0');
|
||||||
|
}
|
||||||
|
last() {
|
||||||
|
return new FrameLocator(this._frame, this._frameSelector + ` >> nth=-1`);
|
||||||
|
}
|
||||||
|
nth(index) {
|
||||||
|
return new FrameLocator(this._frame, this._frameSelector + ` >> nth=${index}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FrameLocator = FrameLocator;
|
||||||
|
let _testIdAttributeName = 'data-testid';
|
||||||
|
function testIdAttributeName() {
|
||||||
|
return _testIdAttributeName;
|
||||||
|
}
|
||||||
|
function setTestIdAttribute(attributeName) {
|
||||||
|
_testIdAttributeName = attributeName;
|
||||||
|
}
|
||||||
552
bin/pac/tools/.playwright/package/lib/client/network.js
Normal file
552
bin/pac/tools/.playwright/package/lib/client/network.js
Normal file
@@ -0,0 +1,552 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.WebSocket = exports.RouteHandler = exports.Route = exports.Response = exports.Request = exports.RawHeaders = void 0;
|
||||||
|
exports.validateHeaders = validateHeaders;
|
||||||
|
var _url = require("url");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var _worker = require("./worker");
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _utilsBundle = require("../utilsBundle");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _manualPromise = require("../utils/manualPromise");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
var _network = require("../utils/network");
|
||||||
|
var _multimap = require("../utils/multimap");
|
||||||
|
var _fetch = require("./fetch");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Request extends _channelOwner.ChannelOwner {
|
||||||
|
static from(request) {
|
||||||
|
return request._object;
|
||||||
|
}
|
||||||
|
static fromNullable(request) {
|
||||||
|
return request ? Request.from(request) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._redirectedFrom = null;
|
||||||
|
this._redirectedTo = null;
|
||||||
|
this._failureText = null;
|
||||||
|
this._provisionalHeaders = void 0;
|
||||||
|
this._actualHeadersPromise = void 0;
|
||||||
|
this._timing = void 0;
|
||||||
|
this._fallbackOverrides = {};
|
||||||
|
this._redirectedFrom = Request.fromNullable(initializer.redirectedFrom);
|
||||||
|
if (this._redirectedFrom) this._redirectedFrom._redirectedTo = this;
|
||||||
|
this._provisionalHeaders = new RawHeaders(initializer.headers);
|
||||||
|
this._fallbackOverrides.postDataBuffer = initializer.postData;
|
||||||
|
this._timing = {
|
||||||
|
startTime: 0,
|
||||||
|
domainLookupStart: -1,
|
||||||
|
domainLookupEnd: -1,
|
||||||
|
connectStart: -1,
|
||||||
|
secureConnectionStart: -1,
|
||||||
|
connectEnd: -1,
|
||||||
|
requestStart: -1,
|
||||||
|
responseStart: -1,
|
||||||
|
responseEnd: -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._fallbackOverrides.url || this._initializer.url;
|
||||||
|
}
|
||||||
|
resourceType() {
|
||||||
|
return this._initializer.resourceType;
|
||||||
|
}
|
||||||
|
method() {
|
||||||
|
return this._fallbackOverrides.method || this._initializer.method;
|
||||||
|
}
|
||||||
|
postData() {
|
||||||
|
var _this$_fallbackOverri;
|
||||||
|
return ((_this$_fallbackOverri = this._fallbackOverrides.postDataBuffer) === null || _this$_fallbackOverri === void 0 ? void 0 : _this$_fallbackOverri.toString('utf-8')) || null;
|
||||||
|
}
|
||||||
|
postDataBuffer() {
|
||||||
|
return this._fallbackOverrides.postDataBuffer || null;
|
||||||
|
}
|
||||||
|
postDataJSON() {
|
||||||
|
const postData = this.postData();
|
||||||
|
if (!postData) return null;
|
||||||
|
const contentType = this.headers()['content-type'];
|
||||||
|
if (contentType === 'application/x-www-form-urlencoded') {
|
||||||
|
const entries = {};
|
||||||
|
const parsed = new _url.URLSearchParams(postData);
|
||||||
|
for (const [k, v] of parsed.entries()) entries[k] = v;
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JSON.parse(postData);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('POST data is not a valid JSON object: ' + postData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
headers() {
|
||||||
|
if (this._fallbackOverrides.headers) return RawHeaders._fromHeadersObjectLossy(this._fallbackOverrides.headers).headers();
|
||||||
|
return this._provisionalHeaders.headers();
|
||||||
|
}
|
||||||
|
_context() {
|
||||||
|
// TODO: make sure this works for service worker requests.
|
||||||
|
return this.frame().page().context();
|
||||||
|
}
|
||||||
|
_actualHeaders() {
|
||||||
|
if (this._fallbackOverrides.headers) return Promise.resolve(RawHeaders._fromHeadersObjectLossy(this._fallbackOverrides.headers));
|
||||||
|
if (!this._actualHeadersPromise) {
|
||||||
|
this._actualHeadersPromise = this._wrapApiCall(async () => {
|
||||||
|
return new RawHeaders((await this._channel.rawRequestHeaders()).headers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this._actualHeadersPromise;
|
||||||
|
}
|
||||||
|
async allHeaders() {
|
||||||
|
return (await this._actualHeaders()).headers();
|
||||||
|
}
|
||||||
|
async headersArray() {
|
||||||
|
return (await this._actualHeaders()).headersArray();
|
||||||
|
}
|
||||||
|
async headerValue(name) {
|
||||||
|
return (await this._actualHeaders()).get(name);
|
||||||
|
}
|
||||||
|
async response() {
|
||||||
|
return Response.fromNullable((await this._channel.response()).response);
|
||||||
|
}
|
||||||
|
async _internalResponse() {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
return Response.fromNullable((await this._channel.response()).response);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
frame() {
|
||||||
|
if (!this._initializer.frame) {
|
||||||
|
(0, _utils.assert)(this.serviceWorker());
|
||||||
|
throw new Error('Service Worker requests do not have an associated frame.');
|
||||||
|
}
|
||||||
|
return _frame.Frame.from(this._initializer.frame);
|
||||||
|
}
|
||||||
|
serviceWorker() {
|
||||||
|
return this._initializer.serviceWorker ? _worker.Worker.from(this._initializer.serviceWorker) : null;
|
||||||
|
}
|
||||||
|
isNavigationRequest() {
|
||||||
|
return this._initializer.isNavigationRequest;
|
||||||
|
}
|
||||||
|
redirectedFrom() {
|
||||||
|
return this._redirectedFrom;
|
||||||
|
}
|
||||||
|
redirectedTo() {
|
||||||
|
return this._redirectedTo;
|
||||||
|
}
|
||||||
|
failure() {
|
||||||
|
if (this._failureText === null) return null;
|
||||||
|
return {
|
||||||
|
errorText: this._failureText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
timing() {
|
||||||
|
return this._timing;
|
||||||
|
}
|
||||||
|
async sizes() {
|
||||||
|
const response = await this.response();
|
||||||
|
if (!response) throw new Error('Unable to fetch sizes for failed request');
|
||||||
|
return (await response._channel.sizes()).sizes;
|
||||||
|
}
|
||||||
|
_setResponseEndTiming(responseEndTiming) {
|
||||||
|
this._timing.responseEnd = responseEndTiming;
|
||||||
|
if (this._timing.responseStart === -1) this._timing.responseStart = responseEndTiming;
|
||||||
|
}
|
||||||
|
_finalRequest() {
|
||||||
|
return this._redirectedTo ? this._redirectedTo._finalRequest() : this;
|
||||||
|
}
|
||||||
|
_applyFallbackOverrides(overrides) {
|
||||||
|
if (overrides.url) this._fallbackOverrides.url = overrides.url;
|
||||||
|
if (overrides.method) this._fallbackOverrides.method = overrides.method;
|
||||||
|
if (overrides.headers) this._fallbackOverrides.headers = overrides.headers;
|
||||||
|
if ((0, _utils.isString)(overrides.postData)) this._fallbackOverrides.postDataBuffer = Buffer.from(overrides.postData, 'utf-8');else if (overrides.postData instanceof Buffer) this._fallbackOverrides.postDataBuffer = overrides.postData;else if (overrides.postData) this._fallbackOverrides.postDataBuffer = Buffer.from(JSON.stringify(overrides.postData), 'utf-8');
|
||||||
|
}
|
||||||
|
_fallbackOverridesForContinue() {
|
||||||
|
return this._fallbackOverrides;
|
||||||
|
}
|
||||||
|
_targetClosedRace() {
|
||||||
|
var _this$serviceWorker, _this$frame$_page;
|
||||||
|
return ((_this$serviceWorker = this.serviceWorker()) === null || _this$serviceWorker === void 0 ? void 0 : _this$serviceWorker._closedRace) || ((_this$frame$_page = this.frame()._page) === null || _this$frame$_page === void 0 ? void 0 : _this$frame$_page._closedOrCrashedRace) || new _manualPromise.ScopedRace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Request = Request;
|
||||||
|
class Route extends _channelOwner.ChannelOwner {
|
||||||
|
static from(route) {
|
||||||
|
return route._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._handlingPromise = null;
|
||||||
|
}
|
||||||
|
request() {
|
||||||
|
return Request.from(this._initializer.request);
|
||||||
|
}
|
||||||
|
_raceWithTargetClose(promise) {
|
||||||
|
// When page closes or crashes, we catch any potential rejects from this Route.
|
||||||
|
// Note that page could be missing when routing popup's initial request that
|
||||||
|
// does not have a Page initialized just yet.
|
||||||
|
return this.request()._targetClosedRace().safeRace(promise);
|
||||||
|
}
|
||||||
|
_startHandling() {
|
||||||
|
this._handlingPromise = new _manualPromise.ManualPromise();
|
||||||
|
return this._handlingPromise;
|
||||||
|
}
|
||||||
|
async fallback(options = {}) {
|
||||||
|
this._checkNotHandled();
|
||||||
|
this.request()._applyFallbackOverrides(options);
|
||||||
|
this._reportHandled(false);
|
||||||
|
}
|
||||||
|
async abort(errorCode) {
|
||||||
|
this._checkNotHandled();
|
||||||
|
await this._raceWithTargetClose(this._channel.abort({
|
||||||
|
requestUrl: this.request()._initializer.url,
|
||||||
|
errorCode
|
||||||
|
}));
|
||||||
|
this._reportHandled(true);
|
||||||
|
}
|
||||||
|
async _redirectNavigationRequest(url) {
|
||||||
|
this._checkNotHandled();
|
||||||
|
await this._raceWithTargetClose(this._channel.redirectNavigationRequest({
|
||||||
|
url
|
||||||
|
}));
|
||||||
|
this._reportHandled(true);
|
||||||
|
}
|
||||||
|
async fetch(options = {}) {
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
const context = this.request()._context();
|
||||||
|
return context.request._innerFetch({
|
||||||
|
request: this.request(),
|
||||||
|
data: options.postData,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async fulfill(options = {}) {
|
||||||
|
this._checkNotHandled();
|
||||||
|
await this._wrapApiCall(async () => {
|
||||||
|
await this._innerFulfill(options);
|
||||||
|
this._reportHandled(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _innerFulfill(options = {}) {
|
||||||
|
let fetchResponseUid;
|
||||||
|
let {
|
||||||
|
status: statusOption,
|
||||||
|
headers: headersOption,
|
||||||
|
body
|
||||||
|
} = options;
|
||||||
|
if (options.json !== undefined) {
|
||||||
|
(0, _utils.assert)(options.body === undefined, 'Can specify either body or json parameters');
|
||||||
|
body = JSON.stringify(options.json);
|
||||||
|
}
|
||||||
|
if (options.response instanceof _fetch.APIResponse) {
|
||||||
|
var _statusOption, _headersOption;
|
||||||
|
(_statusOption = statusOption) !== null && _statusOption !== void 0 ? _statusOption : statusOption = options.response.status();
|
||||||
|
(_headersOption = headersOption) !== null && _headersOption !== void 0 ? _headersOption : headersOption = options.response.headers();
|
||||||
|
if (body === undefined && options.path === undefined) {
|
||||||
|
if (options.response._request._connection === this._connection) fetchResponseUid = options.response._fetchUid();else body = await options.response.body();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let isBase64 = false;
|
||||||
|
let length = 0;
|
||||||
|
if (options.path) {
|
||||||
|
const buffer = await _fs.default.promises.readFile(options.path);
|
||||||
|
body = buffer.toString('base64');
|
||||||
|
isBase64 = true;
|
||||||
|
length = buffer.length;
|
||||||
|
} else if ((0, _utils.isString)(body)) {
|
||||||
|
isBase64 = false;
|
||||||
|
length = Buffer.byteLength(body);
|
||||||
|
} else if (body) {
|
||||||
|
length = body.length;
|
||||||
|
body = body.toString('base64');
|
||||||
|
isBase64 = true;
|
||||||
|
}
|
||||||
|
const headers = {};
|
||||||
|
for (const header of Object.keys(headersOption || {})) headers[header.toLowerCase()] = String(headersOption[header]);
|
||||||
|
if (options.contentType) headers['content-type'] = String(options.contentType);else if (options.json) headers['content-type'] = 'application/json';else if (options.path) headers['content-type'] = _utilsBundle.mime.getType(options.path) || 'application/octet-stream';
|
||||||
|
if (length && !('content-length' in headers)) headers['content-length'] = String(length);
|
||||||
|
await this._raceWithTargetClose(this._channel.fulfill({
|
||||||
|
requestUrl: this.request()._initializer.url,
|
||||||
|
status: statusOption || 200,
|
||||||
|
headers: (0, _utils.headersObjectToArray)(headers),
|
||||||
|
body,
|
||||||
|
isBase64,
|
||||||
|
fetchResponseUid
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
async continue(options = {}) {
|
||||||
|
this._checkNotHandled();
|
||||||
|
this.request()._applyFallbackOverrides(options);
|
||||||
|
await this._innerContinue();
|
||||||
|
this._reportHandled(true);
|
||||||
|
}
|
||||||
|
_checkNotHandled() {
|
||||||
|
if (!this._handlingPromise) throw new Error('Route is already handled!');
|
||||||
|
}
|
||||||
|
_reportHandled(done) {
|
||||||
|
const chain = this._handlingPromise;
|
||||||
|
this._handlingPromise = null;
|
||||||
|
chain.resolve(done);
|
||||||
|
}
|
||||||
|
async _innerContinue(internal = false) {
|
||||||
|
const options = this.request()._fallbackOverridesForContinue();
|
||||||
|
return await this._wrapApiCall(async () => {
|
||||||
|
await this._raceWithTargetClose(this._channel.continue({
|
||||||
|
requestUrl: this.request()._initializer.url,
|
||||||
|
url: options.url,
|
||||||
|
method: options.method,
|
||||||
|
headers: options.headers ? (0, _utils.headersObjectToArray)(options.headers) : undefined,
|
||||||
|
postData: options.postDataBuffer,
|
||||||
|
isFallback: internal
|
||||||
|
}));
|
||||||
|
}, !!internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Route = Route;
|
||||||
|
class Response extends _channelOwner.ChannelOwner {
|
||||||
|
static from(response) {
|
||||||
|
return response._object;
|
||||||
|
}
|
||||||
|
static fromNullable(response) {
|
||||||
|
return response ? Response.from(response) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._provisionalHeaders = void 0;
|
||||||
|
this._actualHeadersPromise = void 0;
|
||||||
|
this._request = void 0;
|
||||||
|
this._finishedPromise = new _manualPromise.ManualPromise();
|
||||||
|
this._provisionalHeaders = new RawHeaders(initializer.headers);
|
||||||
|
this._request = Request.from(this._initializer.request);
|
||||||
|
Object.assign(this._request._timing, this._initializer.timing);
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._initializer.url;
|
||||||
|
}
|
||||||
|
ok() {
|
||||||
|
// Status 0 is for file:// URLs
|
||||||
|
return this._initializer.status === 0 || this._initializer.status >= 200 && this._initializer.status <= 299;
|
||||||
|
}
|
||||||
|
status() {
|
||||||
|
return this._initializer.status;
|
||||||
|
}
|
||||||
|
statusText() {
|
||||||
|
return this._initializer.statusText;
|
||||||
|
}
|
||||||
|
fromServiceWorker() {
|
||||||
|
return this._initializer.fromServiceWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
headers() {
|
||||||
|
return this._provisionalHeaders.headers();
|
||||||
|
}
|
||||||
|
async _actualHeaders() {
|
||||||
|
if (!this._actualHeadersPromise) {
|
||||||
|
this._actualHeadersPromise = (async () => {
|
||||||
|
return new RawHeaders((await this._channel.rawResponseHeaders()).headers);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
return this._actualHeadersPromise;
|
||||||
|
}
|
||||||
|
async allHeaders() {
|
||||||
|
return (await this._actualHeaders()).headers();
|
||||||
|
}
|
||||||
|
async headersArray() {
|
||||||
|
return (await this._actualHeaders()).headersArray().slice();
|
||||||
|
}
|
||||||
|
async headerValue(name) {
|
||||||
|
return (await this._actualHeaders()).get(name);
|
||||||
|
}
|
||||||
|
async headerValues(name) {
|
||||||
|
return (await this._actualHeaders()).getAll(name);
|
||||||
|
}
|
||||||
|
async finished() {
|
||||||
|
return this.request()._targetClosedRace().race(this._finishedPromise);
|
||||||
|
}
|
||||||
|
async body() {
|
||||||
|
return (await this._channel.body()).binary;
|
||||||
|
}
|
||||||
|
async text() {
|
||||||
|
const content = await this.body();
|
||||||
|
return content.toString('utf8');
|
||||||
|
}
|
||||||
|
async json() {
|
||||||
|
const content = await this.text();
|
||||||
|
return JSON.parse(content);
|
||||||
|
}
|
||||||
|
request() {
|
||||||
|
return this._request;
|
||||||
|
}
|
||||||
|
frame() {
|
||||||
|
return this._request.frame();
|
||||||
|
}
|
||||||
|
async serverAddr() {
|
||||||
|
return (await this._channel.serverAddr()).value || null;
|
||||||
|
}
|
||||||
|
async securityDetails() {
|
||||||
|
return (await this._channel.securityDetails()).value || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Response = Response;
|
||||||
|
class WebSocket extends _channelOwner.ChannelOwner {
|
||||||
|
static from(webSocket) {
|
||||||
|
return webSocket._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._page = void 0;
|
||||||
|
this._isClosed = void 0;
|
||||||
|
this._isClosed = false;
|
||||||
|
this._page = parent;
|
||||||
|
this._channel.on('frameSent', event => {
|
||||||
|
if (event.opcode === 1) this.emit(_events.Events.WebSocket.FrameSent, {
|
||||||
|
payload: event.data
|
||||||
|
});else if (event.opcode === 2) this.emit(_events.Events.WebSocket.FrameSent, {
|
||||||
|
payload: Buffer.from(event.data, 'base64')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this._channel.on('frameReceived', event => {
|
||||||
|
if (event.opcode === 1) this.emit(_events.Events.WebSocket.FrameReceived, {
|
||||||
|
payload: event.data
|
||||||
|
});else if (event.opcode === 2) this.emit(_events.Events.WebSocket.FrameReceived, {
|
||||||
|
payload: Buffer.from(event.data, 'base64')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this._channel.on('socketError', ({
|
||||||
|
error
|
||||||
|
}) => this.emit(_events.Events.WebSocket.Error, error));
|
||||||
|
this._channel.on('close', () => {
|
||||||
|
this._isClosed = true;
|
||||||
|
this.emit(_events.Events.WebSocket.Close, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._initializer.url;
|
||||||
|
}
|
||||||
|
isClosed() {
|
||||||
|
return this._isClosed;
|
||||||
|
}
|
||||||
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const timeout = this._page._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||||
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||||
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||||
|
if (event !== _events.Events.WebSocket.Error) waiter.rejectOnEvent(this, _events.Events.WebSocket.Error, new Error('Socket error'));
|
||||||
|
if (event !== _events.Events.WebSocket.Close) waiter.rejectOnEvent(this, _events.Events.WebSocket.Close, new Error('Socket closed'));
|
||||||
|
waiter.rejectOnEvent(this._page, _events.Events.Page.Close, new Error('Page closed'));
|
||||||
|
const result = await waiter.waitForEvent(this, event, predicate);
|
||||||
|
waiter.dispose();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.WebSocket = WebSocket;
|
||||||
|
function validateHeaders(headers) {
|
||||||
|
for (const key of Object.keys(headers)) {
|
||||||
|
const value = headers[key];
|
||||||
|
if (!Object.is(value, undefined) && !(0, _utils.isString)(value)) throw new Error(`Expected value of header "${key}" to be String, but "${typeof value}" is found.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class RouteHandler {
|
||||||
|
constructor(baseURL, url, handler, times = Number.MAX_SAFE_INTEGER) {
|
||||||
|
this.handledCount = 0;
|
||||||
|
this._baseURL = void 0;
|
||||||
|
this._times = void 0;
|
||||||
|
this.url = void 0;
|
||||||
|
this.handler = void 0;
|
||||||
|
this._baseURL = baseURL;
|
||||||
|
this._times = times;
|
||||||
|
this.url = url;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
static prepareInterceptionPatterns(handlers) {
|
||||||
|
const patterns = [];
|
||||||
|
let all = false;
|
||||||
|
for (const handler of handlers) {
|
||||||
|
if ((0, _utils.isString)(handler.url)) patterns.push({
|
||||||
|
glob: handler.url
|
||||||
|
});else if ((0, _utils.isRegExp)(handler.url)) patterns.push({
|
||||||
|
regexSource: handler.url.source,
|
||||||
|
regexFlags: handler.url.flags
|
||||||
|
});else all = true;
|
||||||
|
}
|
||||||
|
if (all) return [{
|
||||||
|
glob: '**/*'
|
||||||
|
}];
|
||||||
|
return patterns;
|
||||||
|
}
|
||||||
|
matches(requestURL) {
|
||||||
|
return (0, _network.urlMatches)(this._baseURL, requestURL, this.url);
|
||||||
|
}
|
||||||
|
async handle(route) {
|
||||||
|
++this.handledCount;
|
||||||
|
const handledPromise = route._startHandling();
|
||||||
|
// Extract handler into a variable to avoid [RouteHandler.handler] in the stack.
|
||||||
|
const handler = this.handler;
|
||||||
|
const [handled] = await Promise.all([handledPromise, handler(route, route.request())]);
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
willExpire() {
|
||||||
|
return this.handledCount + 1 >= this._times;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.RouteHandler = RouteHandler;
|
||||||
|
class RawHeaders {
|
||||||
|
static _fromHeadersObjectLossy(headers) {
|
||||||
|
const headersArray = Object.entries(headers).map(([name, value]) => ({
|
||||||
|
name,
|
||||||
|
value
|
||||||
|
})).filter(header => header.value !== undefined);
|
||||||
|
return new RawHeaders(headersArray);
|
||||||
|
}
|
||||||
|
constructor(headers) {
|
||||||
|
this._headersArray = void 0;
|
||||||
|
this._headersMap = new _multimap.MultiMap();
|
||||||
|
this._headersArray = headers;
|
||||||
|
for (const header of headers) this._headersMap.set(header.name.toLowerCase(), header.value);
|
||||||
|
}
|
||||||
|
get(name) {
|
||||||
|
const values = this.getAll(name);
|
||||||
|
if (!values || !values.length) return null;
|
||||||
|
return values.join(name.toLowerCase() === 'set-cookie' ? '\n' : ', ');
|
||||||
|
}
|
||||||
|
getAll(name) {
|
||||||
|
return [...this._headersMap.get(name.toLowerCase())];
|
||||||
|
}
|
||||||
|
headers() {
|
||||||
|
const result = {};
|
||||||
|
for (const name of this._headersMap.keys()) result[name] = this.get(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
headersArray() {
|
||||||
|
return this._headersArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.RawHeaders = RawHeaders;
|
||||||
655
bin/pac/tools/.playwright/package/lib/client/page.js
Normal file
655
bin/pac/tools/.playwright/package/lib/client/page.js
Normal file
@@ -0,0 +1,655 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Page = exports.BindingCall = void 0;
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
var _path = _interopRequireDefault(require("path"));
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _network = require("../utils/network");
|
||||||
|
var _timeoutSettings = require("../common/timeoutSettings");
|
||||||
|
var _serializers = require("../protocol/serializers");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _fileUtils = require("../utils/fileUtils");
|
||||||
|
var _accessibility = require("./accessibility");
|
||||||
|
var _artifact = require("./artifact");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _clientHelper = require("./clientHelper");
|
||||||
|
var _coverage = require("./coverage");
|
||||||
|
var _download = require("./download");
|
||||||
|
var _elementHandle = require("./elementHandle");
|
||||||
|
var _events = require("./events");
|
||||||
|
var _fileChooser = require("./fileChooser");
|
||||||
|
var _frame = require("./frame");
|
||||||
|
var _input = require("./input");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _network2 = require("./network");
|
||||||
|
var _video = require("./video");
|
||||||
|
var _waiter = require("./waiter");
|
||||||
|
var _worker = require("./worker");
|
||||||
|
var _harRouter = require("./harRouter");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Page extends _channelOwner.ChannelOwner {
|
||||||
|
static from(page) {
|
||||||
|
return page._object;
|
||||||
|
}
|
||||||
|
static fromNullable(page) {
|
||||||
|
return page ? Page.from(page) : null;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._browserContext = void 0;
|
||||||
|
this._ownedContext = void 0;
|
||||||
|
this._mainFrame = void 0;
|
||||||
|
this._frames = new Set();
|
||||||
|
this._workers = new Set();
|
||||||
|
this._closed = false;
|
||||||
|
this._closedOrCrashedRace = new _utils.ScopedRace();
|
||||||
|
this._viewportSize = void 0;
|
||||||
|
this._routes = [];
|
||||||
|
this.accessibility = void 0;
|
||||||
|
this.coverage = void 0;
|
||||||
|
this.keyboard = void 0;
|
||||||
|
this.mouse = void 0;
|
||||||
|
this.request = void 0;
|
||||||
|
this.touchscreen = void 0;
|
||||||
|
this._bindings = new Map();
|
||||||
|
this._timeoutSettings = void 0;
|
||||||
|
this._video = null;
|
||||||
|
this._opener = void 0;
|
||||||
|
this._browserContext = parent;
|
||||||
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings(this._browserContext._timeoutSettings);
|
||||||
|
this.accessibility = new _accessibility.Accessibility(this._channel);
|
||||||
|
this.keyboard = new _input.Keyboard(this);
|
||||||
|
this.mouse = new _input.Mouse(this);
|
||||||
|
this.request = this._browserContext.request;
|
||||||
|
this.touchscreen = new _input.Touchscreen(this);
|
||||||
|
this._mainFrame = _frame.Frame.from(initializer.mainFrame);
|
||||||
|
this._mainFrame._page = this;
|
||||||
|
this._frames.add(this._mainFrame);
|
||||||
|
this._viewportSize = initializer.viewportSize || null;
|
||||||
|
this._closed = initializer.isClosed;
|
||||||
|
this._opener = Page.fromNullable(initializer.opener);
|
||||||
|
this._channel.on('bindingCall', ({
|
||||||
|
binding
|
||||||
|
}) => this._onBinding(BindingCall.from(binding)));
|
||||||
|
this._channel.on('close', () => this._onClose());
|
||||||
|
this._channel.on('crash', () => this._onCrash());
|
||||||
|
this._channel.on('download', ({
|
||||||
|
url,
|
||||||
|
suggestedFilename,
|
||||||
|
artifact
|
||||||
|
}) => {
|
||||||
|
const artifactObject = _artifact.Artifact.from(artifact);
|
||||||
|
this.emit(_events.Events.Page.Download, new _download.Download(this, url, suggestedFilename, artifactObject));
|
||||||
|
});
|
||||||
|
this._channel.on('fileChooser', ({
|
||||||
|
element,
|
||||||
|
isMultiple
|
||||||
|
}) => this.emit(_events.Events.Page.FileChooser, new _fileChooser.FileChooser(this, _elementHandle.ElementHandle.from(element), isMultiple)));
|
||||||
|
this._channel.on('frameAttached', ({
|
||||||
|
frame
|
||||||
|
}) => this._onFrameAttached(_frame.Frame.from(frame)));
|
||||||
|
this._channel.on('frameDetached', ({
|
||||||
|
frame
|
||||||
|
}) => this._onFrameDetached(_frame.Frame.from(frame)));
|
||||||
|
this._channel.on('pageError', ({
|
||||||
|
error
|
||||||
|
}) => this.emit(_events.Events.Page.PageError, (0, _serializers.parseError)(error)));
|
||||||
|
this._channel.on('route', ({
|
||||||
|
route
|
||||||
|
}) => this._onRoute(_network2.Route.from(route)));
|
||||||
|
this._channel.on('video', ({
|
||||||
|
artifact
|
||||||
|
}) => {
|
||||||
|
const artifactObject = _artifact.Artifact.from(artifact);
|
||||||
|
this._forceVideo()._artifactReady(artifactObject);
|
||||||
|
});
|
||||||
|
this._channel.on('webSocket', ({
|
||||||
|
webSocket
|
||||||
|
}) => this.emit(_events.Events.Page.WebSocket, _network2.WebSocket.from(webSocket)));
|
||||||
|
this._channel.on('worker', ({
|
||||||
|
worker
|
||||||
|
}) => this._onWorker(_worker.Worker.from(worker)));
|
||||||
|
this.coverage = new _coverage.Coverage(this._channel);
|
||||||
|
this.once(_events.Events.Page.Close, () => this._closedOrCrashedRace.scopeClosed(new Error(_errors.kBrowserOrContextClosedError)));
|
||||||
|
this.once(_events.Events.Page.Crash, () => this._closedOrCrashedRace.scopeClosed(new Error(_errors.kBrowserOrContextClosedError)));
|
||||||
|
this._setEventToSubscriptionMapping(new Map([[_events.Events.Page.Console, 'console'], [_events.Events.Page.Dialog, 'dialog'], [_events.Events.Page.Request, 'request'], [_events.Events.Page.Response, 'response'], [_events.Events.Page.RequestFinished, 'requestFinished'], [_events.Events.Page.RequestFailed, 'requestFailed'], [_events.Events.Page.FileChooser, 'fileChooser']]));
|
||||||
|
}
|
||||||
|
_onFrameAttached(frame) {
|
||||||
|
frame._page = this;
|
||||||
|
this._frames.add(frame);
|
||||||
|
if (frame._parentFrame) frame._parentFrame._childFrames.add(frame);
|
||||||
|
this.emit(_events.Events.Page.FrameAttached, frame);
|
||||||
|
}
|
||||||
|
_onFrameDetached(frame) {
|
||||||
|
this._frames.delete(frame);
|
||||||
|
frame._detached = true;
|
||||||
|
if (frame._parentFrame) frame._parentFrame._childFrames.delete(frame);
|
||||||
|
this.emit(_events.Events.Page.FrameDetached, frame);
|
||||||
|
}
|
||||||
|
async _onRoute(route) {
|
||||||
|
const routeHandlers = this._routes.slice();
|
||||||
|
for (const routeHandler of routeHandlers) {
|
||||||
|
if (!routeHandler.matches(route.request().url())) continue;
|
||||||
|
if (routeHandler.willExpire()) this._routes.splice(this._routes.indexOf(routeHandler), 1);
|
||||||
|
const handled = await routeHandler.handle(route);
|
||||||
|
if (!this._routes.length) this._wrapApiCall(() => this._updateInterceptionPatterns(), true).catch(() => {});
|
||||||
|
if (handled) return;
|
||||||
|
}
|
||||||
|
await this._browserContext._onRoute(route);
|
||||||
|
}
|
||||||
|
async _onBinding(bindingCall) {
|
||||||
|
const func = this._bindings.get(bindingCall._initializer.name);
|
||||||
|
if (func) {
|
||||||
|
await bindingCall.call(func);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this._browserContext._onBinding(bindingCall);
|
||||||
|
}
|
||||||
|
_onWorker(worker) {
|
||||||
|
this._workers.add(worker);
|
||||||
|
worker._page = this;
|
||||||
|
this.emit(_events.Events.Page.Worker, worker);
|
||||||
|
}
|
||||||
|
_onClose() {
|
||||||
|
this._closed = true;
|
||||||
|
this._browserContext._pages.delete(this);
|
||||||
|
this._browserContext._backgroundPages.delete(this);
|
||||||
|
this.emit(_events.Events.Page.Close, this);
|
||||||
|
}
|
||||||
|
_onCrash() {
|
||||||
|
this.emit(_events.Events.Page.Crash, this);
|
||||||
|
}
|
||||||
|
context() {
|
||||||
|
return this._browserContext;
|
||||||
|
}
|
||||||
|
async opener() {
|
||||||
|
if (!this._opener || this._opener.isClosed()) return null;
|
||||||
|
return this._opener;
|
||||||
|
}
|
||||||
|
mainFrame() {
|
||||||
|
return this._mainFrame;
|
||||||
|
}
|
||||||
|
frame(frameSelector) {
|
||||||
|
const name = (0, _utils.isString)(frameSelector) ? frameSelector : frameSelector.name;
|
||||||
|
const url = (0, _utils.isObject)(frameSelector) ? frameSelector.url : undefined;
|
||||||
|
(0, _utils.assert)(name || url, 'Either name or url matcher should be specified');
|
||||||
|
return this.frames().find(f => {
|
||||||
|
if (name) return f.name() === name;
|
||||||
|
return (0, _network.urlMatches)(this._browserContext._options.baseURL, f.url(), url);
|
||||||
|
}) || null;
|
||||||
|
}
|
||||||
|
frames() {
|
||||||
|
return [...this._frames];
|
||||||
|
}
|
||||||
|
setDefaultNavigationTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||||
|
this._wrapApiCall(async () => {
|
||||||
|
this._channel.setDefaultNavigationTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
}).catch(() => {});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
setDefaultTimeout(timeout) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
|
this._wrapApiCall(async () => {
|
||||||
|
this._channel.setDefaultTimeoutNoReply({
|
||||||
|
timeout
|
||||||
|
}).catch(() => {});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
_forceVideo() {
|
||||||
|
if (!this._video) this._video = new _video.Video(this, this._connection);
|
||||||
|
return this._video;
|
||||||
|
}
|
||||||
|
video() {
|
||||||
|
// Note: we are creating Video object lazily, because we do not know
|
||||||
|
// BrowserContextOptions when constructing the page - it is assigned
|
||||||
|
// too late during launchPersistentContext.
|
||||||
|
if (!this._browserContext._options.recordVideo) return null;
|
||||||
|
return this._forceVideo();
|
||||||
|
}
|
||||||
|
async $(selector, options) {
|
||||||
|
return this._mainFrame.$(selector, options);
|
||||||
|
}
|
||||||
|
async waitForSelector(selector, options) {
|
||||||
|
return this._mainFrame.waitForSelector(selector, options);
|
||||||
|
}
|
||||||
|
async dispatchEvent(selector, type, eventInit, options) {
|
||||||
|
return this._mainFrame.dispatchEvent(selector, type, eventInit, options);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
return this._mainFrame.evaluateHandle(pageFunction, arg);
|
||||||
|
}
|
||||||
|
async $eval(selector, pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
||||||
|
return this._mainFrame.$eval(selector, pageFunction, arg);
|
||||||
|
}
|
||||||
|
async $$eval(selector, pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
||||||
|
return this._mainFrame.$$eval(selector, pageFunction, arg);
|
||||||
|
}
|
||||||
|
async $$(selector) {
|
||||||
|
return this._mainFrame.$$(selector);
|
||||||
|
}
|
||||||
|
async addScriptTag(options = {}) {
|
||||||
|
return this._mainFrame.addScriptTag(options);
|
||||||
|
}
|
||||||
|
async addStyleTag(options = {}) {
|
||||||
|
return this._mainFrame.addStyleTag(options);
|
||||||
|
}
|
||||||
|
async exposeFunction(name, callback) {
|
||||||
|
await this._channel.exposeBinding({
|
||||||
|
name
|
||||||
|
});
|
||||||
|
const binding = (source, ...args) => callback(...args);
|
||||||
|
this._bindings.set(name, binding);
|
||||||
|
}
|
||||||
|
async exposeBinding(name, callback, options = {}) {
|
||||||
|
await this._channel.exposeBinding({
|
||||||
|
name,
|
||||||
|
needsHandle: options.handle
|
||||||
|
});
|
||||||
|
this._bindings.set(name, callback);
|
||||||
|
}
|
||||||
|
async setExtraHTTPHeaders(headers) {
|
||||||
|
(0, _network2.validateHeaders)(headers);
|
||||||
|
await this._channel.setExtraHTTPHeaders({
|
||||||
|
headers: (0, _utils.headersObjectToArray)(headers)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._mainFrame.url();
|
||||||
|
}
|
||||||
|
async content() {
|
||||||
|
return this._mainFrame.content();
|
||||||
|
}
|
||||||
|
async setContent(html, options) {
|
||||||
|
return this._mainFrame.setContent(html, options);
|
||||||
|
}
|
||||||
|
async goto(url, options) {
|
||||||
|
return this._mainFrame.goto(url, options);
|
||||||
|
}
|
||||||
|
async reload(options = {}) {
|
||||||
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
return _network2.Response.fromNullable((await this._channel.reload({
|
||||||
|
...options,
|
||||||
|
waitUntil
|
||||||
|
})).response);
|
||||||
|
}
|
||||||
|
async waitForLoadState(state, options) {
|
||||||
|
return this._mainFrame.waitForLoadState(state, options);
|
||||||
|
}
|
||||||
|
async waitForNavigation(options) {
|
||||||
|
return this._mainFrame.waitForNavigation(options);
|
||||||
|
}
|
||||||
|
async waitForURL(url, options) {
|
||||||
|
return this._mainFrame.waitForURL(url, options);
|
||||||
|
}
|
||||||
|
async waitForRequest(urlOrPredicate, options = {}) {
|
||||||
|
const predicate = request => {
|
||||||
|
if ((0, _utils.isString)(urlOrPredicate) || (0, _utils.isRegExp)(urlOrPredicate)) return (0, _network.urlMatches)(this._browserContext._options.baseURL, request.url(), urlOrPredicate);
|
||||||
|
return urlOrPredicate(request);
|
||||||
|
};
|
||||||
|
const trimmedUrl = trimUrl(urlOrPredicate);
|
||||||
|
const logLine = trimmedUrl ? `waiting for request ${trimmedUrl}` : undefined;
|
||||||
|
return this._waitForEvent(_events.Events.Page.Request, {
|
||||||
|
predicate,
|
||||||
|
timeout: options.timeout
|
||||||
|
}, logLine);
|
||||||
|
}
|
||||||
|
async waitForResponse(urlOrPredicate, options = {}) {
|
||||||
|
const predicate = response => {
|
||||||
|
if ((0, _utils.isString)(urlOrPredicate) || (0, _utils.isRegExp)(urlOrPredicate)) return (0, _network.urlMatches)(this._browserContext._options.baseURL, response.url(), urlOrPredicate);
|
||||||
|
return urlOrPredicate(response);
|
||||||
|
};
|
||||||
|
const trimmedUrl = trimUrl(urlOrPredicate);
|
||||||
|
const logLine = trimmedUrl ? `waiting for response ${trimmedUrl}` : undefined;
|
||||||
|
return this._waitForEvent(_events.Events.Page.Response, {
|
||||||
|
predicate,
|
||||||
|
timeout: options.timeout
|
||||||
|
}, logLine);
|
||||||
|
}
|
||||||
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
||||||
|
return this._waitForEvent(event, optionsOrPredicate, `waiting for event "${event}"`);
|
||||||
|
}
|
||||||
|
async _waitForEvent(event, optionsOrPredicate, logLine) {
|
||||||
|
return this._wrapApiCall(async () => {
|
||||||
|
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||||
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||||
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
||||||
|
if (logLine) waiter.log(logLine);
|
||||||
|
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||||
|
if (event !== _events.Events.Page.Crash) waiter.rejectOnEvent(this, _events.Events.Page.Crash, new Error('Page crashed'));
|
||||||
|
if (event !== _events.Events.Page.Close) waiter.rejectOnEvent(this, _events.Events.Page.Close, new Error('Page closed'));
|
||||||
|
const result = await waiter.waitForEvent(this, event, predicate);
|
||||||
|
waiter.dispose();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async goBack(options = {}) {
|
||||||
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
return _network2.Response.fromNullable((await this._channel.goBack({
|
||||||
|
...options,
|
||||||
|
waitUntil
|
||||||
|
})).response);
|
||||||
|
}
|
||||||
|
async goForward(options = {}) {
|
||||||
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||||
|
return _network2.Response.fromNullable((await this._channel.goForward({
|
||||||
|
...options,
|
||||||
|
waitUntil
|
||||||
|
})).response);
|
||||||
|
}
|
||||||
|
async emulateMedia(options = {}) {
|
||||||
|
await this._channel.emulateMedia({
|
||||||
|
media: options.media === null ? 'no-override' : options.media,
|
||||||
|
colorScheme: options.colorScheme === null ? 'no-override' : options.colorScheme,
|
||||||
|
reducedMotion: options.reducedMotion === null ? 'no-override' : options.reducedMotion,
|
||||||
|
forcedColors: options.forcedColors === null ? 'no-override' : options.forcedColors
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async setViewportSize(viewportSize) {
|
||||||
|
this._viewportSize = viewportSize;
|
||||||
|
await this._channel.setViewportSize({
|
||||||
|
viewportSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
viewportSize() {
|
||||||
|
return this._viewportSize;
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
return this._mainFrame.evaluate(pageFunction, arg);
|
||||||
|
}
|
||||||
|
async addInitScript(script, arg) {
|
||||||
|
const source = await (0, _clientHelper.evaluationScript)(script, arg);
|
||||||
|
await this._channel.addInitScript({
|
||||||
|
source
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async route(url, handler, options = {}) {
|
||||||
|
this._routes.unshift(new _network2.RouteHandler(this._browserContext._options.baseURL, url, handler, options.times));
|
||||||
|
await this._updateInterceptionPatterns();
|
||||||
|
}
|
||||||
|
async routeFromHAR(har, options = {}) {
|
||||||
|
if (options.update) {
|
||||||
|
await this._browserContext._recordIntoHAR(har, this, options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const harRouter = await _harRouter.HarRouter.create(this._connection.localUtils(), har, options.notFound || 'abort', {
|
||||||
|
urlMatch: options.url
|
||||||
|
});
|
||||||
|
harRouter.addPageRoute(this);
|
||||||
|
}
|
||||||
|
async unroute(url, handler) {
|
||||||
|
this._routes = this._routes.filter(route => !(0, _utils.urlMatchesEqual)(route.url, url) || handler && route.handler !== handler);
|
||||||
|
await this._updateInterceptionPatterns();
|
||||||
|
}
|
||||||
|
async _updateInterceptionPatterns() {
|
||||||
|
const patterns = _network2.RouteHandler.prepareInterceptionPatterns(this._routes);
|
||||||
|
await this._channel.setNetworkInterceptionPatterns({
|
||||||
|
patterns
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async screenshot(options = {}) {
|
||||||
|
const copy = {
|
||||||
|
...options,
|
||||||
|
mask: undefined
|
||||||
|
};
|
||||||
|
if (!copy.type) copy.type = (0, _elementHandle.determineScreenshotType)(options);
|
||||||
|
if (options.mask) {
|
||||||
|
copy.mask = options.mask.map(locator => ({
|
||||||
|
frame: locator._frame._channel,
|
||||||
|
selector: locator._selector
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const result = await this._channel.screenshot(copy);
|
||||||
|
if (options.path) {
|
||||||
|
await (0, _fileUtils.mkdirIfNeeded)(options.path);
|
||||||
|
await _fs.default.promises.writeFile(options.path, result.binary);
|
||||||
|
}
|
||||||
|
return result.binary;
|
||||||
|
}
|
||||||
|
async _expectScreenshot(options) {
|
||||||
|
var _options$screenshotOp, _options$screenshotOp2;
|
||||||
|
const mask = (_options$screenshotOp = options.screenshotOptions) !== null && _options$screenshotOp !== void 0 && _options$screenshotOp.mask ? (_options$screenshotOp2 = options.screenshotOptions) === null || _options$screenshotOp2 === void 0 ? void 0 : _options$screenshotOp2.mask.map(locator => ({
|
||||||
|
frame: locator._frame._channel,
|
||||||
|
selector: locator._selector
|
||||||
|
})) : undefined;
|
||||||
|
const locator = options.locator ? {
|
||||||
|
frame: options.locator._frame._channel,
|
||||||
|
selector: options.locator._selector
|
||||||
|
} : undefined;
|
||||||
|
return await this._channel.expectScreenshot({
|
||||||
|
...options,
|
||||||
|
isNot: !!options.isNot,
|
||||||
|
locator,
|
||||||
|
screenshotOptions: {
|
||||||
|
...options.screenshotOptions,
|
||||||
|
mask
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async title() {
|
||||||
|
return this._mainFrame.title();
|
||||||
|
}
|
||||||
|
async bringToFront() {
|
||||||
|
await this._channel.bringToFront();
|
||||||
|
}
|
||||||
|
async close(options = {
|
||||||
|
runBeforeUnload: undefined
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
if (this._ownedContext) await this._ownedContext.close();else await this._channel.close(options);
|
||||||
|
} catch (e) {
|
||||||
|
if ((0, _errors.isSafeCloseError)(e) && !options.runBeforeUnload) return;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isClosed() {
|
||||||
|
return this._closed;
|
||||||
|
}
|
||||||
|
async click(selector, options) {
|
||||||
|
return this._mainFrame.click(selector, options);
|
||||||
|
}
|
||||||
|
async dragAndDrop(source, target, options) {
|
||||||
|
return this._mainFrame.dragAndDrop(source, target, options);
|
||||||
|
}
|
||||||
|
async dblclick(selector, options) {
|
||||||
|
return this._mainFrame.dblclick(selector, options);
|
||||||
|
}
|
||||||
|
async tap(selector, options) {
|
||||||
|
return this._mainFrame.tap(selector, options);
|
||||||
|
}
|
||||||
|
async fill(selector, value, options) {
|
||||||
|
return this._mainFrame.fill(selector, value, options);
|
||||||
|
}
|
||||||
|
locator(selector, options) {
|
||||||
|
return this.mainFrame().locator(selector, options);
|
||||||
|
}
|
||||||
|
getByTestId(testId) {
|
||||||
|
return this.mainFrame().getByTestId(testId);
|
||||||
|
}
|
||||||
|
getByAltText(text, options) {
|
||||||
|
return this.mainFrame().getByAltText(text, options);
|
||||||
|
}
|
||||||
|
getByLabel(text, options) {
|
||||||
|
return this.mainFrame().getByLabel(text, options);
|
||||||
|
}
|
||||||
|
getByPlaceholder(text, options) {
|
||||||
|
return this.mainFrame().getByPlaceholder(text, options);
|
||||||
|
}
|
||||||
|
getByText(text, options) {
|
||||||
|
return this.mainFrame().getByText(text, options);
|
||||||
|
}
|
||||||
|
getByTitle(text, options) {
|
||||||
|
return this.mainFrame().getByTitle(text, options);
|
||||||
|
}
|
||||||
|
getByRole(role, options = {}) {
|
||||||
|
return this.mainFrame().getByRole(role, options);
|
||||||
|
}
|
||||||
|
frameLocator(selector) {
|
||||||
|
return this.mainFrame().frameLocator(selector);
|
||||||
|
}
|
||||||
|
async focus(selector, options) {
|
||||||
|
return this._mainFrame.focus(selector, options);
|
||||||
|
}
|
||||||
|
async textContent(selector, options) {
|
||||||
|
return this._mainFrame.textContent(selector, options);
|
||||||
|
}
|
||||||
|
async innerText(selector, options) {
|
||||||
|
return this._mainFrame.innerText(selector, options);
|
||||||
|
}
|
||||||
|
async innerHTML(selector, options) {
|
||||||
|
return this._mainFrame.innerHTML(selector, options);
|
||||||
|
}
|
||||||
|
async getAttribute(selector, name, options) {
|
||||||
|
return this._mainFrame.getAttribute(selector, name, options);
|
||||||
|
}
|
||||||
|
async inputValue(selector, options) {
|
||||||
|
return this._mainFrame.inputValue(selector, options);
|
||||||
|
}
|
||||||
|
async isChecked(selector, options) {
|
||||||
|
return this._mainFrame.isChecked(selector, options);
|
||||||
|
}
|
||||||
|
async isDisabled(selector, options) {
|
||||||
|
return this._mainFrame.isDisabled(selector, options);
|
||||||
|
}
|
||||||
|
async isEditable(selector, options) {
|
||||||
|
return this._mainFrame.isEditable(selector, options);
|
||||||
|
}
|
||||||
|
async isEnabled(selector, options) {
|
||||||
|
return this._mainFrame.isEnabled(selector, options);
|
||||||
|
}
|
||||||
|
async isHidden(selector, options) {
|
||||||
|
return this._mainFrame.isHidden(selector, options);
|
||||||
|
}
|
||||||
|
async isVisible(selector, options) {
|
||||||
|
return this._mainFrame.isVisible(selector, options);
|
||||||
|
}
|
||||||
|
async hover(selector, options) {
|
||||||
|
return this._mainFrame.hover(selector, options);
|
||||||
|
}
|
||||||
|
async selectOption(selector, values, options) {
|
||||||
|
return this._mainFrame.selectOption(selector, values, options);
|
||||||
|
}
|
||||||
|
async setInputFiles(selector, files, options) {
|
||||||
|
return this._mainFrame.setInputFiles(selector, files, options);
|
||||||
|
}
|
||||||
|
async type(selector, text, options) {
|
||||||
|
return this._mainFrame.type(selector, text, options);
|
||||||
|
}
|
||||||
|
async press(selector, key, options) {
|
||||||
|
return this._mainFrame.press(selector, key, options);
|
||||||
|
}
|
||||||
|
async check(selector, options) {
|
||||||
|
return this._mainFrame.check(selector, options);
|
||||||
|
}
|
||||||
|
async uncheck(selector, options) {
|
||||||
|
return this._mainFrame.uncheck(selector, options);
|
||||||
|
}
|
||||||
|
async setChecked(selector, checked, options) {
|
||||||
|
return this._mainFrame.setChecked(selector, checked, options);
|
||||||
|
}
|
||||||
|
async waitForTimeout(timeout) {
|
||||||
|
return this._mainFrame.waitForTimeout(timeout);
|
||||||
|
}
|
||||||
|
async waitForFunction(pageFunction, arg, options) {
|
||||||
|
return this._mainFrame.waitForFunction(pageFunction, arg, options);
|
||||||
|
}
|
||||||
|
workers() {
|
||||||
|
return [...this._workers];
|
||||||
|
}
|
||||||
|
async pause() {
|
||||||
|
var _this$_instrumentatio;
|
||||||
|
if (require('inspector').url()) return;
|
||||||
|
const defaultNavigationTimeout = this._browserContext._timeoutSettings.defaultNavigationTimeout();
|
||||||
|
const defaultTimeout = this._browserContext._timeoutSettings.defaultTimeout();
|
||||||
|
this._browserContext.setDefaultNavigationTimeout(0);
|
||||||
|
this._browserContext.setDefaultTimeout(0);
|
||||||
|
(_this$_instrumentatio = this._instrumentation) === null || _this$_instrumentatio === void 0 ? void 0 : _this$_instrumentatio.onWillPause();
|
||||||
|
await this._closedOrCrashedRace.safeRace(this.context()._channel.pause());
|
||||||
|
this._browserContext.setDefaultNavigationTimeout(defaultNavigationTimeout);
|
||||||
|
this._browserContext.setDefaultTimeout(defaultTimeout);
|
||||||
|
}
|
||||||
|
async pdf(options = {}) {
|
||||||
|
const transportOptions = {
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
if (transportOptions.margin) transportOptions.margin = {
|
||||||
|
...transportOptions.margin
|
||||||
|
};
|
||||||
|
if (typeof options.width === 'number') transportOptions.width = options.width + 'px';
|
||||||
|
if (typeof options.height === 'number') transportOptions.height = options.height + 'px';
|
||||||
|
for (const margin of ['top', 'right', 'bottom', 'left']) {
|
||||||
|
const index = margin;
|
||||||
|
if (options.margin && typeof options.margin[index] === 'number') transportOptions.margin[index] = transportOptions.margin[index] + 'px';
|
||||||
|
}
|
||||||
|
const result = await this._channel.pdf(transportOptions);
|
||||||
|
if (options.path) {
|
||||||
|
await _fs.default.promises.mkdir(_path.default.dirname(options.path), {
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
await _fs.default.promises.writeFile(options.path, result.pdf);
|
||||||
|
}
|
||||||
|
return result.pdf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Page = Page;
|
||||||
|
class BindingCall extends _channelOwner.ChannelOwner {
|
||||||
|
static from(channel) {
|
||||||
|
return channel._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
async call(func) {
|
||||||
|
try {
|
||||||
|
const frame = _frame.Frame.from(this._initializer.frame);
|
||||||
|
const source = {
|
||||||
|
context: frame._page.context(),
|
||||||
|
page: frame._page,
|
||||||
|
frame
|
||||||
|
};
|
||||||
|
let result;
|
||||||
|
if (this._initializer.handle) result = await func(source, _jsHandle.JSHandle.from(this._initializer.handle));else result = await func(source, ...this._initializer.args.map(_jsHandle.parseResult));
|
||||||
|
this._channel.resolve({
|
||||||
|
result: (0, _jsHandle.serializeArgument)(result)
|
||||||
|
}).catch(() => {});
|
||||||
|
} catch (e) {
|
||||||
|
this._channel.reject({
|
||||||
|
error: (0, _serializers.serializeError)(e)
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BindingCall = BindingCall;
|
||||||
|
function trimEnd(s) {
|
||||||
|
if (s.length > 50) s = s.substring(0, 50) + '\u2026';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
function trimUrl(param) {
|
||||||
|
if ((0, _utils.isRegExp)(param)) return `/${trimEnd(param.source)}/${param.flags}`;
|
||||||
|
if ((0, _utils.isString)(param)) return `"${trimEnd(param)}"`;
|
||||||
|
}
|
||||||
77
bin/pac/tools/.playwright/package/lib/client/playwright.js
Normal file
77
bin/pac/tools/.playwright/package/lib/client/playwright.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Playwright = void 0;
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _android = require("./android");
|
||||||
|
var _browserType = require("./browserType");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _electron = require("./electron");
|
||||||
|
var _fetch = require("./fetch");
|
||||||
|
var _selectors = require("./selectors");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Playwright extends _channelOwner.ChannelOwner {
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._android = void 0;
|
||||||
|
this._electron = void 0;
|
||||||
|
this.chromium = void 0;
|
||||||
|
this.firefox = void 0;
|
||||||
|
this.webkit = void 0;
|
||||||
|
this.devices = void 0;
|
||||||
|
this.selectors = void 0;
|
||||||
|
this.request = void 0;
|
||||||
|
this.errors = void 0;
|
||||||
|
this.request = new _fetch.APIRequest(this);
|
||||||
|
this.chromium = _browserType.BrowserType.from(initializer.chromium);
|
||||||
|
this.chromium._playwright = this;
|
||||||
|
this.firefox = _browserType.BrowserType.from(initializer.firefox);
|
||||||
|
this.firefox._playwright = this;
|
||||||
|
this.webkit = _browserType.BrowserType.from(initializer.webkit);
|
||||||
|
this.webkit._playwright = this;
|
||||||
|
this._android = _android.Android.from(initializer.android);
|
||||||
|
this._electron = _electron.Electron.from(initializer.electron);
|
||||||
|
this.devices = {};
|
||||||
|
for (const {
|
||||||
|
name,
|
||||||
|
descriptor
|
||||||
|
} of initializer.deviceDescriptors) this.devices[name] = descriptor;
|
||||||
|
this.selectors = new _selectors.Selectors();
|
||||||
|
this.errors = {
|
||||||
|
TimeoutError: _errors.TimeoutError
|
||||||
|
};
|
||||||
|
const selectorsOwner = _selectors.SelectorsOwner.from(initializer.selectors);
|
||||||
|
this.selectors._addChannel(selectorsOwner);
|
||||||
|
this._connection.on('close', () => {
|
||||||
|
this.selectors._removeChannel(selectorsOwner);
|
||||||
|
});
|
||||||
|
global._playwrightInstance = this;
|
||||||
|
}
|
||||||
|
_setSelectors(selectors) {
|
||||||
|
const selectorsOwner = _selectors.SelectorsOwner.from(this._initializer.selectors);
|
||||||
|
this.selectors._removeChannel(selectorsOwner);
|
||||||
|
this.selectors = selectors;
|
||||||
|
this.selectors._addChannel(selectorsOwner);
|
||||||
|
}
|
||||||
|
static from(channel) {
|
||||||
|
return channel._object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Playwright = Playwright;
|
||||||
67
bin/pac/tools/.playwright/package/lib/client/selectors.js
Normal file
67
bin/pac/tools/.playwright/package/lib/client/selectors.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.SelectorsOwner = exports.Selectors = void 0;
|
||||||
|
var _clientHelper = require("./clientHelper");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _locator = require("./locator");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Selectors {
|
||||||
|
constructor() {
|
||||||
|
this._channels = new Set();
|
||||||
|
this._registrations = [];
|
||||||
|
}
|
||||||
|
async register(name, script, options = {}) {
|
||||||
|
const source = await (0, _clientHelper.evaluationScript)(script, undefined, false);
|
||||||
|
const params = {
|
||||||
|
...options,
|
||||||
|
name,
|
||||||
|
source
|
||||||
|
};
|
||||||
|
for (const channel of this._channels) await channel._channel.register(params);
|
||||||
|
this._registrations.push(params);
|
||||||
|
}
|
||||||
|
setTestIdAttribute(attributeName) {
|
||||||
|
(0, _locator.setTestIdAttribute)(attributeName);
|
||||||
|
for (const channel of this._channels) channel._channel.setTestIdAttributeName({
|
||||||
|
testIdAttributeName: attributeName
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
_addChannel(channel) {
|
||||||
|
this._channels.add(channel);
|
||||||
|
for (const params of this._registrations) {
|
||||||
|
// This should not fail except for connection closure, but just in case we catch.
|
||||||
|
channel._channel.register(params).catch(() => {});
|
||||||
|
channel._channel.setTestIdAttributeName({
|
||||||
|
testIdAttributeName: (0, _locator.testIdAttributeName)()
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_removeChannel(channel) {
|
||||||
|
this._channels.delete(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Selectors = Selectors;
|
||||||
|
class SelectorsOwner extends _channelOwner.ChannelOwner {
|
||||||
|
static from(browser) {
|
||||||
|
return browser._object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.SelectorsOwner = SelectorsOwner;
|
||||||
54
bin/pac/tools/.playwright/package/lib/client/stream.js
Normal file
54
bin/pac/tools/.playwright/package/lib/client/stream.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Stream = void 0;
|
||||||
|
var _stream = require("stream");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Stream extends _channelOwner.ChannelOwner {
|
||||||
|
static from(Stream) {
|
||||||
|
return Stream._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
stream() {
|
||||||
|
return new StreamImpl(this._channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Stream = Stream;
|
||||||
|
class StreamImpl extends _stream.Readable {
|
||||||
|
constructor(channel) {
|
||||||
|
super();
|
||||||
|
this._channel = void 0;
|
||||||
|
this._channel = channel;
|
||||||
|
}
|
||||||
|
async _read() {
|
||||||
|
const result = await this._channel.read({
|
||||||
|
size: 1024 * 1024
|
||||||
|
});
|
||||||
|
if (result.binary.byteLength) this.push(result.binary);else this.push(null);
|
||||||
|
}
|
||||||
|
_destroy(error, callback) {
|
||||||
|
// Stream might be destroyed after the connection was closed.
|
||||||
|
this._channel.close().catch(e => null);
|
||||||
|
super._destroy(error, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
128
bin/pac/tools/.playwright/package/lib/client/tracing.js
Normal file
128
bin/pac/tools/.playwright/package/lib/client/tracing.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Tracing = void 0;
|
||||||
|
var _artifact = require("./artifact");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Tracing extends _channelOwner.ChannelOwner {
|
||||||
|
static from(channel) {
|
||||||
|
return channel._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._includeSources = false;
|
||||||
|
this._tracesDir = void 0;
|
||||||
|
this._stacksId = void 0;
|
||||||
|
this._isTracing = false;
|
||||||
|
}
|
||||||
|
async start(options = {}) {
|
||||||
|
this._includeSources = !!options.sources;
|
||||||
|
const traceName = await this._wrapApiCall(async () => {
|
||||||
|
await this._channel.tracingStart(options);
|
||||||
|
const response = await this._channel.tracingStartChunk({
|
||||||
|
name: options.name,
|
||||||
|
title: options.title
|
||||||
|
});
|
||||||
|
return response.traceName;
|
||||||
|
});
|
||||||
|
await this._startCollectingStacks(traceName);
|
||||||
|
}
|
||||||
|
async startChunk(options = {}) {
|
||||||
|
const {
|
||||||
|
traceName
|
||||||
|
} = await this._channel.tracingStartChunk(options);
|
||||||
|
await this._startCollectingStacks(traceName);
|
||||||
|
}
|
||||||
|
async _startCollectingStacks(traceName) {
|
||||||
|
if (!this._isTracing) {
|
||||||
|
this._isTracing = true;
|
||||||
|
this._connection.setIsTracing(true);
|
||||||
|
}
|
||||||
|
const result = await this._connection.localUtils()._channel.tracingStarted({
|
||||||
|
tracesDir: this._tracesDir,
|
||||||
|
traceName
|
||||||
|
});
|
||||||
|
this._stacksId = result.stacksId;
|
||||||
|
}
|
||||||
|
async stopChunk(options = {}) {
|
||||||
|
await this._doStopChunk(options.path);
|
||||||
|
}
|
||||||
|
async stop(options = {}) {
|
||||||
|
await this._wrapApiCall(async () => {
|
||||||
|
await this._doStopChunk(options.path);
|
||||||
|
await this._channel.tracingStop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _doStopChunk(filePath) {
|
||||||
|
if (this._isTracing) {
|
||||||
|
this._isTracing = false;
|
||||||
|
this._connection.setIsTracing(false);
|
||||||
|
}
|
||||||
|
if (!filePath) {
|
||||||
|
// Not interested in artifacts.
|
||||||
|
await this._channel.tracingStopChunk({
|
||||||
|
mode: 'discard'
|
||||||
|
});
|
||||||
|
if (this._stacksId) await this._connection.localUtils()._channel.traceDiscarded({
|
||||||
|
stacksId: this._stacksId
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const isLocal = !this._connection.isRemote();
|
||||||
|
if (isLocal) {
|
||||||
|
const result = await this._channel.tracingStopChunk({
|
||||||
|
mode: 'entries'
|
||||||
|
});
|
||||||
|
await this._connection.localUtils()._channel.zip({
|
||||||
|
zipFile: filePath,
|
||||||
|
entries: result.entries,
|
||||||
|
mode: 'write',
|
||||||
|
stacksId: this._stacksId,
|
||||||
|
includeSources: this._includeSources
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await this._channel.tracingStopChunk({
|
||||||
|
mode: 'archive'
|
||||||
|
});
|
||||||
|
|
||||||
|
// The artifact may be missing if the browser closed while stopping tracing.
|
||||||
|
if (!result.artifact) {
|
||||||
|
if (this._stacksId) await this._connection.localUtils()._channel.traceDiscarded({
|
||||||
|
stacksId: this._stacksId
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save trace to the final local file.
|
||||||
|
const artifact = _artifact.Artifact.from(result.artifact);
|
||||||
|
await artifact.saveAs(filePath);
|
||||||
|
await artifact.delete();
|
||||||
|
await this._connection.localUtils()._channel.zip({
|
||||||
|
zipFile: filePath,
|
||||||
|
entries: [],
|
||||||
|
mode: 'append',
|
||||||
|
stacksId: this._stacksId,
|
||||||
|
includeSources: this._includeSources
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Tracing = Tracing;
|
||||||
25
bin/pac/tools/.playwright/package/lib/client/types.js
Normal file
25
bin/pac/tools/.playwright/package/lib/client/types.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.kLifecycleEvents = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const kLifecycleEvents = new Set(['load', 'domcontentloaded', 'networkidle', 'commit']);
|
||||||
|
exports.kLifecycleEvents = kLifecycleEvents;
|
||||||
51
bin/pac/tools/.playwright/package/lib/client/video.js
Normal file
51
bin/pac/tools/.playwright/package/lib/client/video.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Video = void 0;
|
||||||
|
var _utils = require("../utils");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Video {
|
||||||
|
constructor(page, connection) {
|
||||||
|
this._artifact = null;
|
||||||
|
this._artifactReadyPromise = new _utils.ManualPromise();
|
||||||
|
this._isRemote = false;
|
||||||
|
this._isRemote = connection.isRemote();
|
||||||
|
this._artifact = page._closedOrCrashedRace.safeRace(this._artifactReadyPromise);
|
||||||
|
}
|
||||||
|
_artifactReady(artifact) {
|
||||||
|
this._artifactReadyPromise.resolve(artifact);
|
||||||
|
}
|
||||||
|
async path() {
|
||||||
|
if (this._isRemote) throw new Error(`Path is not available when connecting remotely. Use saveAs() to save a local copy.`);
|
||||||
|
const artifact = await this._artifact;
|
||||||
|
if (!artifact) throw new Error('Page did not produce any video frames');
|
||||||
|
return artifact._initializer.absolutePath;
|
||||||
|
}
|
||||||
|
async saveAs(path) {
|
||||||
|
const artifact = await this._artifact;
|
||||||
|
if (!artifact) throw new Error('Page did not produce any video frames');
|
||||||
|
return artifact.saveAs(path);
|
||||||
|
}
|
||||||
|
async delete() {
|
||||||
|
const artifact = await this._artifact;
|
||||||
|
if (artifact) await artifact.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Video = Video;
|
||||||
158
bin/pac/tools/.playwright/package/lib/client/waiter.js
Normal file
158
bin/pac/tools/.playwright/package/lib/client/waiter.js
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Waiter = void 0;
|
||||||
|
var _stackTrace = require("../utils/stackTrace");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Waiter {
|
||||||
|
constructor(channelOwner, event) {
|
||||||
|
this._dispose = void 0;
|
||||||
|
this._failures = [];
|
||||||
|
this._immediateError = void 0;
|
||||||
|
this._logs = [];
|
||||||
|
this._channelOwner = void 0;
|
||||||
|
this._waitId = void 0;
|
||||||
|
this._error = void 0;
|
||||||
|
this._waitId = (0, _utils.createGuid)();
|
||||||
|
this._channelOwner = channelOwner;
|
||||||
|
this._channelOwner._channel.waitForEventInfo({
|
||||||
|
info: {
|
||||||
|
waitId: this._waitId,
|
||||||
|
phase: 'before',
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
this._dispose = [() => this._channelOwner._wrapApiCall(async () => {
|
||||||
|
await this._channelOwner._channel.waitForEventInfo({
|
||||||
|
info: {
|
||||||
|
waitId: this._waitId,
|
||||||
|
phase: 'after',
|
||||||
|
error: this._error
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, true).catch(() => {})];
|
||||||
|
}
|
||||||
|
static createForEvent(channelOwner, event) {
|
||||||
|
return new Waiter(channelOwner, event);
|
||||||
|
}
|
||||||
|
async waitForEvent(emitter, event, predicate) {
|
||||||
|
const {
|
||||||
|
promise,
|
||||||
|
dispose
|
||||||
|
} = waitForEvent(emitter, event, predicate);
|
||||||
|
return this.waitForPromise(promise, dispose);
|
||||||
|
}
|
||||||
|
rejectOnEvent(emitter, event, error, predicate) {
|
||||||
|
const {
|
||||||
|
promise,
|
||||||
|
dispose
|
||||||
|
} = waitForEvent(emitter, event, predicate);
|
||||||
|
this._rejectOn(promise.then(() => {
|
||||||
|
throw error;
|
||||||
|
}), dispose);
|
||||||
|
}
|
||||||
|
rejectOnTimeout(timeout, message) {
|
||||||
|
if (!timeout) return;
|
||||||
|
const {
|
||||||
|
promise,
|
||||||
|
dispose
|
||||||
|
} = waitForTimeout(timeout);
|
||||||
|
this._rejectOn(promise.then(() => {
|
||||||
|
throw new _errors.TimeoutError(message);
|
||||||
|
}), dispose);
|
||||||
|
}
|
||||||
|
rejectImmediately(error) {
|
||||||
|
this._immediateError = error;
|
||||||
|
}
|
||||||
|
dispose() {
|
||||||
|
for (const dispose of this._dispose) dispose();
|
||||||
|
}
|
||||||
|
async waitForPromise(promise, dispose) {
|
||||||
|
try {
|
||||||
|
if (this._immediateError) throw this._immediateError;
|
||||||
|
const result = await Promise.race([promise, ...this._failures]);
|
||||||
|
if (dispose) dispose();
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
if (dispose) dispose();
|
||||||
|
this._error = e.message;
|
||||||
|
this.dispose();
|
||||||
|
(0, _stackTrace.rewriteErrorMessage)(e, e.message + formatLogRecording(this._logs));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log(s) {
|
||||||
|
this._logs.push(s);
|
||||||
|
this._channelOwner._wrapApiCall(async () => {
|
||||||
|
await this._channelOwner._channel.waitForEventInfo({
|
||||||
|
info: {
|
||||||
|
waitId: this._waitId,
|
||||||
|
phase: 'log',
|
||||||
|
message: s
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
_rejectOn(promise, dispose) {
|
||||||
|
this._failures.push(promise);
|
||||||
|
if (dispose) this._dispose.push(dispose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Waiter = Waiter;
|
||||||
|
function waitForEvent(emitter, event, predicate) {
|
||||||
|
let listener;
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
listener = async eventArg => {
|
||||||
|
try {
|
||||||
|
if (predicate && !(await predicate(eventArg))) return;
|
||||||
|
emitter.removeListener(event, listener);
|
||||||
|
resolve(eventArg);
|
||||||
|
} catch (e) {
|
||||||
|
emitter.removeListener(event, listener);
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
emitter.addListener(event, listener);
|
||||||
|
});
|
||||||
|
const dispose = () => emitter.removeListener(event, listener);
|
||||||
|
return {
|
||||||
|
promise,
|
||||||
|
dispose
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function waitForTimeout(timeout) {
|
||||||
|
let timeoutId;
|
||||||
|
const promise = new Promise(resolve => timeoutId = setTimeout(resolve, timeout));
|
||||||
|
const dispose = () => clearTimeout(timeoutId);
|
||||||
|
return {
|
||||||
|
promise,
|
||||||
|
dispose
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function formatLogRecording(log) {
|
||||||
|
if (!log.length) return '';
|
||||||
|
const header = ` logs `;
|
||||||
|
const headerLength = 60;
|
||||||
|
const leftLength = (headerLength - header.length) / 2;
|
||||||
|
const rightLength = headerLength - header.length - leftLength;
|
||||||
|
return `\n${'='.repeat(leftLength)}${header}${'='.repeat(rightLength)}\n${log.join('\n')}\n${'='.repeat(headerLength)}`;
|
||||||
|
}
|
||||||
69
bin/pac/tools/.playwright/package/lib/client/worker.js
Normal file
69
bin/pac/tools/.playwright/package/lib/client/worker.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Worker = void 0;
|
||||||
|
var _events = require("./events");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
var _jsHandle = require("./jsHandle");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
var _errors = require("../common/errors");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Worker extends _channelOwner.ChannelOwner {
|
||||||
|
// Set for web workers.
|
||||||
|
// Set for service workers.
|
||||||
|
|
||||||
|
static from(worker) {
|
||||||
|
return worker._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._page = void 0;
|
||||||
|
this._context = void 0;
|
||||||
|
this._closedRace = new _utils.ScopedRace();
|
||||||
|
this._channel.on('close', () => {
|
||||||
|
if (this._page) this._page._workers.delete(this);
|
||||||
|
if (this._context) this._context._serviceWorkers.delete(this);
|
||||||
|
this.emit(_events.Events.Worker.Close, this);
|
||||||
|
});
|
||||||
|
this.once(_events.Events.Worker.Close, () => this._closedRace.scopeClosed(new Error(_errors.kBrowserOrContextClosedError)));
|
||||||
|
}
|
||||||
|
url() {
|
||||||
|
return this._initializer.url;
|
||||||
|
}
|
||||||
|
async evaluate(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
const result = await this._channel.evaluateExpression({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return (0, _jsHandle.parseResult)(result.value);
|
||||||
|
}
|
||||||
|
async evaluateHandle(pageFunction, arg) {
|
||||||
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
||||||
|
const result = await this._channel.evaluateExpressionHandle({
|
||||||
|
expression: String(pageFunction),
|
||||||
|
isFunction: typeof pageFunction === 'function',
|
||||||
|
arg: (0, _jsHandle.serializeArgument)(arg)
|
||||||
|
});
|
||||||
|
return _jsHandle.JSHandle.from(result.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Worker = Worker;
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.WritableStream = void 0;
|
||||||
|
var _stream = require("stream");
|
||||||
|
var _channelOwner = require("./channelOwner");
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class WritableStream extends _channelOwner.ChannelOwner {
|
||||||
|
static from(Stream) {
|
||||||
|
return Stream._object;
|
||||||
|
}
|
||||||
|
constructor(parent, type, guid, initializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
}
|
||||||
|
stream() {
|
||||||
|
return new WritableStreamImpl(this._channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.WritableStream = WritableStream;
|
||||||
|
class WritableStreamImpl extends _stream.Writable {
|
||||||
|
constructor(channel) {
|
||||||
|
super();
|
||||||
|
this._channel = void 0;
|
||||||
|
this._channel = channel;
|
||||||
|
}
|
||||||
|
async _write(chunk, encoding, callback) {
|
||||||
|
const error = await this._channel.write({
|
||||||
|
binary: typeof chunk === 'string' ? Buffer.from(chunk) : chunk
|
||||||
|
}).catch(e => e);
|
||||||
|
callback(error || null);
|
||||||
|
}
|
||||||
|
async _final(callback) {
|
||||||
|
// Stream might be destroyed after the connection was closed.
|
||||||
|
const error = await this._channel.close().catch(e => e);
|
||||||
|
callback(error || null);
|
||||||
|
}
|
||||||
|
}
|
||||||
93
bin/pac/tools/.playwright/package/lib/common/debugLogger.js
Normal file
93
bin/pac/tools/.playwright/package/lib/common/debugLogger.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.debugLogger = exports.RecentLogsCollector = void 0;
|
||||||
|
var _utilsBundle = require("../utilsBundle");
|
||||||
|
var _fs = _interopRequireDefault(require("fs"));
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const debugLoggerColorMap = {
|
||||||
|
'api': 45,
|
||||||
|
// cyan
|
||||||
|
'protocol': 34,
|
||||||
|
// green
|
||||||
|
'install': 34,
|
||||||
|
// green
|
||||||
|
'download': 34,
|
||||||
|
// green
|
||||||
|
'browser': 0,
|
||||||
|
// reset
|
||||||
|
'socks': 92,
|
||||||
|
// purple
|
||||||
|
'error': 160,
|
||||||
|
// red,
|
||||||
|
'channel:command': 33,
|
||||||
|
// blue
|
||||||
|
'channel:response': 202,
|
||||||
|
// orange
|
||||||
|
'channel:event': 207,
|
||||||
|
// magenta
|
||||||
|
'server': 45,
|
||||||
|
// cyan
|
||||||
|
'server:channel': 34 // green
|
||||||
|
};
|
||||||
|
|
||||||
|
class DebugLogger {
|
||||||
|
constructor() {
|
||||||
|
this._debuggers = new Map();
|
||||||
|
if (process.env.DEBUG_FILE) {
|
||||||
|
const ansiRegex = new RegExp(['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'].join('|'), 'g');
|
||||||
|
const stream = _fs.default.createWriteStream(process.env.DEBUG_FILE);
|
||||||
|
_utilsBundle.debug.log = data => {
|
||||||
|
stream.write(data.replace(ansiRegex, ''));
|
||||||
|
stream.write('\n');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log(name, message) {
|
||||||
|
let cachedDebugger = this._debuggers.get(name);
|
||||||
|
if (!cachedDebugger) {
|
||||||
|
cachedDebugger = (0, _utilsBundle.debug)(`pw:${name}`);
|
||||||
|
this._debuggers.set(name, cachedDebugger);
|
||||||
|
cachedDebugger.color = debugLoggerColorMap[name];
|
||||||
|
}
|
||||||
|
cachedDebugger(message);
|
||||||
|
}
|
||||||
|
isEnabled(name) {
|
||||||
|
return _utilsBundle.debug.enabled(`pw:${name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const debugLogger = new DebugLogger();
|
||||||
|
exports.debugLogger = debugLogger;
|
||||||
|
const kLogCount = 150;
|
||||||
|
class RecentLogsCollector {
|
||||||
|
constructor() {
|
||||||
|
this._logs = [];
|
||||||
|
}
|
||||||
|
log(message) {
|
||||||
|
this._logs.push(message);
|
||||||
|
if (this._logs.length === kLogCount * 2) this._logs.splice(0, kLogCount);
|
||||||
|
}
|
||||||
|
recentLogs() {
|
||||||
|
if (this._logs.length > kLogCount) return this._logs.slice(-kLogCount);
|
||||||
|
return this._logs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.RecentLogsCollector = RecentLogsCollector;
|
||||||
41
bin/pac/tools/.playwright/package/lib/common/errors.js
Normal file
41
bin/pac/tools/.playwright/package/lib/common/errors.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.TimeoutError = void 0;
|
||||||
|
exports.isSafeCloseError = isSafeCloseError;
|
||||||
|
exports.kBrowserOrContextClosedError = exports.kBrowserClosedError = void 0;
|
||||||
|
/**
|
||||||
|
* Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CustomError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = this.constructor.name;
|
||||||
|
Error.captureStackTrace(this, this.constructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class TimeoutError extends CustomError {}
|
||||||
|
exports.TimeoutError = TimeoutError;
|
||||||
|
const kBrowserClosedError = 'Browser has been closed';
|
||||||
|
exports.kBrowserClosedError = kBrowserClosedError;
|
||||||
|
const kBrowserOrContextClosedError = 'Target page, context or browser has been closed';
|
||||||
|
exports.kBrowserOrContextClosedError = kBrowserOrContextClosedError;
|
||||||
|
function isSafeCloseError(error) {
|
||||||
|
return error.message.endsWith(kBrowserClosedError) || error.message.endsWith(kBrowserOrContextClosedError);
|
||||||
|
}
|
||||||
574
bin/pac/tools/.playwright/package/lib/common/socksProxy.js
Normal file
574
bin/pac/tools/.playwright/package/lib/common/socksProxy.js
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.SocksProxyHandler = exports.SocksProxy = void 0;
|
||||||
|
exports.parsePattern = parsePattern;
|
||||||
|
var _events = _interopRequireDefault(require("events"));
|
||||||
|
var _net = _interopRequireDefault(require("net"));
|
||||||
|
var _debugLogger = require("./debugLogger");
|
||||||
|
var _happyEyeballs = require("../utils/happy-eyeballs");
|
||||||
|
var _utils = require("../utils");
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
// https://tools.ietf.org/html/rfc1928
|
||||||
|
var SocksAuth;
|
||||||
|
(function (SocksAuth) {
|
||||||
|
SocksAuth[SocksAuth["NO_AUTHENTICATION_REQUIRED"] = 0] = "NO_AUTHENTICATION_REQUIRED";
|
||||||
|
SocksAuth[SocksAuth["GSSAPI"] = 1] = "GSSAPI";
|
||||||
|
SocksAuth[SocksAuth["USERNAME_PASSWORD"] = 2] = "USERNAME_PASSWORD";
|
||||||
|
SocksAuth[SocksAuth["NO_ACCEPTABLE_METHODS"] = 255] = "NO_ACCEPTABLE_METHODS";
|
||||||
|
})(SocksAuth || (SocksAuth = {}));
|
||||||
|
var SocksAddressType;
|
||||||
|
(function (SocksAddressType) {
|
||||||
|
SocksAddressType[SocksAddressType["IPv4"] = 1] = "IPv4";
|
||||||
|
SocksAddressType[SocksAddressType["FqName"] = 3] = "FqName";
|
||||||
|
SocksAddressType[SocksAddressType["IPv6"] = 4] = "IPv6";
|
||||||
|
})(SocksAddressType || (SocksAddressType = {}));
|
||||||
|
var SocksCommand;
|
||||||
|
(function (SocksCommand) {
|
||||||
|
SocksCommand[SocksCommand["CONNECT"] = 1] = "CONNECT";
|
||||||
|
SocksCommand[SocksCommand["BIND"] = 2] = "BIND";
|
||||||
|
SocksCommand[SocksCommand["UDP_ASSOCIATE"] = 3] = "UDP_ASSOCIATE";
|
||||||
|
})(SocksCommand || (SocksCommand = {}));
|
||||||
|
var SocksReply;
|
||||||
|
(function (SocksReply) {
|
||||||
|
SocksReply[SocksReply["Succeeded"] = 0] = "Succeeded";
|
||||||
|
SocksReply[SocksReply["GeneralServerFailure"] = 1] = "GeneralServerFailure";
|
||||||
|
SocksReply[SocksReply["NotAllowedByRuleSet"] = 2] = "NotAllowedByRuleSet";
|
||||||
|
SocksReply[SocksReply["NetworkUnreachable"] = 3] = "NetworkUnreachable";
|
||||||
|
SocksReply[SocksReply["HostUnreachable"] = 4] = "HostUnreachable";
|
||||||
|
SocksReply[SocksReply["ConnectionRefused"] = 5] = "ConnectionRefused";
|
||||||
|
SocksReply[SocksReply["TtlExpired"] = 6] = "TtlExpired";
|
||||||
|
SocksReply[SocksReply["CommandNotSupported"] = 7] = "CommandNotSupported";
|
||||||
|
SocksReply[SocksReply["AddressTypeNotSupported"] = 8] = "AddressTypeNotSupported";
|
||||||
|
})(SocksReply || (SocksReply = {}));
|
||||||
|
class SocksConnection {
|
||||||
|
constructor(uid, socket, client) {
|
||||||
|
this._buffer = Buffer.from([]);
|
||||||
|
this._offset = 0;
|
||||||
|
this._fence = 0;
|
||||||
|
this._fenceCallback = void 0;
|
||||||
|
this._socket = void 0;
|
||||||
|
this._boundOnData = void 0;
|
||||||
|
this._uid = void 0;
|
||||||
|
this._client = void 0;
|
||||||
|
this._uid = uid;
|
||||||
|
this._socket = socket;
|
||||||
|
this._client = client;
|
||||||
|
this._boundOnData = this._onData.bind(this);
|
||||||
|
socket.on('data', this._boundOnData);
|
||||||
|
socket.on('close', () => this._onClose());
|
||||||
|
socket.on('end', () => this._onClose());
|
||||||
|
socket.on('error', () => this._onClose());
|
||||||
|
this._run().catch(() => this._socket.end());
|
||||||
|
}
|
||||||
|
async _run() {
|
||||||
|
(0, _utils.assert)(await this._authenticate());
|
||||||
|
const {
|
||||||
|
command,
|
||||||
|
host,
|
||||||
|
port
|
||||||
|
} = await this._parseRequest();
|
||||||
|
if (command !== SocksCommand.CONNECT) {
|
||||||
|
this._writeBytes(Buffer.from([0x05, SocksReply.CommandNotSupported, 0x00,
|
||||||
|
// RSV
|
||||||
|
0x01,
|
||||||
|
// IPv4
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
// Address
|
||||||
|
0x00, 0x00 // Port
|
||||||
|
]));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._socket.off('data', this._boundOnData);
|
||||||
|
this._client.onSocketRequested({
|
||||||
|
uid: this._uid,
|
||||||
|
host,
|
||||||
|
port
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async _authenticate() {
|
||||||
|
// Request:
|
||||||
|
// +----+----------+----------+
|
||||||
|
// |VER | NMETHODS | METHODS |
|
||||||
|
// +----+----------+----------+
|
||||||
|
// | 1 | 1 | 1 to 255 |
|
||||||
|
// +----+----------+----------+
|
||||||
|
|
||||||
|
// Response:
|
||||||
|
// +----+--------+
|
||||||
|
// |VER | METHOD |
|
||||||
|
// +----+--------+
|
||||||
|
// | 1 | 1 |
|
||||||
|
// +----+--------+
|
||||||
|
|
||||||
|
const version = await this._readByte();
|
||||||
|
(0, _utils.assert)(version === 0x05, 'The VER field must be set to x05 for this version of the protocol, was ' + version);
|
||||||
|
const nMethods = await this._readByte();
|
||||||
|
(0, _utils.assert)(nMethods, 'No authentication methods specified');
|
||||||
|
const methods = await this._readBytes(nMethods);
|
||||||
|
for (const method of methods) {
|
||||||
|
if (method === 0) {
|
||||||
|
this._writeBytes(Buffer.from([version, method]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._writeBytes(Buffer.from([version, SocksAuth.NO_ACCEPTABLE_METHODS]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
async _parseRequest() {
|
||||||
|
// Request.
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
// | 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
|
||||||
|
// Response.
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
// |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
// | 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||||
|
// +----+-----+-------+------+----------+----------+
|
||||||
|
|
||||||
|
const version = await this._readByte();
|
||||||
|
(0, _utils.assert)(version === 0x05, 'The VER field must be set to x05 for this version of the protocol, was ' + version);
|
||||||
|
const command = await this._readByte();
|
||||||
|
await this._readByte(); // skip reserved.
|
||||||
|
const addressType = await this._readByte();
|
||||||
|
let host = '';
|
||||||
|
switch (addressType) {
|
||||||
|
case SocksAddressType.IPv4:
|
||||||
|
host = (await this._readBytes(4)).join('.');
|
||||||
|
break;
|
||||||
|
case SocksAddressType.FqName:
|
||||||
|
const length = await this._readByte();
|
||||||
|
host = (await this._readBytes(length)).toString();
|
||||||
|
break;
|
||||||
|
case SocksAddressType.IPv6:
|
||||||
|
const bytes = await this._readBytes(16);
|
||||||
|
const tokens = [];
|
||||||
|
for (let i = 0; i < 8; ++i) tokens.push(bytes.readUInt16BE(i * 2).toString(16));
|
||||||
|
host = tokens.join(':');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const port = (await this._readBytes(2)).readUInt16BE(0);
|
||||||
|
this._buffer = Buffer.from([]);
|
||||||
|
this._offset = 0;
|
||||||
|
this._fence = 0;
|
||||||
|
return {
|
||||||
|
command,
|
||||||
|
host,
|
||||||
|
port
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async _readByte() {
|
||||||
|
const buffer = await this._readBytes(1);
|
||||||
|
return buffer[0];
|
||||||
|
}
|
||||||
|
async _readBytes(length) {
|
||||||
|
this._fence = this._offset + length;
|
||||||
|
if (!this._buffer || this._buffer.length < this._fence) await new Promise(f => this._fenceCallback = f);
|
||||||
|
this._offset += length;
|
||||||
|
return this._buffer.slice(this._offset - length, this._offset);
|
||||||
|
}
|
||||||
|
_writeBytes(buffer) {
|
||||||
|
if (this._socket.writable) this._socket.write(buffer);
|
||||||
|
}
|
||||||
|
_onClose() {
|
||||||
|
this._client.onSocketClosed({
|
||||||
|
uid: this._uid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_onData(buffer) {
|
||||||
|
this._buffer = Buffer.concat([this._buffer, buffer]);
|
||||||
|
if (this._fenceCallback && this._buffer.length >= this._fence) {
|
||||||
|
const callback = this._fenceCallback;
|
||||||
|
this._fenceCallback = undefined;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socketConnected(host, port) {
|
||||||
|
this._writeBytes(Buffer.from([0x05, SocksReply.Succeeded, 0x00,
|
||||||
|
// RSV
|
||||||
|
...ipToSocksAddress(host),
|
||||||
|
// ATYP, Address
|
||||||
|
port >> 8, port & 0xFF // Port
|
||||||
|
]));
|
||||||
|
|
||||||
|
this._socket.on('data', data => this._client.onSocketData({
|
||||||
|
uid: this._uid,
|
||||||
|
data
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
socketFailed(errorCode) {
|
||||||
|
const buffer = Buffer.from([0x05, 0, 0x00,
|
||||||
|
// RSV
|
||||||
|
...ipToSocksAddress('0.0.0.0'),
|
||||||
|
// ATYP, Address
|
||||||
|
0, 0 // Port
|
||||||
|
]);
|
||||||
|
|
||||||
|
switch (errorCode) {
|
||||||
|
case 'ENOENT':
|
||||||
|
case 'ENOTFOUND':
|
||||||
|
case 'ETIMEDOUT':
|
||||||
|
case 'EHOSTUNREACH':
|
||||||
|
buffer[1] = SocksReply.HostUnreachable;
|
||||||
|
break;
|
||||||
|
case 'ENETUNREACH':
|
||||||
|
buffer[1] = SocksReply.NetworkUnreachable;
|
||||||
|
break;
|
||||||
|
case 'ECONNREFUSED':
|
||||||
|
buffer[1] = SocksReply.ConnectionRefused;
|
||||||
|
break;
|
||||||
|
case 'ERULESET':
|
||||||
|
buffer[1] = SocksReply.NotAllowedByRuleSet;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this._writeBytes(buffer);
|
||||||
|
this._socket.end();
|
||||||
|
}
|
||||||
|
sendData(data) {
|
||||||
|
this._socket.write(data);
|
||||||
|
}
|
||||||
|
end() {
|
||||||
|
this._socket.end();
|
||||||
|
}
|
||||||
|
error(error) {
|
||||||
|
this._socket.destroy(new Error(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function hexToNumber(hex) {
|
||||||
|
// Note: parseInt has a few issues including ignoring trailing characters and allowing leading 0x.
|
||||||
|
return [...hex].reduce((value, digit) => {
|
||||||
|
const code = digit.charCodeAt(0);
|
||||||
|
if (code >= 48 && code <= 57)
|
||||||
|
// 0..9
|
||||||
|
return value + code;
|
||||||
|
if (code >= 97 && code <= 102)
|
||||||
|
// a..f
|
||||||
|
return value + (code - 97) + 10;
|
||||||
|
if (code >= 65 && code <= 70)
|
||||||
|
// A..F
|
||||||
|
return value + (code - 65) + 10;
|
||||||
|
throw new Error('Invalid IPv6 token ' + hex);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
function ipToSocksAddress(address) {
|
||||||
|
if (_net.default.isIPv4(address)) {
|
||||||
|
return [0x01,
|
||||||
|
// IPv4
|
||||||
|
...address.split('.', 4).map(t => +t & 0xFF) // Address
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_net.default.isIPv6(address)) {
|
||||||
|
const result = [0x04]; // IPv6
|
||||||
|
const tokens = address.split(':', 8);
|
||||||
|
while (tokens.length < 8) tokens.unshift('');
|
||||||
|
for (const token of tokens) {
|
||||||
|
const value = hexToNumber(token);
|
||||||
|
result.push(value >> 8 & 0xFF, value & 0xFF); // Big-endian
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
throw new Error('Only IPv4 and IPv6 addresses are supported');
|
||||||
|
}
|
||||||
|
function starMatchToRegex(pattern) {
|
||||||
|
const source = pattern.split('*').map(s => {
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
||||||
|
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}).join('.*');
|
||||||
|
return new RegExp('^' + source + '$');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This follows "Proxy bypass rules" syntax without implicit and negative rules.
|
||||||
|
// https://source.chromium.org/chromium/chromium/src/+/main:net/docs/proxy.md;l=331
|
||||||
|
function parsePattern(pattern) {
|
||||||
|
if (!pattern) return () => false;
|
||||||
|
const matchers = pattern.split(',').map(token => {
|
||||||
|
const match = token.match(/^(.*?)(?::(\d+))?$/);
|
||||||
|
if (!match) throw new Error(`Unsupported token "${token}" in pattern "${pattern}"`);
|
||||||
|
const tokenPort = match[2] ? +match[2] : undefined;
|
||||||
|
const portMatches = port => tokenPort === undefined || tokenPort === port;
|
||||||
|
let tokenHost = match[1];
|
||||||
|
if (tokenHost === '<loopback>') {
|
||||||
|
return (host, port) => {
|
||||||
|
if (!portMatches(port)) return false;
|
||||||
|
return host === 'localhost' || host.endsWith('.localhost') || host === '127.0.0.1' || host === '[::1]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (tokenHost === '*') return (host, port) => portMatches(port);
|
||||||
|
if (_net.default.isIPv4(tokenHost) || _net.default.isIPv6(tokenHost)) return (host, port) => host === tokenHost && portMatches(port);
|
||||||
|
if (tokenHost[0] === '.') tokenHost = '*' + tokenHost;
|
||||||
|
const tokenRegex = starMatchToRegex(tokenHost);
|
||||||
|
return (host, port) => {
|
||||||
|
if (!portMatches(port)) return false;
|
||||||
|
if (_net.default.isIPv4(host) || _net.default.isIPv6(host)) return false;
|
||||||
|
return !!host.match(tokenRegex);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return (host, port) => matchers.some(matcher => matcher(host, port));
|
||||||
|
}
|
||||||
|
class SocksProxy extends _events.default {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._server = void 0;
|
||||||
|
this._connections = new Map();
|
||||||
|
this._sockets = new Set();
|
||||||
|
this._closed = false;
|
||||||
|
this._port = void 0;
|
||||||
|
this._patternMatcher = () => false;
|
||||||
|
this._directSockets = new Map();
|
||||||
|
this._server = new _net.default.Server(socket => {
|
||||||
|
const uid = (0, _utils.createGuid)();
|
||||||
|
const connection = new SocksConnection(uid, socket, this);
|
||||||
|
this._connections.set(uid, connection);
|
||||||
|
});
|
||||||
|
this._server.on('connection', socket => {
|
||||||
|
if (this._closed) {
|
||||||
|
socket.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._sockets.add(socket);
|
||||||
|
socket.once('close', () => this._sockets.delete(socket));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setPattern(pattern) {
|
||||||
|
try {
|
||||||
|
this._patternMatcher = parsePattern(pattern);
|
||||||
|
} catch (e) {
|
||||||
|
this._patternMatcher = () => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async _handleDirect(request) {
|
||||||
|
try {
|
||||||
|
var _this$_connections$ge4;
|
||||||
|
const socket = await (0, _happyEyeballs.createSocket)(request.host, request.port);
|
||||||
|
socket.on('data', data => {
|
||||||
|
var _this$_connections$ge;
|
||||||
|
return (_this$_connections$ge = this._connections.get(request.uid)) === null || _this$_connections$ge === void 0 ? void 0 : _this$_connections$ge.sendData(data);
|
||||||
|
});
|
||||||
|
socket.on('error', error => {
|
||||||
|
var _this$_connections$ge2;
|
||||||
|
(_this$_connections$ge2 = this._connections.get(request.uid)) === null || _this$_connections$ge2 === void 0 ? void 0 : _this$_connections$ge2.error(error.message);
|
||||||
|
this._directSockets.delete(request.uid);
|
||||||
|
});
|
||||||
|
socket.on('end', () => {
|
||||||
|
var _this$_connections$ge3;
|
||||||
|
(_this$_connections$ge3 = this._connections.get(request.uid)) === null || _this$_connections$ge3 === void 0 ? void 0 : _this$_connections$ge3.end();
|
||||||
|
this._directSockets.delete(request.uid);
|
||||||
|
});
|
||||||
|
const localAddress = socket.localAddress;
|
||||||
|
const localPort = socket.localPort;
|
||||||
|
this._directSockets.set(request.uid, socket);
|
||||||
|
(_this$_connections$ge4 = this._connections.get(request.uid)) === null || _this$_connections$ge4 === void 0 ? void 0 : _this$_connections$ge4.socketConnected(localAddress, localPort);
|
||||||
|
} catch (error) {
|
||||||
|
var _this$_connections$ge5;
|
||||||
|
(_this$_connections$ge5 = this._connections.get(request.uid)) === null || _this$_connections$ge5 === void 0 ? void 0 : _this$_connections$ge5.socketFailed(error.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
port() {
|
||||||
|
return this._port;
|
||||||
|
}
|
||||||
|
async listen(port) {
|
||||||
|
return new Promise(f => {
|
||||||
|
this._server.listen(port, () => {
|
||||||
|
const port = this._server.address().port;
|
||||||
|
this._port = port;
|
||||||
|
f(port);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async close() {
|
||||||
|
if (this._closed) return;
|
||||||
|
this._closed = true;
|
||||||
|
for (const socket of this._sockets) socket.destroy();
|
||||||
|
this._sockets.clear();
|
||||||
|
await new Promise(f => this._server.close(f));
|
||||||
|
}
|
||||||
|
onSocketRequested(payload) {
|
||||||
|
if (!this._patternMatcher(payload.host, payload.port)) {
|
||||||
|
this._handleDirect(payload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emit(SocksProxy.Events.SocksRequested, payload);
|
||||||
|
}
|
||||||
|
onSocketData(payload) {
|
||||||
|
const direct = this._directSockets.get(payload.uid);
|
||||||
|
if (direct) {
|
||||||
|
direct.write(payload.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emit(SocksProxy.Events.SocksData, payload);
|
||||||
|
}
|
||||||
|
onSocketClosed(payload) {
|
||||||
|
const direct = this._directSockets.get(payload.uid);
|
||||||
|
if (direct) {
|
||||||
|
direct.destroy();
|
||||||
|
this._directSockets.delete(payload.uid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emit(SocksProxy.Events.SocksClosed, payload);
|
||||||
|
}
|
||||||
|
socketConnected({
|
||||||
|
uid,
|
||||||
|
host,
|
||||||
|
port
|
||||||
|
}) {
|
||||||
|
var _this$_connections$ge6;
|
||||||
|
(_this$_connections$ge6 = this._connections.get(uid)) === null || _this$_connections$ge6 === void 0 ? void 0 : _this$_connections$ge6.socketConnected(host, port);
|
||||||
|
}
|
||||||
|
socketFailed({
|
||||||
|
uid,
|
||||||
|
errorCode
|
||||||
|
}) {
|
||||||
|
var _this$_connections$ge7;
|
||||||
|
(_this$_connections$ge7 = this._connections.get(uid)) === null || _this$_connections$ge7 === void 0 ? void 0 : _this$_connections$ge7.socketFailed(errorCode);
|
||||||
|
}
|
||||||
|
sendSocketData({
|
||||||
|
uid,
|
||||||
|
data
|
||||||
|
}) {
|
||||||
|
var _this$_connections$ge8;
|
||||||
|
(_this$_connections$ge8 = this._connections.get(uid)) === null || _this$_connections$ge8 === void 0 ? void 0 : _this$_connections$ge8.sendData(data);
|
||||||
|
}
|
||||||
|
sendSocketEnd({
|
||||||
|
uid
|
||||||
|
}) {
|
||||||
|
var _this$_connections$ge9;
|
||||||
|
(_this$_connections$ge9 = this._connections.get(uid)) === null || _this$_connections$ge9 === void 0 ? void 0 : _this$_connections$ge9.end();
|
||||||
|
}
|
||||||
|
sendSocketError({
|
||||||
|
uid,
|
||||||
|
error
|
||||||
|
}) {
|
||||||
|
var _this$_connections$ge10;
|
||||||
|
(_this$_connections$ge10 = this._connections.get(uid)) === null || _this$_connections$ge10 === void 0 ? void 0 : _this$_connections$ge10.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.SocksProxy = SocksProxy;
|
||||||
|
SocksProxy.Events = {
|
||||||
|
SocksRequested: 'socksRequested',
|
||||||
|
SocksData: 'socksData',
|
||||||
|
SocksClosed: 'socksClosed'
|
||||||
|
};
|
||||||
|
class SocksProxyHandler extends _events.default {
|
||||||
|
constructor(pattern, redirectPortForTest) {
|
||||||
|
super();
|
||||||
|
this._sockets = new Map();
|
||||||
|
this._patternMatcher = () => false;
|
||||||
|
this._redirectPortForTest = void 0;
|
||||||
|
this._patternMatcher = parsePattern(pattern);
|
||||||
|
this._redirectPortForTest = redirectPortForTest;
|
||||||
|
}
|
||||||
|
cleanup() {
|
||||||
|
for (const uid of this._sockets.keys()) this.socketClosed({
|
||||||
|
uid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async socketRequested({
|
||||||
|
uid,
|
||||||
|
host,
|
||||||
|
port
|
||||||
|
}) {
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] => request ${host}:${port}`);
|
||||||
|
if (!this._patternMatcher(host, port)) {
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
errorCode: 'ERULESET'
|
||||||
|
};
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= pattern error ${payload.errorCode}`);
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksFailed, payload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (host === 'local.playwright') host = 'localhost';
|
||||||
|
try {
|
||||||
|
if (this._redirectPortForTest) port = this._redirectPortForTest;
|
||||||
|
const socket = await (0, _happyEyeballs.createSocket)(host, port);
|
||||||
|
socket.on('data', data => {
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksData, payload);
|
||||||
|
});
|
||||||
|
socket.on('error', error => {
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
error: error.message
|
||||||
|
};
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= network socket error ${payload.error}`);
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksError, payload);
|
||||||
|
this._sockets.delete(uid);
|
||||||
|
});
|
||||||
|
socket.on('end', () => {
|
||||||
|
const payload = {
|
||||||
|
uid
|
||||||
|
};
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= network socket closed`);
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksEnd, payload);
|
||||||
|
this._sockets.delete(uid);
|
||||||
|
});
|
||||||
|
const localAddress = socket.localAddress;
|
||||||
|
const localPort = socket.localPort;
|
||||||
|
this._sockets.set(uid, socket);
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
host: localAddress,
|
||||||
|
port: localPort
|
||||||
|
};
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= connected to network ${payload.host}:${payload.port}`);
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksConnected, payload);
|
||||||
|
} catch (error) {
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
errorCode: error.code
|
||||||
|
};
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= connect error ${payload.errorCode}`);
|
||||||
|
this.emit(SocksProxyHandler.Events.SocksFailed, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendSocketData({
|
||||||
|
uid,
|
||||||
|
data
|
||||||
|
}) {
|
||||||
|
var _this$_sockets$get;
|
||||||
|
(_this$_sockets$get = this._sockets.get(uid)) === null || _this$_sockets$get === void 0 ? void 0 : _this$_sockets$get.write(data);
|
||||||
|
}
|
||||||
|
socketClosed({
|
||||||
|
uid
|
||||||
|
}) {
|
||||||
|
var _this$_sockets$get2;
|
||||||
|
_debugLogger.debugLogger.log('socks', `[${uid}] <= browser socket closed`);
|
||||||
|
(_this$_sockets$get2 = this._sockets.get(uid)) === null || _this$_sockets$get2 === void 0 ? void 0 : _this$_sockets$get2.destroy();
|
||||||
|
this._sockets.delete(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.SocksProxyHandler = SocksProxyHandler;
|
||||||
|
SocksProxyHandler.Events = {
|
||||||
|
SocksConnected: 'socksConnected',
|
||||||
|
SocksData: 'socksData',
|
||||||
|
SocksError: 'socksError',
|
||||||
|
SocksFailed: 'socksFailed',
|
||||||
|
SocksEnd: 'socksEnd'
|
||||||
|
};
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.TimeoutSettings = exports.DEFAULT_TIMEOUT = exports.DEFAULT_LAUNCH_TIMEOUT = void 0;
|
||||||
|
var _utils = require("../utils");
|
||||||
|
/**
|
||||||
|
* Copyright 2019 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const DEFAULT_TIMEOUT = 30000;
|
||||||
|
exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
|
||||||
|
const DEFAULT_LAUNCH_TIMEOUT = 3 * 60 * 1000; // 3 minutes
|
||||||
|
exports.DEFAULT_LAUNCH_TIMEOUT = DEFAULT_LAUNCH_TIMEOUT;
|
||||||
|
class TimeoutSettings {
|
||||||
|
constructor(parent) {
|
||||||
|
this._parent = void 0;
|
||||||
|
this._defaultTimeout = void 0;
|
||||||
|
this._defaultNavigationTimeout = void 0;
|
||||||
|
this._parent = parent;
|
||||||
|
}
|
||||||
|
setDefaultTimeout(timeout) {
|
||||||
|
this._defaultTimeout = timeout;
|
||||||
|
}
|
||||||
|
setDefaultNavigationTimeout(timeout) {
|
||||||
|
this._defaultNavigationTimeout = timeout;
|
||||||
|
}
|
||||||
|
defaultNavigationTimeout() {
|
||||||
|
return this._defaultNavigationTimeout;
|
||||||
|
}
|
||||||
|
defaultTimeout() {
|
||||||
|
return this._defaultTimeout;
|
||||||
|
}
|
||||||
|
navigationTimeout(options) {
|
||||||
|
if (typeof options.timeout === 'number') return options.timeout;
|
||||||
|
if (this._defaultNavigationTimeout !== undefined) return this._defaultNavigationTimeout;
|
||||||
|
if ((0, _utils.debugMode)()) return 0;
|
||||||
|
if (this._defaultTimeout !== undefined) return this._defaultTimeout;
|
||||||
|
if (this._parent) return this._parent.navigationTimeout(options);
|
||||||
|
return DEFAULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
timeout(options) {
|
||||||
|
if (typeof options.timeout === 'number') return options.timeout;
|
||||||
|
if ((0, _utils.debugMode)()) return 0;
|
||||||
|
if (this._defaultTimeout !== undefined) return this._defaultTimeout;
|
||||||
|
if (this._parent) return this._parent.timeout(options);
|
||||||
|
return DEFAULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
static timeout(options) {
|
||||||
|
if (typeof options.timeout === 'number') return options.timeout;
|
||||||
|
if ((0, _utils.debugMode)()) return 0;
|
||||||
|
return DEFAULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
static launchTimeout(options) {
|
||||||
|
if (typeof options.timeout === 'number') return options.timeout;
|
||||||
|
if ((0, _utils.debugMode)()) return 0;
|
||||||
|
return DEFAULT_LAUNCH_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.TimeoutSettings = TimeoutSettings;
|
||||||
5
bin/pac/tools/.playwright/package/lib/common/types.js
Normal file
5
bin/pac/tools/.playwright/package/lib/common/types.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,98 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.blendWithWhite = blendWithWhite;
|
||||||
|
exports.colorDeltaE94 = colorDeltaE94;
|
||||||
|
exports.rgb2gray = rgb2gray;
|
||||||
|
exports.srgb2xyz = srgb2xyz;
|
||||||
|
exports.xyz2lab = xyz2lab;
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function blendWithWhite(c, a) {
|
||||||
|
return 255 + (c - 255) * a;
|
||||||
|
}
|
||||||
|
function rgb2gray(r, g, b) {
|
||||||
|
// NOTE: this is the exact integer formula from SSIM.js.
|
||||||
|
// See https://github.com/obartra/ssim/blob/ca8e3c6a6ff5f4f2e232239e0c3d91806f3c97d5/src/matlab/rgb2gray.ts#L56
|
||||||
|
return 77 * r + 150 * g + 29 * b + 128 >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Percieved color difference defined by CIE94.
|
||||||
|
// See https://en.wikipedia.org/wiki/Color_difference#CIE94
|
||||||
|
//
|
||||||
|
// The result of 1.0 is a "just-noticiable difference".
|
||||||
|
//
|
||||||
|
// Other results interpretation (taken from http://zschuessler.github.io/DeltaE/learn/):
|
||||||
|
// < 1.0 Not perceptible by human eyes.
|
||||||
|
// 1-2 Perceptible through close observation.
|
||||||
|
// 2-10 Perceptible at a glance.
|
||||||
|
// 11-49 Colors are more similar than opposite
|
||||||
|
// 100 Colors are exact opposite
|
||||||
|
function colorDeltaE94(rgb1, rgb2) {
|
||||||
|
const [l1, a1, b1] = xyz2lab(srgb2xyz(rgb1));
|
||||||
|
const [l2, a2, b2] = xyz2lab(srgb2xyz(rgb2));
|
||||||
|
const deltaL = l1 - l2;
|
||||||
|
const deltaA = a1 - a2;
|
||||||
|
const deltaB = b1 - b2;
|
||||||
|
const c1 = Math.sqrt(a1 ** 2 + b1 ** 2);
|
||||||
|
const c2 = Math.sqrt(a2 ** 2 + b2 ** 2);
|
||||||
|
const deltaC = c1 - c2;
|
||||||
|
let deltaH = deltaA ** 2 + deltaB ** 2 - deltaC ** 2;
|
||||||
|
deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH);
|
||||||
|
// The k1, k2, kL, kC, kH values for "graphic arts" applications.
|
||||||
|
// See https://en.wikipedia.org/wiki/Color_difference#CIE94
|
||||||
|
const k1 = 0.045;
|
||||||
|
const k2 = 0.015;
|
||||||
|
const kL = 1;
|
||||||
|
const kC = 1;
|
||||||
|
const kH = 1;
|
||||||
|
const sC = 1.0 + k1 * c1;
|
||||||
|
const sH = 1.0 + k2 * c1;
|
||||||
|
const sL = 1;
|
||||||
|
return Math.sqrt((deltaL / sL / kL) ** 2 + (deltaC / sC / kC) ** 2 + (deltaH / sH / kH) ** 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sRGB -> 1-normalized XYZ (i.e. Y ∈ [0, 1]) with D65 illuminant
|
||||||
|
// See https://en.wikipedia.org/wiki/SRGB#From_sRGB_to_CIE_XYZ
|
||||||
|
function srgb2xyz(rgb) {
|
||||||
|
let r = rgb[0] / 255;
|
||||||
|
let g = rgb[1] / 255;
|
||||||
|
let b = rgb[2] / 255;
|
||||||
|
r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
|
||||||
|
g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
|
||||||
|
b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
|
||||||
|
return [r * 0.4124 + g * 0.3576 + b * 0.1805, r * 0.2126 + g * 0.7152 + b * 0.0722, r * 0.0193 + g * 0.1192 + b * 0.9505];
|
||||||
|
}
|
||||||
|
const sigma_pow2 = 6 * 6 / 29 / 29;
|
||||||
|
const sigma_pow3 = 6 * 6 * 6 / 29 / 29 / 29;
|
||||||
|
|
||||||
|
// 1-normalized CIE XYZ with D65 to L*a*b*
|
||||||
|
// See https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB
|
||||||
|
function xyz2lab(xyz) {
|
||||||
|
const x = xyz[0] / 0.950489;
|
||||||
|
const y = xyz[1];
|
||||||
|
const z = xyz[2] / 1.088840;
|
||||||
|
const fx = x > sigma_pow3 ? x ** (1 / 3) : x / 3 / sigma_pow2 + 4 / 29;
|
||||||
|
const fy = y > sigma_pow3 ? y ** (1 / 3) : y / 3 / sigma_pow2 + 4 / 29;
|
||||||
|
const fz = z > sigma_pow3 ? z ** (1 / 3) : z / 3 / sigma_pow2 + 4 / 29;
|
||||||
|
const l = 116 * fy - 16;
|
||||||
|
const a = 500 * (fx - fy);
|
||||||
|
const b = 200 * (fy - fz);
|
||||||
|
return [l, a, b];
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user