Browse Source

Initial commit

pull/24/head
Pavel Feldman 2 years ago
committed by Andrey Lushnikov
parent
commit
9ba375c063
  1. 19
      .appveyor.yml
  2. 17
      .ci/node10/Dockerfile.linux
  3. 17
      .ci/node12/Dockerfile.linux
  4. 17
      .ci/node8/Dockerfile.linux
  5. 47
      .cirrus.yml
  6. 9
      .editorconfig
  7. 12
      .eslintignore
  8. 107
      .eslintrc.js
  9. 81
      .gitignore
  10. 44
      .npmignore
  11. 48
      .travis.yml
  12. 23
      DeviceDescriptors.js
  13. 17
      Errors.js
  14. 31
      browser_patches/README.md
  15. 58
      browser_patches/check_cdn.sh
  16. 136
      browser_patches/do_checkout.sh
  17. 115
      browser_patches/export.sh
  18. 1
      browser_patches/firefox/.gitignore
  19. 1
      browser_patches/firefox/BASE_REVISION
  20. 2
      browser_patches/firefox/BUILD_NUMBER
  21. 22
      browser_patches/firefox/README.md
  22. 53
      browser_patches/firefox/archive.sh
  23. 45
      browser_patches/firefox/build.sh
  24. 4895
      browser_patches/firefox/patches/0001-chore-bootstrap.patch
  25. 68
      browser_patches/upload.sh
  26. 1
      browser_patches/webkit/.gitignore
  27. 1
      browser_patches/webkit/BASE_REVISION
  28. 2
      browser_patches/webkit/BUILD_NUMBER
  29. 85
      browser_patches/webkit/archive.sh
  30. 29
      browser_patches/webkit/build.sh
  31. 6
      browser_patches/webkit/concat_protocol.js
  32. 5890
      browser_patches/webkit/patches/0001-chore-bootstrap.patch
  33. 40
      browser_patches/webkit/pw_run.sh
  34. 30
      chromium.js
  35. 4107
      docs/api.md
  36. 36
      examples/block-images.js
  37. 48
      examples/custom-event.js
  38. 44
      examples/detect-sniff.js
  39. 33
      examples/pdf.js
  40. 35
      examples/proxy.js
  41. 29
      examples/screenshot-fullpage.js
  42. 27
      examples/screenshot.js
  43. 55
      examples/search.js
  44. 29
      firefox.js
  45. 137
      install.js
  46. 3
      misc/00-playwright-prefs.js
  47. 59
      misc/install-preferences.js
  48. 212
      misc/playwright.cfg
  49. 75
      package.json
  50. 16
      src/.eslintrc.js
  51. 6
      src/ConnectionTransport.ts
  52. 871
      src/DeviceDescriptors.ts
  53. 26
      src/Errors.ts
  54. 55
      src/Events.ts
  55. 45
      src/TimeoutSettings.ts
  56. 285
      src/USKeyboardLayout.ts
  57. 88
      src/api.ts
  58. 373
      src/chromium/Accessibility.ts
  59. 220
      src/chromium/Browser.ts
  60. 103
      src/chromium/BrowserContext.ts
  61. 261
      src/chromium/BrowserFetcher.ts
  62. 219
      src/chromium/Connection.ts
  63. 298
      src/chromium/Coverage.ts
  64. 580
      src/chromium/DOMWorld.ts
  65. 70
      src/chromium/Dialog.ts
  66. 51
      src/chromium/EmulationManager.ts
  67. 171
      src/chromium/ExecutionContext.ts
  68. 264
      src/chromium/Frame.ts
  69. 316
      src/chromium/FrameManager.ts
  70. 337
      src/chromium/Input.ts
  71. 578
      src/chromium/JSHandle.ts
  72. 404
      src/chromium/Launcher.ts
  73. 176
      src/chromium/LifecycleWatcher.ts
  74. 93
      src/chromium/Multimap.ts
  75. 657
      src/chromium/NetworkManager.ts
  76. 1073
      src/chromium/Page.ts
  77. 73
      src/chromium/PipeTransport.ts
  78. 66
      src/chromium/Playwright.ts
  79. 134
      src/chromium/Target.ts
  80. 30
      src/chromium/TaskQueue.ts
  81. 66
      src/chromium/Tracing.ts
  82. 58
      src/chromium/WebSocketTransport.ts
  83. 63
      src/chromium/Worker.ts
  84. 97
      src/chromium/protocolHelper.ts
  85. 273
      src/firefox/Accessibility.ts
  86. 334
      src/firefox/Browser.ts
  87. 283
      src/firefox/BrowserFetcher.ts
  88. 203
      src/firefox/Connection.ts
  89. 503
      src/firefox/DOMWorld.ts
  90. 51
      src/firefox/Dialog.ts
  91. 100
      src/firefox/ExecutionContext.ts
  92. 394
      src/firefox/FrameManager.ts
  93. 292
      src/firefox/Input.ts
  94. 360
      src/firefox/JSHandle.ts
  95. 268
      src/firefox/Launcher.ts
  96. 125
      src/firefox/NavigationWatchdog.ts
  97. 365
      src/firefox/NetworkManager.ts
  98. 640
      src/firefox/Page.ts
  99. 66
      src/firefox/Playwright.ts
  100. 89
      src/firefox/WebSocketTransport.ts

19
.appveyor.yml

@ -0,0 +1,19 @@
environment:
matrix:
- nodejs_version: "8.16.0"
FLAKINESS_DASHBOARD_NAME: Appveyor Chromium (Win + node8)
FLAKINESS_DASHBOARD_PASSWORD:
secure: g66jP+j6C+hkXLutBV9fdxB5fRJgcQQzy93SgQzXUmcCl/RjkJwnzyHvX0xfCVnv
build: off
install:
- ps: $env:FLAKINESS_DASHBOARD_BUILD_URL="https://ci.appveyor.com/project/aslushnikov/playwright/builds/$env:APPVEYOR_BUILD_ID/job/$env:APPVEYOR_JOB_ID"
- ps: Install-Product node $env:nodejs_version
- npm install
- if "%nodejs_version%" == "8.16.0" (
npm run lint &&
npm run coverage &&
npm run test-doclint &&
npm run test-types
)

17
.ci/node10/Dockerfile.linux

@ -0,0 +1,17 @@
FROM node:10
RUN apt-get update && \
apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser
# Run everything after as non-privileged user.
USER pptruser

17
.ci/node12/Dockerfile.linux

@ -0,0 +1,17 @@
FROM node:12
RUN apt-get update && \
apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser
# Run everything after as non-privileged user.
USER pptruser

17
.ci/node8/Dockerfile.linux

@ -0,0 +1,17 @@
FROM node:8.11.3
RUN apt-get update && \
apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser
# Run everything after as non-privileged user.
USER pptruser

47
.cirrus.yml

@ -0,0 +1,47 @@
env:
DISPLAY: :99.0
FLAKINESS_DASHBOARD_PASSWORD: ENCRYPTED[b3e207db5d153b543f219d3c3b9123d8321834b783b9e45ac7d380e026ab3a56398bde51b521ac5859e7e45cb95d0992]
FLAKINESS_DASHBOARD_NAME: Cirrus ${CIRRUS_TASK_NAME}
FLAKINESS_DASHBOARD_BUILD_URL: https://cirrus-ci.com/task/${CIRRUS_TASK_ID}
task:
matrix:
- name: Chromium (node8 + linux)
container:
dockerfile: .ci/node8/Dockerfile.linux
- name: Chromium (node10 + linux)
container:
dockerfile: .ci/node10/Dockerfile.linux
- name: Chromium (node12 + linux)
container:
dockerfile: .ci/node12/Dockerfile.linux
xvfb_start_background_script: Xvfb :99 -ac -screen 0 1024x768x24
install_script: npm install --unsafe-perm
lint_script: npm run lint
coverage_script: npm run coverage
test_doclint_script: npm run test-doclint
test_types_script: npm run test-types
task:
matrix:
- name: Firefox (node8 + linux)
container:
dockerfile: .ci/node8/Dockerfile.linux
xvfb_start_background_script: Xvfb :99 -ac -screen 0 1024x768x24
install_script: npm install --unsafe-perm
test_script: npm run funit
task:
osx_instance:
image: high-sierra-base
name: Chromium (node8 + macOS)
env:
HOMEBREW_NO_AUTO_UPDATE: 1
node_install_script:
- brew install node@8
- brew link --force node@8
install_script: npm install --unsafe-perm
lint_script: npm run lint
coverage_script: npm run coverage
test_doclint_script: npm run test-doclint
test_types_script: npm run test-types

9
.editorconfig

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

12
.eslintignore

@ -0,0 +1,12 @@
test/assets/modernizr.js
third_party/*
utils/browser/playwright-web.js
utils/doclint/check_public_api/test/
utils/testrunner/examples/
node6/*
node6-test/*
node6-testrunner/*
lib/
*.js
src/chromium/protocol.d.ts
src/webkit/protocol.d.ts

107
.eslintrc.js

@ -0,0 +1,107 @@
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 9,
sourceType: 'module',
},
/**
* ESLint rules
*
* All available rules: http://eslint.org/docs/rules/
*
* Rules take the following form:
* "rule-name", [severity, { opts }]
* Severity: 2 == error, 1 == warning, 0 == off.
*/
"rules": {
'@typescript-eslint/no-unused-vars': [2, {args: 'none'}],
/**
* Enforced rules
*/
// syntax preferences
"quotes": [2, "single", {
"avoidEscape": true,
"allowTemplateLiterals": true
}],
"semi": 2,
"no-extra-semi": 2,
"comma-style": [2, "last"],
"wrap-iife": [2, "inside"],
"spaced-comment": [2, "always", {
"markers": ["*"]
}],
"eqeqeq": [2],
"arrow-body-style": [2, "as-needed"],
"accessor-pairs": [2, {
"getWithoutSet": false,
"setWithoutGet": false
}],
"brace-style": [2, "1tbs", {"allowSingleLine": true}],
"curly": [2, "multi-or-nest", "consistent"],
"new-parens": 2,
"func-call-spacing": 2,
"arrow-parens": [2, "as-needed"],
"prefer-const": 2,
"quote-props": [2, "consistent"],
// anti-patterns
"no-var": 2,
"no-with": 2,
"no-multi-str": 2,
"no-caller": 2,
"no-implied-eval": 2,
"no-labels": 2,
"no-new-object": 2,
"no-octal-escape": 2,
"no-self-compare": 2,
"no-shadow-restricted-names": 2,
"no-cond-assign": 2,
"no-debugger": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-empty-character-class": 2,
"no-unreachable": 2,
"no-unsafe-negation": 2,
"radix": 2,
"valid-typeof": 2,
"no-implicit-globals": [2],
// es2015 features
"require-yield": 2,
"template-curly-spacing": [2, "never"],
// spacing details
"space-infix-ops": 2,
"space-in-parens": [2, "never"],
"space-before-function-paren": [2, "never"],
"no-whitespace-before-property": 2,
"keyword-spacing": [2, {
"overrides": {
"if": {"after": true},
"else": {"after": true},
"for": {"after": true},
"while": {"after": true},
"do": {"after": true},
"switch": {"after": true},
"return": {"after": true}
}
}],
"arrow-spacing": [2, {
"after": true,
"before": true
}],
// file whitespace
"no-multiple-empty-lines": [2, {"max": 2}],
"no-mixed-spaces-and-tabs": 2,
"no-trailing-spaces": 2,
"linebreak-style": [ process.platform === "win32" ? 0 : 2, "unix" ],
"indent": [2, 2, { "SwitchCase": 1, "CallExpression": {"arguments": 2}, "MemberExpression": 2 }],
"key-spacing": [2, {
"beforeColon": false
}]
}
};

81
.gitignore

@ -1,61 +1,20 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
/node_modules/
/test/output-chromium
/test/output-firefox
/test/test-user-data-dir*
/.local-chromium/
/.local-browser/
/.local-webkit/
/.dev_profile*
.DS_Store
*.swp
*.pyc
.vscode
package-lock.json
yarn.lock
/node6
/src/chromium/protocol.d.ts
/src/webkit/protocol.d.ts
/utils/browser/playwright-web.js
/index.d.ts
lib/

44
.npmignore

@ -0,0 +1,44 @@
.appveyor.yml
.gitattributes
# no longer generated, but old checkouts might still have it
node6
# exclude all tests
test
utils/node6-transform
# exclude source files
src
# repeats from .gitignore
node_modules
.local-chromium
.local-browser
.dev_profile*
.DS_Store
*.swp
*.pyc
.vscode
package-lock.json
/node6/test
/node6/utils
/test
/utils
/docs
yarn.lock
# other
/.ci
/examples
.appveyour.yml
.cirrus.yml
.editorconfig
.eslintignore
.eslintrc.js
.travis.yml
README.md
tsconfig.json
# exclude types, see https://github.com/GoogleChrome/puppeteer/issues/3878
/index.d.ts

48
.travis.yml

@ -0,0 +1,48 @@
language: node_js
dist: trusty
addons:
apt:
packages:
# This is required to run new chrome on old trusty
- libnss3
notifications:
email: false
cache:
directories:
- node_modules
# allow headful tests
before_install:
- "sysctl kernel.unprivileged_userns_clone=1"
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
script:
- 'if [ "$NODE8" = "true" ]; then npm run lint; fi'
- 'if [ "$NODE8" = "true" ]; then npm run coverage; fi'
- 'if [ "$FIREFOX" = "true" ]; then npm run funit; fi'
- 'if [ "$NODE8" = "true" ]; then npm run test-doclint; fi'
- 'if [ "$NODE8" = "true" ]; then npm run test-types; fi'
- 'if [ "$NODE8" = "true" ]; then npm run bundle; fi'
- 'if [ "$NODE8" = "true" ]; then npm run unit-bundle; fi'
jobs:
include:
- node_js: "8.16.0"
env:
- NODE8=true
- FLAKINESS_DASHBOARD_NAME="Travis Chromium (node8 + linux)"
- FLAKINESS_DASHBOARD_BUILD_URL="${TRAVIS_JOB_WEB_URL}"
- node_js: "8.16.0"
env:
- FIREFOX=true
- FLAKINESS_DASHBOARD_NAME="Travis Firefox (node8 + linux)"
- FLAKINESS_DASHBOARD_BUILD_URL="${TRAVIS_JOB_WEB_URL}"
before_deploy: "npm run apply-next-version"
deploy:
provider: npm
email: aslushnikov@gmail.com
api_key:
secure: Ng8o2KwJf90XCBNgUKK3jRZnwtdBSJatjYNmZBERJEqBWFTadFAp1NdhxZaqjnuG8aFYaH5bRJdL+EQBYUksVCbrv/gcaXeEFkwsfPfVX1QXGqu7NnZmtme2hbxppLQ7dEJ8hz2Z9K4vehqVOxmLabxvoupOumxEQMLCphVHh2FOmsm/S5JrRZqZ4V9k76eIc0/PiyfXNMdx5WTZjHbIRDIHRy9nqOXjFp2Rx3PMa3uU2fS8mTshYEYs151TA6e6VdHjqmBwEQC/M5tXbDlLCMNUr4JBtLTcL4OipNYjzkwD1N2xYlbSRqtvqqF4ifdvFhoI65a31GinlMC7Z/SH1Zy+d+/z3Mo7D63eYcsJVnsg9OYxTFy2piUntr0JqTBHtQoe/CvGxJmkcVt+H6YSkcBibSG9s9tG3qpAD5wBCFqqOYnfClX+YZziEd+Hngd9inxAf87qdvgVIZ5tPD2dygtE+te2/qoEHtvccv/HuS8MxNj5iKwlP7JaBPM6uAkazYqZP2R99I2ph9gNOEVuQLtk+3+OIdb8HWrEKUrJBgKhdKY1dvcKYElI+D8NRlyzrr6BnZfudACuAt2EtfKpfJ3mL+iRMFdBJ3ntLt93xBrB+j4z3pD0iWZcg1g3I742PFzQEHzyd/DDTP1yRTUoJeQWwoQRJyNO1m6Qk4wx77c=
on:
branch: master
condition: "$NODE8 = true"
skip_cleanup: true
tag: next

23
DeviceDescriptors.js

@ -0,0 +1,23 @@
/**
* 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 {DeviceDescriptors} = require('./lib/DeviceDescriptors');
const descriptors = DeviceDescriptors.slice();
module.exports = descriptors;
for (const device of descriptors)
module.exports[device.name] = device;

17
Errors.js

@ -0,0 +1,17 @@
/**
* Copyright 2018 Google Inc. 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.
*/
module.exports = require('./lib/Errors');

31
browser_patches/README.md

@ -0,0 +1,31 @@
# Compiling and Uploading Builds
### 1. Getting code
```sh
$ ./checkout.sh firefox/ # or ./checkout.sh webkit/
```
This command will create a `./firefox/checkout` folder that contains firefox GIT checkout.
Checkout current branch will be set to `pwdev` and it will have all additional changes
applied to the browser atop of the `./firefox/BASE_REVISION` version.
### 2. Compiling
> **NOTE** You might need to prepare your host environment according to browser build instructions:
> - [firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions)
> - [webkit](https://webkit.org/building-webkit/)
```sh
$ ./firefox/build.sh # or ./webkit/build.sh
```
### 3. Uploading builds to Azure CDN
> **NOTE** You should have `$AZ_ACCOUNT_KEY` and `$AZ_ACCOUNT_NAME` variables set in your environment.
```sh
$ ./upload.sh firefox/ # or ./upload.sh webkit/
```
This will package archives and upload builds to Azure CDN.

58
browser_patches/check_cdn.sh

@ -0,0 +1,58 @@
#!/bin/bash
set -e
set +x
HOST="https://playwrightaccount.blob.core.windows.net/builds"
ARCHIVES=(
"$HOST/firefox/%s/firefox-mac.zip"
"$HOST/firefox/%s/firefox-linux.zip"
"$HOST/firefox/%s/firefox-win.zip"
"$HOST/webkit/%s/minibrowser-linux.zip"
"$HOST/webkit/%s/minibrowser-mac10.14.zip"
"$HOST/webkit/%s/minibrowser-mac10.15.zip"
)
ALIASES=(
"FF-MAC"
"FF-LINUX"
"FF-WIN"
"WK-MAC-10.14"
"WK-MAC-10.15"
"WK-LINUX"
)
COLUMN="%-15s"
# COLORS
RED=$'\e[1;31m'
GRN=$'\e[1;32m'
YEL=$'\e[1;33m'
END=$'\e[0m'
# Read start revision if there's any.
REVISION=$(git rev-parse HEAD)
if [[ $# == 1 ]]; then
if ! git rev-parse $1; then
echo "ERROR: there is no $REVISION in this repo - pull from upstream?"
exit 1
fi
REVISION=$(git rev-parse $1)
fi
printf "%12s" ""
for i in "${ALIASES[@]}"; do
printf $COLUMN $i
done
printf "\n"
while true; do
printf "%-12s" ${REVISION:0:10}
for i in "${ARCHIVES[@]}"; do
URL=$(printf $i $REVISION)
if [[ $(curl -s -L -I $URL | head -1 | cut -f2 -d' ') == 200 ]]; then
printf ${GRN}$COLUMN${END} "YES"
else
printf ${RED}$COLUMN${END} "NO"
fi
done;
echo
REVISION=$(git rev-parse $REVISION^)
done;

136
browser_patches/do_checkout.sh

@ -0,0 +1,136 @@
#!/bin/bash
set -e
set +x
function cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
echo "usage: do_something.sh [firefox|webkit]"
echo
echo "Produces a browser checkout ready to be built."
echo
exit 0
fi
if [[ $# == 0 ]]; then
echo "missing browser: 'firefox' or 'webkit'"
echo "try './do_something.sh --help' for more information"
exit 1
fi
# FRIENDLY_CHECKOUT_PATH is used only for logging.
FRIENDLY_CHECKOUT_PATH="";
CHECKOUT_PATH=""
# Export path is where we put the patches and BASE_REVISION
REMOTE_URL=""
BASE_BRANCH=""
if [[ ("$1" == "firefox") || ("$1" == "firefox/") ]]; then
# we always apply our patches atop of beta since it seems to get better
# reliability guarantees.
BASE_BRANCH="beta"
FRIENDLY_CHECKOUT_PATH="//browser_patches/firefox/checkout";
CHECKOUT_PATH="$PWD/firefox/checkout"
REMOTE_URL="https://github.com/mozilla/gecko-dev"
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") ]]; then
# webkit has only a master branch.
BASE_BRANCH="master"
FRIENDLY_CHECKOUT_PATH="//browser_patches/webkit/checkout";
CHECKOUT_PATH="$PWD/webkit/checkout"
REMOTE_URL=""
REMOTE_URL="https://github.com/webkit/webkit"
else
echo ERROR: unknown browser to export - "$1"
exit 1
fi
# if there's no checkout folder - checkout one.
if ! [[ -d $CHECKOUT_PATH ]]; then
echo "-- $FRIENDLY_CHECKOUT_PATH is missing - checking out.."
git clone --single-branch --branch $BASE_BRANCH $REMOTE_URL $CHECKOUT_PATH
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH folder - OK"
fi
# if folder exists but not a git repository - bail out.
if ! [[ -d $CHECKOUT_PATH/.git ]]; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH is not a git repository! Remove it and re-run the script."
exit 1
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH is a git repo - OK"
fi
# Switch to git repository.
cd $CHECKOUT_PATH
# Check if git repo is dirty.
if [[ -n $(git status -s) ]]; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH has dirty GIT state - commit everything and re-run the script."
exit 1
fi
if [[ $(git config --get remote.origin.url) == "$REMOTE_URL" ]]; then
echo "-- checking git origin url to point to $REMOTE_URL - OK";
else
echo "ERROR: git origin url DOES NOT point to $REMOTE_URL. Remove $FRIENDLY_CHECKOUT_PATH and re-run the script.";
exit 1
fi
# if there's no "BASE_BRANCH" branch - bail out.
if ! git show-ref --verify --quiet refs/heads/$BASE_BRANCH; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH/ does not have '$BASE_BRANCH' branch! Remove checkout/ and re-run the script."
exit 1
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH has 'beta' branch - OK"
fi
if ! [[ -z $(git log --oneline origin/$BASE_BRANCH..$BASE_BRANCH) ]]; then
echo "ERROR: branch '$BASE_BRANCH' and branch 'origin/$BASE_BRANCH' have diverged - bailing out. Remove checkout/ and re-run the script."
exit 1;
else
echo "-- checking that $BASE_BRANCH and origin/$BASE_BRANCH are not diverged - OK"
fi
git checkout $BASE_BRANCH
git pull origin $BASE_BRANCH
PINNED_COMMIT=$(cat ../BASE_REVISION)
if ! git cat-file -e $PINNED_COMMIT^{commit}; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH/ does not include the BASE_REVISION (@$PINNED_COMMIT). Remove checkout/ and re-run the script."
exit 1
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH repo has BASE_REVISION (@$PINNED_COMMIT) commit - OK"
fi
# If there's already a PWDEV branch than we should check if it's fine to reset all changes
# to it.
if git show-ref --verify --quiet refs/heads/pwdev; then
read -p "Do you want to reset 'PWDEV' branch? (ALL CHANGES WILL BE LOST) Y/n " -n 1 -r
echo
# if it's not fine to reset branch - bail out.
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo "If you want to keep the branch, than I can't do much! Bailing out!"
exit 1
else
git checkout pwdev
git reset --hard $PINNED_COMMIT
echo "-- PWDEV now points to BASE_REVISION (@$PINNED_COMMIT)"
fi
else
# Otherwise just create a new branch.
git checkout -b pwdev
git reset --hard $PINNED_COMMIT
echo "-- created 'pwdev' branch that points to BASE_REVISION (@$PINNED_COMMIT)."
fi
echo "-- applying all patches"
git am ../patches/*
echo
echo
echo "DONE. Browser is ready to be built."

115
browser_patches/export.sh

@ -0,0 +1,115 @@
#!/bin/bash
set -e
set +x
cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
echo "usage: export.sh [firefox|webkit] [custom_checkout_path]"
echo
echo "Exports BASE_REVISION and patch from the checkout to browser folder."
echo
echo "You can optionally specify custom_checkout_path if you have browser checkout somewhere else"
echo "and wish to export patches from it."
echo
exit 0
fi
if [[ $# == 0 ]]; then
echo "missing browser: 'firefox' or 'webkit'"
echo "try './export.sh --help' for more information"
exit 1
fi
# FRIENDLY_CHECKOUT_PATH is used only for logging.
FRIENDLY_CHECKOUT_PATH="";
CHECKOUT_PATH=""
# Export path is where we put the patches and BASE_REVISION
EXPORT_PATH=""
BASE_BRANCH=""
if [[ ("$1" == "firefox") || ("$1" == "firefox/") ]]; then
# we always apply our patches atop of beta since it seems to get better
# reliability guarantees.
BASE_BRANCH="origin/beta"
FRIENDLY_CHECKOUT_PATH="//browser_patches/firefox/checkout";
CHECKOUT_PATH="$PWD/firefox/checkout"
EXPORT_PATH="$PWD/firefox/"
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") ]]; then
# webkit has only a master branch.
BASE_BRANCH="origin/master"
FRIENDLY_CHECKOUT_PATH="//browser_patches/webkit/checkout";
CHECKOUT_PATH="$PWD/webkit/checkout"
EXPORT_PATH="$PWD/webkit/"
else
echo ERROR: unknown browser to export - "$1"
exit 1
fi
# we will use this just for beauty.
if [[ $# == 2 ]]; then
echo "WARNING: using custom checkout path $CHECKOUT_PATH"
CHECKOUT_PATH=$2
FRIENDLY_CHECKOUT_PATH="<custom_checkout>"
fi
# if there's no checkout folder - bail out.
if ! [[ -d $CHECKOUT_PATH ]]; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH is missing - nothing to export."
exit 1;
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH exists - OK"
fi
# if folder exists but not a git repository - bail out.
if ! [[ -d $CHECKOUT_PATH/.git ]]; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH is not a git repository! Nothing to export."
exit 1
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH is a git repo - OK"
fi
# Switch to git repository.
cd $CHECKOUT_PATH
# Check if git repo is dirty.
if [[ -n $(git status -s) ]]; then
echo "ERROR: $FRIENDLY_CHECKOUT_PATH has dirty GIT state - aborting export."
exit 1
else
echo "-- checking $FRIENDLY_CHECKOUT_PATH is clean - OK"
fi
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
MERGE_BASE=$(git merge-base $BASE_BRANCH $CURRENT_BRANCH)
echo "=============================================================="
echo " Repository: $FRIENDLY_CHECKOUT_PATH"
echo " Changes between branches: $BASE_BRANCH..$CURRENT_BRANCH"
echo " BASE_REVISION: $MERGE_BASE"
echo
read -p "Export? Y/n " -n 1 -r
echo
# if it's not fine to reset branch - bail out.
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Exiting."
exit 1
fi
echo $MERGE_BASE > $EXPORT_PATH/BASE_REVISION
git checkout -b tmpsquash_export_script $MERGE_BASE
git merge --squash $CURRENT_BRANCH
git commit -am "chore: bootstrap"
PATCH_NAME=$(git format-patch -1 HEAD)
mv $PATCH_NAME $EXPORT_PATH/patches/
git checkout $CURRENT_BRANCH
git branch -D tmpsquash_export_script
# Increment BUILD_NUMBER
BUILD_NUMBER=$(cat $EXPORT_PATH/BUILD_NUMBER)
BUILD_NUMBER=$((BUILD_NUMBER+1))
echo $BUILD_NUMBER > $EXPORT_PATH/BUILD_NUMBER

1
browser_patches/firefox/.gitignore

@ -0,0 +1 @@
/checkout

1
browser_patches/firefox/BASE_REVISION

@ -0,0 +1 @@
46ca28eadfe840021e2ea496fa6b26f924fa135b

2
browser_patches/firefox/BUILD_NUMBER

@ -0,0 +1,2 @@
1

22
browser_patches/firefox/README.md

@ -0,0 +1,22 @@
# Building Juggler (Linux & Mac)
1. Run `./do_checkout.sh` script. This will create a "checkout" folder with gecko-dev mirror from
GitHub and apply the PlayWright-specific patches.
2. Run `./do_build.sh` script to compile browser. Note: you'll need to follow [build instructions](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions) to setup host environment first.
# Updating `FIREFOX_REVISION` and `//patches/*`
The `./export.sh` script will export a patch that describes all the differences between the current branch in `./checkout`
and the `beta` branch in `./checkout`.
# Uploading to Azure CDN
Uploading requires having both `AZ_ACCOUNT_KEY` and `AZ_ACCOUNT_NAME` env variables to be defined.
The following sequence of steps will checkout, build and upload build to Azure CDN on both Linux and Mac:
```sh
$ ./do_checkout.sh
$ ./build.sh
$ ./upload.sh
```

53
browser_patches/firefox/archive.sh

@ -0,0 +1,53 @@
#!/bin/bash
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
echo "usage: $0"
echo
echo "Generate distributable .zip archive from ./checkout folder that was previously built."
echo
exit 0
fi
set -e
set -x
createZIPForLinuxOrMac() {
cd checkout
local zipname=$1
local OBJ_FOLDER=$(ls -1 | grep obj-)
if [[ $OBJ_FOLDER == "" ]]; then
echo "ERROR: cannot find obj-* folder in the checkout/. Did you build?"
exit 1;
fi
if ! [[ -d $OBJ_FOLDER/dist/firefox ]]; then
echo "ERROR: cannot find $OBJ_FOLDER/dist/firefox folder in the checkout/. Did you build?"
exit 1;
fi
# Copy the libstdc++ version we linked against.
# TODO(aslushnikov): this won't be needed with official builds.
if [[ "$(uname)" == "Linux" ]]; then
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 $OBJ_FOLDER/dist/firefox/libstdc++.so.6
fi
# tar resulting directory and cleanup TMP.
cd $OBJ_FOLDER/dist
zip -r ../../../$zipname firefox
cd -
}
cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
if [[ "$(uname)" == "Darwin" ]]; then
createZIPForLinuxOrMac "firefox-mac.zip"
elif [[ "$(uname)" == "Linux" ]]; then
createZIPForLinuxOrMac "firefox-linux.zip"
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi

45
browser_patches/firefox/build.sh

@ -0,0 +1,45 @@
#!/bin/bash
set -e
set +x
function cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
cd checkout
if ! [[ $(git rev-parse --abbrev-ref HEAD) == "pwdev" ]]; then
echo "ERROR: Cannot build any branch other than PWDEV"
exit 1;
else
echo "-- checking git branch is PWDEV - OK"
fi
if [[ "$(uname)" == "Darwin" ]]; then
# Firefox currently does not build on 10.15 out of the box - it requires SDK for 10.14.
# Make sure the SDK is out there.
if [[ $(sw_vers -productVersion) == "10.15" ]]; then
if ! [[ -d $HOME/SDK-archive/MacOSX10.14.sdk ]]; then
echo "As of Nov 2019, Firefox does not build on Mac 10.15 without 10.14 SDK."
echo "Check out instructions on getting 10.14 sdk at https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Mac_OS_X_Prerequisites"
echo "and make sure to put SDK to $HOME/SDK-archive/MacOSX10.14.sdk/"
exit 1
else
echo "-- configuting .mozconfig with 10.14 SDK path"
echo "ac_add_options --with-macos-sdk=$HOME/SDK-archive/MacOSX10.14.sdk/" > .mozconfig
fi
fi
echo "-- building on Mac"
elif [[ "$(uname)" == "Linux" ]]; then
echo "-- building on Linux"
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi
./mach build
./mach package

4895
browser_patches/firefox/patches/0001-chore-bootstrap.patch
File diff suppressed because it is too large
View File

68
browser_patches/upload.sh

@ -0,0 +1,68 @@
#!/bin/bash
set -e
set +x
cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
echo "usage: $0 [firefox|webkit]"
echo
echo "Archive and upload a browser"
echo
echo "NOTE: \$AZ_ACCOUNT_KEY (azure account name) and \$AZ_ACCOUNT_NAME (azure account name)"
echo "env variables are required to upload builds to CDN."
exit 0
fi
if [[ $# == 0 ]]; then
echo "missing browser: 'firefox' or 'webkit'"
echo "try '$0 --help' for more information"
exit 1
fi
if [[ (-z $AZ_ACCOUNT_KEY) || (-z $AZ_ACCOUNT_NAME) ]]; then
echo "ERROR: Either \$AZ_ACCOUNT_KEY or \$AZ_ACCOUNT_NAME environment variable is missing."
echo " 'Azure Account Name' and 'Azure Account Key' secrets that are required"
echo " to upload builds ot Azure CDN."
exit 1
fi
ARCHIVE_SCRIPT=""
BROWSER_NAME=""
BUILD_NUMBER=""
if [[ ("$1" == "firefox") || ("$1" == "firefox/") ]]; then
# we always apply our patches atop of beta since it seems to get better
# reliability guarantees.
ARCHIVE_FOLDER="$PWD/firefox"
BUILD_NUMBER=$(cat "$PWD/firefox/BUILD_NUMBER")
ARCHIVE_SCRIPT="$PWD/firefox/archive.sh"
BROWSER_NAME="firefox"
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") ]]; then
ARCHIVE_FOLDER="$PWD/webkit"
BUILD_NUMBER=$(cat "$PWD/webkit/BUILD_NUMBER")
ARCHIVE_SCRIPT="$PWD/webkit/archive.sh"
BROWSER_NAME="webkit"
else
echo ERROR: unknown browser to export - "$1"
exit 1
fi
if ! [[ -z $(ls $ARCHIVE_FOLDER | grep '.zip') ]]; then
echo ERROR: .zip file already exists in $ARCHIVE_FOLDER!
echo Remove manually all zip files and re-run the script.
exit 1
fi
$ARCHIVE_SCRIPT
ZIP_NAME=$(ls $ARCHIVE_FOLDER | grep '.zip')
ZIP_PATH=$ARCHIVE_FOLDER/$ZIP_NAME
BLOB_NAME="$BROWSER_NAME/$BUILD_NUMBER/$ZIP_NAME"
az storage blob upload -c builds --account-key $AZ_ACCOUNT_KEY --account-name $AZ_ACCOUNT_NAME -f $ZIP_PATH -n "$BLOB_NAME"
echo "Uploaded $(du -h "$ZIP_PATH" | awk '{print $1}') as $BLOB_NAME"
rm $ZIP_PATH

1
browser_patches/webkit/.gitignore

@ -0,0 +1 @@
/checkout

1
browser_patches/webkit/BASE_REVISION

@ -0,0 +1 @@
cadee71e3e832cc0b78184a714ade07d9a6d3173

2
browser_patches/webkit/BUILD_NUMBER

@ -0,0 +1,2 @@
1

85
browser_patches/webkit/archive.sh

@ -0,0 +1,85 @@
#!/bin/bash
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
echo "usage: $0"
echo
echo "Generate distributable .zip archive from ./checkout folder that was previously built."
echo
exit 0
fi
set -e
set -x
main() {
cd checkout
if [[ "$(uname)" == "Darwin" ]]; then
createZipForMac
elif [[ "$(uname)" == "Linux" ]]; then
createZipForLinux
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi
}
createZipForLinux() {
# create a TMP directory to copy all necessary files
local tmpdir=$(mktemp -d -t webkit-deploy-XXXXXXXXXX)
mkdir -p $tmpdir
# copy all relevant binaries
cp -t $tmpdir ./WebKitBuild/Release/bin/MiniBrowser ./WebKitBuild/Release/bin/WebKit*Process
# copy runner
cp -t $tmpdir ../pw_run.sh
# copy protocol
node ../concat_protocol.js > $tmpdir/protocol.json
# copy all relevant shared objects
LD_LIBRARY_PATH="$PWD/WebKitBuild/DependenciesGTK/Root/lib" ldd WebKitBuild/Release/bin/MiniBrowser | grep -o '[^ ]*WebKitBuild/[^ ]*' | xargs cp -t $tmpdir
# we failed to nicely build libgdk_pixbuf - expect it in the env
rm $tmpdir/libgdk_pixbuf*
# tar resulting directory and cleanup TMP.
local zipname="minibrowser-linux.zip"
zip -jr ../$zipname $tmpdir
rm -rf $tmpdir
}
createZipForMac() {
# create a TMP directory to copy all necessary files
local tmpdir=$(mktemp -d)
# copy all relevant files
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.Networking.xpc
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.Plugin.64.xpc
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.WebContent.xpc
ditto {./WebKitBuild/Release,$tmpdir}/JavaScriptCore.framework
ditto {./WebKitBuild/Release,$tmpdir}/libwebrtc.dylib
ditto {./WebKitBuild/Release,$tmpdir}/MiniBrowser.app
ditto {./WebKitBuild/Release,$tmpdir}/PluginProcessShim.dylib
ditto {./WebKitBuild/Release,$tmpdir}/SecItemShim.dylib
ditto {./WebKitBuild/Release,$tmpdir}/WebCore.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebInspectorUI.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebKit.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebKitLegacy.framework
ditto {..,$tmpdir}/pw_run.sh
# copy protocol
node ../concat_protocol.js > $tmpdir/protocol.json
# zip resulting directory and cleanup TMP.
local MAC_MAJOR_MINOR_VERSION=$(sw_vers -productVersion | grep -o '^\d\+.\d\+')
local zipname="minibrowser-mac-$MAC_MAJOR_MINOR_VERSION.zip"
ditto -c -k $tmpdir ../$zipname
rm -rf $tmpdir
}
cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
main "$@"

29
browser_patches/webkit/build.sh

@ -0,0 +1,29 @@
#!/bin/bash
set -e
set +x
function cleanup() {
cd $OLD_DIR
}
OLD_DIR=$(pwd -P)
cd "$(dirname "$0")"
trap cleanup EXIT
cd checkout
if ! [[ $(git rev-parse --abbrev-ref HEAD) == "pwdev" ]]; then
echo "ERROR: Cannot build any branch other than PWDEV"
exit 1;
else
echo "-- checking git branch is PWDEV - OK"
fi
if [[ "$(uname)" == "Darwin" ]]; then
./Tools/Scripts/build-webkit --release
elif [[ "$(uname)" == "Linux" ]]; then
./Tools/Scripts/build-webkit --gtk --release MiniBrowser
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi

6
browser_patches/webkit/concat_protocol.js

@ -0,0 +1,6 @@
const fs = require('fs');
const path = require('path');
const protocolDir = path.join(__dirname, './checkout/Source/JavaScriptCore/inspector/protocol');
const files = fs.readdirSync(protocolDir).filter(f => f.endsWith('.json')).map(f => path.join(protocolDir, f));
const json = files.map(file => JSON.parse(fs.readFileSync(file)));
console.log(JSON.stringify(json));

5890
browser_patches/webkit/patches/0001-chore-bootstrap.patch
File diff suppressed because it is too large
View File

40
browser_patches/webkit/pw_run.sh

@ -0,0 +1,40 @@
#!/bin/bash
function runOSX() {
# if script is run as-is
if [ -d $SCRIPT_PATH/checkout/WebKitBuild/Release/MiniBrowser.app ]; then
DYLIB_PATH="$SCRIPT_PATH/checkout/WebKitBuild/Release"
elif [ -d $SCRIPT_PATH/MiniBrowser.app ]; then
DYLIB_PATH="$SCRIPT_PATH"
else
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
exit 1
fi
MINIBROWSER="$DYLIB_PATH/MiniBrowser.app/Contents/MacOS/MiniBrowser"
DYLD_FRAMEWORK_PATH=$DYLIB_PATH DYLD_LIBRARY_PATH=$DYLIB_PATH $MINIBROWSER "$@"
}
function runLinux() {
# if script is run as-is
if [ -d $SCRIPT_PATH/checkout/WebKitBuild ]; then
LD_PATH="$SCRIPT_PATH/checkout/WebKitBuild/DependenciesGTK/Root/lib:$SCRIPT_PATH/checkout/WebKitBuild/Release/bin"
MINIBROWSER="$SCRIPT_PATH/checkout/WebKitBuild/Release/bin/MiniBrowser"
elif [ -f $SCRIPT_PATH/MiniBrowser ]; then
LD_PATH="$SCRIPT_PATH"
MINIBROWSER="$SCRIPT_PATH/MiniBrowser"
else
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
exit 1
fi
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_PATH $MINIBROWSER "$@"
}
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
if [ "$(uname)" == "Darwin" ]; then
runOSX "$@"
elif [ "$(uname)" == "Linux" ]; then
runLinux "$@"
else
echo "ERROR: cannot run on this platform!" 1>&2
exit 1;
fi

30
chromium.js

@ -0,0 +1,30 @@
/**
* Copyright 2017 Google Inc. 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.
*/
const {helper} = require('./lib/helper');
const api = require('./lib/api');
for (const className in api.Chromium) {
// Playwright-web excludes certain classes from bundle, e.g. BrowserFetcher.
if (typeof api.Chromium[className] === 'function')
helper.installAsyncStackHooks(api.Chromium[className]);
}
// If node does not support async await, use the compiled version.
const {Playwright} = require('./lib/chromium/Playwright');
const packageJson = require('./package.json');
const isPlaywrightCore = packageJson.name === 'playwright-core';
module.exports = new Playwright(__dirname, packageJson.playwright.chromium_revision, isPlaywrightCore);

4107
docs/api.md
File diff suppressed because it is too large
View File

36
examples/block-images.js

@ -0,0 +1,36 @@
/**
* Copyright 2017 Google Inc., PhantomJS Authors 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.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'image')
request.abort();
else
request.continue();
});
await page.goto('https://news.google.com/news/');
await page.screenshot({path: 'news.png', fullPage: true});
await browser.close();
})();

48
examples/custom-event.js

@ -0,0 +1,48 @@
/**
* Copyright 2017 Google Inc. 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.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
// Define a window.onCustomEvent function on the page.
await page.exposeFunction('onCustomEvent', e => {
console.log(`${e.type} fired`, e.detail || '');
});
/**
* Attach an event listener to page to capture a custom event on page load/navigation.
* @param {string} type Event name.
* @return {!Promise}
*/
function listenFor(type) {
return page.evaluateOnNewDocument(type => {
document.addEventListener(type, e => {
window.onCustomEvent({type, detail: e.detail});
});
}, type);
}
await listenFor('app-ready'); // Listen for "app-ready" custom event on page load.
await page.goto('https://www.chromestatus.com/features', {waitUntil: 'networkidle0'});
await browser.close();
})();

44
examples/detect-sniff.js

@ -0,0 +1,44 @@
/**
* Copyright 2017 Google Inc., PhantomJS Authors 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.
*/
'use strict';
const playwright = require('playwright');
function sniffDetector() {
const userAgent = window.navigator.userAgent;
const platform = window.navigator.platform;
window.navigator.__defineGetter__('userAgent', function() {
window.navigator.sniffed = true;
return userAgent;
});
window.navigator.__defineGetter__('platform', function() {
window.navigator.sniffed = true;
return platform;
});
}
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.evaluateOnNewDocument(sniffDetector);
await page.goto('https://www.google.com', {waitUntil: 'networkidle2'});
console.log('Sniffed: ' + (await page.evaluate(() => !!navigator.sniffed)));
await browser.close();
})();

33
examples/pdf.js

@ -0,0 +1,33 @@
/**
* Copyright 2017 Google Inc. 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.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
// page.pdf() is currently supported only in headless mode.
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=753118
await page.pdf({
path: 'hn.pdf',
format: 'letter'
});
await browser.close();
})();

35
examples/proxy.js

@ -0,0 +1,35 @@
/**
* Copyright 2017 Google Inc. 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.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch({
// Launch chromium using a proxy server on port 9876.
// More on proxying:
// https://www.chromium.org/developers/design-documents/network-settings
args: [
'--proxy-server=127.0.0.1:9876',
// Use proxy for localhost URLs
'--proxy-bypass-list=<-loopback>',
]
});
const page = await browser.newPage();
await page.goto('https://google.com');
await browser.close();
})();

29
examples/screenshot-fullpage.js

@ -0,0 +1,29 @@
/**
* Copyright 2017 Google Inc. 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.
*/
'use strict';
const playwright = require('playwright');
const devices = require('playwright/DeviceDescriptors');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.emulate(devices['iPhone 6']);
await page.goto('https://www.nytimes.com/');
await page.screenshot({path: 'full.png', fullPage: true});
await browser.close();
})();

27
examples/screenshot.js

@ -0,0 +1,27 @@
/**
* Copyright 2017 Google Inc. 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.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.goto('http://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();

55
examples/search.js

@ -0,0 +1,55 @@
/**
* Copyright 2017 Google Inc. 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.
*/
/**
* @fileoverview Search developers.google.com/web for articles tagged
* "Headless Chrome" and scrape results from the results page.
*/
'use strict';
const playwright = require('playwright');
(async() => {
const browser = await playwright.launch();
const page = await browser.newPage();
await page.goto('https://developers.google.com/web/');
// Type into search box.
await page.type('#searchbox input', 'Headless Chrome');
// Wait for suggest overlay to appear and click "show all results".
const allResultsSelector = '.devsite-suggest-all-results';
await page.waitForSelector(allResultsSelector);
await page.click(allResultsSelector);
// Wait for the results page to load and display the results.
const resultsSelector = '.gsc-results .gsc-thumbnail-inside a.gs-title';
await page.waitForSelector(resultsSelector);
// Extract the results from the page.
const links = await page.evaluate(resultsSelector => {
const anchors = Array.from(document.querySelectorAll(resultsSelector));
return anchors.map(anchor => {
const title = anchor.textContent.split('|')[0].trim();
return `${title} - ${anchor.href}`;
});
}, resultsSelector);
console.log(links.join('\n'));
await browser.close();
})();

29
firefox.js

@ -0,0 +1,29 @@
/**
* Copyright 2017 Google Inc. 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