Merge branch 'master' into ff-use-workers
This commit is contained in:
commit
b9a81f42d0
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
We currently have 4 build bots that produce the following builds
|
We currently have 4 build bots that produce the following builds
|
||||||
- **[buildbot-linux]** Ubuntu 18.04 machine
|
- **[buildbot-linux]** Ubuntu 18.04 machine
|
||||||
- builds: `Webkit-Linux`, `Firefox-Linux`
|
- builds: `webkit-gtk`, `webkit-wpe`, `firefox-linux`
|
||||||
- **[buildbot-mac-10.14]** Mac 10.14 machine
|
- **[buildbot-mac-10.14]** Mac 10.14 machine
|
||||||
- builds: `WebKit-mac-10.14`, `Firefox-Mac`
|
- builds: `webKit-mac-10.14`, `firefox-mac`
|
||||||
- **[buildbot-mac-10.15]** machine
|
- **[buildbot-mac-10.15]** machine
|
||||||
- builds: `WebKit-mac-10.15`
|
- builds: `webkit-mac-10.15`
|
||||||
- **[buildbot-windows]** Windows 10 machine
|
- **[buildbot-windows]** Windows 10 machine
|
||||||
- builds: `Firefox-win32`, `Firefox-win64`, `webkit-win64`
|
- builds: `firefox-win32`, `firefox-win64`, `webkit-win64`
|
||||||
|
|
||||||
This document describes setting up bots infrastructure to produce
|
This document describes setting up bots infrastructure to produce
|
||||||
browser builds.
|
browser builds.
|
||||||
|
|
@ -105,6 +105,18 @@ The `core.longpaths` is needed for webkit since it has some very long layout pat
|
||||||
|
|
||||||
Run `c:\mozilla-build\start-shell.bat` and checkout PlayWright repo to `/c/playwright`.
|
Run `c:\mozilla-build\start-shell.bat` and checkout PlayWright repo to `/c/playwright`.
|
||||||
|
|
||||||
|
### 7. Create a c:\WEBKIT_WIN64_LIBS\ directory with win64 dlls
|
||||||
|
|
||||||
|
|
||||||
|
Create a new `c:\WEBKIT_WIN64_LIBS` folder and copy the following libraries from `C:\Windows\System32` into it:
|
||||||
|
- `msvcp140.dll`
|
||||||
|
- `vcruntime140.dll`
|
||||||
|
- `vcruntime140_1.dll`
|
||||||
|
|
||||||
|
> **NOTE**: these libraries are expected by `//browser_patches/webkit/archive.sh`.
|
||||||
|
|
||||||
|
This is necessary since mingw is a 32-bit application and cannot access the `C:\Windows\System32` folder due to [Windows FileSystem Redirector](https://docs.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector?redirectedfrom=MSDN). ([StackOverflow question](https://stackoverflow.com/questions/18982551/is-mingw-caching-windows-directory-contents))
|
||||||
|
|
||||||
## Running Build Loop
|
## Running Build Loop
|
||||||
|
|
||||||
1. Launch `c:\mozilla-build/start-shell.bat`
|
1. Launch `c:\mozilla-build/start-shell.bat`
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,9 @@ if [[ -n $(git status -s) ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh firefox >/tmp/$(basename $0)-firefox-log.log || true
|
../checkout_build_archive_upload.sh firefox-linux >/tmp/$(basename $0)--firefox-linux.log || true
|
||||||
|
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh webkit >/tmp/$(basename $0)-webkit-log.log || true
|
../checkout_build_archive_upload.sh webkit-gtk >/tmp/$(basename $0)--webkit-gtk.log || true
|
||||||
|
../checkout_build_archive_upload.sh webkit-wpe >/tmp/$(basename $0)--webkit-wpe.log || true
|
||||||
|
../checkout_build_archive_upload.sh webkit-gtk-wpe >/tmp/$(basename $0)--webkit-gtk-wpe.log || true
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ if [[ -n $(git status -s) ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh firefox >/tmp/$(basename $0)-firefox-log.log || true
|
../checkout_build_archive_upload.sh firefox-mac >/tmp/$(basename $0)--firefox-mac.log || true
|
||||||
|
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh webkit >/tmp/$(basename $0)-webkit-log.log || true
|
../checkout_build_archive_upload.sh webkit-mac-10.14 >/tmp/$(basename $0)--webkit-mac-10.14.log || true
|
||||||
|
|
|
||||||
|
|
@ -62,4 +62,4 @@ if [[ -n $(git status -s) ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh webkit >/tmp/$(basename $0)-webkit-log.log || true
|
../checkout_build_archive_upload.sh webkit-mac-10.15 >/tmp/$(basename $0)--webkit-mac-10.15.log || true
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ while true; do
|
||||||
iteration=$(( iteration + 1 ))
|
iteration=$(( iteration + 1 ))
|
||||||
echo "== ITERATION ${iteration} =="
|
echo "== ITERATION ${iteration} =="
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh webkit || true
|
../checkout_build_archive_upload.sh webkit-win64 || true
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh firefox || true
|
../checkout_build_archive_upload.sh firefox-win32 || true
|
||||||
git pull origin master
|
git pull origin master
|
||||||
../checkout_build_archive_upload.sh firefox-win64 || true
|
../checkout_build_archive_upload.sh firefox-win64 || true
|
||||||
newTimestamp=$(date +%s)
|
newTimestamp=$(date +%s)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ set -e
|
||||||
set +x
|
set +x
|
||||||
|
|
||||||
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
||||||
echo "usage: $(basename $0) [firefox|firefox-win64|webkit] [-f|--force]"
|
echo "usage: $(basename $0) [firefox-linux|firefox-win32|firefox-win64|webkit-gtk|webkit-wpe|webkit-gtk-wpe|webkit-win64|webkit-mac-10.14|webkit-mac-10.15] [-f|--force]"
|
||||||
echo
|
echo
|
||||||
echo "Prepares checkout under browser folder, applies patches, builds, archives, and uploades if build is missing."
|
echo "Prepares checkout under browser folder, applies patches, builds, archives, and uploades if build is missing."
|
||||||
echo "Script will bail out early if the build for the browser version is already present."
|
echo "Script will bail out early if the build for the browser version is already present."
|
||||||
|
|
@ -15,22 +15,75 @@ if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $# == 0 ]]; then
|
if [[ $# == 0 ]]; then
|
||||||
echo "missing browser: 'firefox' or 'webkit'"
|
echo "missing build flavor!"
|
||||||
echo "try './$(basename $0) --help' for more information"
|
echo "try './$(basename $0) --help' for more information"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CURRENT_HOST_OS="$(uname)"
|
||||||
|
CURRENT_HOST_OS_VERSION=""
|
||||||
|
if [[ "$CURRENT_HOST_OS" == "Darwin" ]]; then
|
||||||
|
CURRENT_HOST_OS_VERSION=$(sw_vers -productVersion | grep -o '^\d\+.\d\+')
|
||||||
|
fi
|
||||||
|
|
||||||
BROWSER_NAME=""
|
BROWSER_NAME=""
|
||||||
EXTRA_BUILD_ARGS=""
|
EXTRA_BUILD_ARGS=""
|
||||||
if [[ ("$1" == "firefox") || ("$1" == "firefox/") ]]; then
|
EXTRA_ARCHIVE_ARGS=""
|
||||||
|
BUILD_FLAVOR="$1"
|
||||||
|
EXPECTED_HOST_OS=""
|
||||||
|
EXPECTED_HOST_OS_VERSION=""
|
||||||
|
if [[ "$BUILD_FLAVOR" == "firefox-linux" ]]; then
|
||||||
BROWSER_NAME="firefox"
|
BROWSER_NAME="firefox"
|
||||||
elif [[ ("$1" == "firefox-win64") || ("$1" == "firefox-win64/") ]]; then
|
EXPECTED_HOST_OS="Linux"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "firefox-mac" ]]; then
|
||||||
|
BROWSER_NAME="firefox"
|
||||||
|
EXPECTED_HOST_OS="Darwin"
|
||||||
|
EXPECTED_HOST_OS_VERSION="10.14"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "firefox-win32" ]]; then
|
||||||
|
BROWSER_NAME="firefox"
|
||||||
|
EXPECTED_HOST_OS="MINGW"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "firefox-win64" ]]; then
|
||||||
BROWSER_NAME="firefox"
|
BROWSER_NAME="firefox"
|
||||||
EXTRA_BUILD_ARGS="--win64"
|
EXTRA_BUILD_ARGS="--win64"
|
||||||
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") ]]; then
|
EXPECTED_HOST_OS="MINGW"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-gtk" ]]; then
|
||||||
BROWSER_NAME="webkit"
|
BROWSER_NAME="webkit"
|
||||||
|
EXPECTED_HOST_OS="Linux"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-wpe" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
EXTRA_BUILD_ARGS="--wpe"
|
||||||
|
EXTRA_ARCHIVE_ARGS="--wpe"
|
||||||
|
EXPECTED_HOST_OS="Linux"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-gtk-wpe" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
EXPECTED_HOST_OS="Linux"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-win64" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
EXPECTED_HOST_OS="MINGW"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.14" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
EXPECTED_HOST_OS="Darwin"
|
||||||
|
EXPECTED_HOST_OS_VERSION="10.14"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.15" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
EXPECTED_HOST_OS="Darwin"
|
||||||
|
EXPECTED_HOST_OS_VERSION="10.15"
|
||||||
else
|
else
|
||||||
echo ERROR: unknown browser - "$1"
|
echo ERROR: unknown build flavor - "$BUILD_FLAVOR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$CURRENT_HOST_OS" != $EXPECTED_HOST_OS* ]]; then
|
||||||
|
echo "ERROR: cannot build $BUILD_FLAVOR"
|
||||||
|
echo " -- expected OS: $EXPECTED_HOST_OS"
|
||||||
|
echo " -- current OS: $CURRENT_HOST_OS"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$CURRENT_HOST_OS_VERSION" != "$EXPECTED_HOST_OS_VERSION" ]]; then
|
||||||
|
echo "ERROR: cannot build $BUILD_FLAVOR"
|
||||||
|
echo " -- expected OS Version: $EXPECTED_HOST_OS_VERSION"
|
||||||
|
echo " -- current OS Version: $CURRENT_HOST_OS_VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -50,7 +103,7 @@ BUILD_NUMBER=$(cat ./$BROWSER_NAME/BUILD_NUMBER)
|
||||||
|
|
||||||
# pull from upstream and check if a new build has to be uploaded.
|
# pull from upstream and check if a new build has to be uploaded.
|
||||||
if ! [[ ($2 == '-f') || ($2 == '--force') ]]; then
|
if ! [[ ($2 == '-f') || ($2 == '--force') ]]; then
|
||||||
if ./upload.sh $1 --check; then
|
if ./upload.sh $BUILD_FLAVOR --check; then
|
||||||
echo "Build is already uploaded - no changes."
|
echo "Build is already uploaded - no changes."
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
|
|
@ -69,36 +122,46 @@ cd -
|
||||||
|
|
||||||
source ./buildbots/send_telegram_message.sh
|
source ./buildbots/send_telegram_message.sh
|
||||||
LAST_COMMIT_MESSAGE=$(git log --format=%s -n 1 HEAD -- ./$BROWSER_NAME/BUILD_NUMBER)
|
LAST_COMMIT_MESSAGE=$(git log --format=%s -n 1 HEAD -- ./$BROWSER_NAME/BUILD_NUMBER)
|
||||||
BUILD_ALIAS="<b>[[$(./upload.sh $1 --show-alias)]]</b> $LAST_COMMIT_MESSAGE"
|
BUILD_ALIAS="<b>[[$BUILD_FLAVOR r$BUILD_NUMBER]]</b> $LAST_COMMIT_MESSAGE"
|
||||||
|
|
||||||
send_telegram_message "$BUILD_ALIAS -- started ⏳"
|
send_telegram_message "$BUILD_ALIAS -- started ⏳"
|
||||||
|
|
||||||
echo "-- preparing checkout"
|
if [[ "$BUILD_FLAVOR" == "webkit-gtk-wpe" ]]; then
|
||||||
if ! ./prepare_checkout.sh $BROWSER_NAME; then
|
echo "-- combining binaries together"
|
||||||
|
if ! ./webkit/download_gtk_and_wpe_and_zip_together.sh $ZIP_PATH; then
|
||||||
|
send_telegram_message "$BUILD_ALIAS -- ./download_gtk_and_wpe_and_zip_together.sh failed! ❌"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "-- preparing checkout"
|
||||||
|
if ! ./prepare_checkout.sh $BROWSER_NAME; then
|
||||||
send_telegram_message "$BUILD_ALIAS -- ./prepare_checkout.sh failed! ❌"
|
send_telegram_message "$BUILD_ALIAS -- ./prepare_checkout.sh failed! ❌"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "-- cleaning"
|
echo "-- cleaning"
|
||||||
if ! ./$BROWSER_NAME/clean.sh; then
|
if ! ./$BROWSER_NAME/clean.sh; then
|
||||||
send_telegram_message "$BUILD_ALIAS -- ./clean.sh failed! ❌"
|
send_telegram_message "$BUILD_ALIAS -- ./clean.sh failed! ❌"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "-- building"
|
echo "-- building"
|
||||||
if ! ./$BROWSER_NAME/build.sh "$EXTRA_BUILD_ARGS"; then
|
if ! ./$BROWSER_NAME/build.sh "$EXTRA_BUILD_ARGS"; then
|
||||||
send_telegram_message "$BUILD_ALIAS -- ./build.sh failed! ❌"
|
send_telegram_message "$BUILD_ALIAS -- ./build.sh failed! ❌"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "-- archiving to $ZIP_PATH"
|
echo "-- archiving to $ZIP_PATH"
|
||||||
if ! ./$BROWSER_NAME/archive.sh $ZIP_PATH; then
|
if ! ./$BROWSER_NAME/archive.sh $ZIP_PATH "$EXTRA_ARCHIVE_ARGS"; then
|
||||||
send_telegram_message "$BUILD_ALIAS -- ./archive.sh failed! ❌"
|
send_telegram_message "$BUILD_ALIAS -- ./archive.sh failed! ❌"
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "-- uploading"
|
echo "-- uploading"
|
||||||
if ! ./upload.sh $1 $ZIP_PATH; then
|
if ! ./upload.sh $BUILD_FLAVOR $ZIP_PATH; then
|
||||||
send_telegram_message "$BUILD_ALIAS -- ./upload.sh failed! ❌"
|
send_telegram_message "$BUILD_ALIAS -- ./upload.sh failed! ❌"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
send_telegram_message "$BUILD_ALIAS -- uploaded ✅"
|
UPLOAD_SIZE=$(du -h "$ZIP_PATH" | awk '{print $1}')
|
||||||
|
send_telegram_message "$BUILD_ALIAS -- $UPLOAD_SIZE uploaded ✅"
|
||||||
|
|
|
||||||
70
browser_patches/download.sh
Executable file
70
browser_patches/download.sh
Executable file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set +x
|
||||||
|
|
||||||
|
trap "cd $(pwd -P)" EXIT
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
||||||
|
echo "usage: $(basename $0) [webkit-gtk|webkit-wpe] [zip-path]"
|
||||||
|
echo
|
||||||
|
echo "Download .zip of a browser build."
|
||||||
|
echo
|
||||||
|
echo "NOTE: \$AZ_ACCOUNT_KEY (azure account name) and \$AZ_ACCOUNT_NAME (azure account name)"
|
||||||
|
echo "env variables are required to download builds from CDN."
|
||||||
|
exit 0
|
||||||
|
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 download builds from Azure CDN."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# < 1 ]]; then
|
||||||
|
echo "missing build flavor"
|
||||||
|
echo "try '$(basename $0) --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BUILD_FLAVOR="$1"
|
||||||
|
BROWSER_NAME=""
|
||||||
|
BLOB_NAME=""
|
||||||
|
if [[ "$BUILD_FLAVOR" == "webkit-gtk" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
BLOB_NAME="minibrowser-gtk.zip"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-wpe" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
BLOB_NAME="minibrowser-wpe.zip"
|
||||||
|
else
|
||||||
|
echo ERROR: unsupported build flavor - "$BUILD_FLAVOR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BUILD_NUMBER=$(cat ./$BROWSER_NAME/BUILD_NUMBER)
|
||||||
|
BLOB_PATH="$BROWSER_NAME/$BUILD_NUMBER/$BLOB_NAME"
|
||||||
|
|
||||||
|
if [[ $# < 2 ]]; then
|
||||||
|
echo "missing path to zip archive to download to"
|
||||||
|
echo "try '$(basename $0) --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ZIP_PATH="$2"
|
||||||
|
|
||||||
|
if [[ -f $ZIP_PATH ]]; then
|
||||||
|
echo "ERROR: $ZIP_PATH exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! [[ $ZIP_PATH == *.zip ]]; then
|
||||||
|
echo "ERROR: $ZIP_PATH is not a zip archive (must have a .zip extension)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
az storage blob download -c builds --account-key $AZ_ACCOUNT_KEY --account-name $AZ_ACCOUNT_NAME -f $ZIP_PATH -n "$BLOB_PATH"
|
||||||
|
|
||||||
|
echo "DOWNLOAD SUCCESSFUL!"
|
||||||
|
echo "-- SRC: $ZIP_PATH"
|
||||||
|
echo "-- SIZE: $(du -h "$ZIP_PATH" | awk '{print $1}')"
|
||||||
|
echo "-- DST: $BLOB_PATH"
|
||||||
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1014
|
1016
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,6 @@ if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $# != 1 ]]; then
|
|
||||||
echo "error: missing zip output path"
|
|
||||||
echo "try '$(basename $0) --help' for details"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ZIP_PATH=$1
|
ZIP_PATH=$1
|
||||||
if [[ $ZIP_PATH != /* ]]; then
|
if [[ $ZIP_PATH != /* ]]; then
|
||||||
echo "ERROR: path $ZIP_PATH is not absolute"
|
echo "ERROR: path $ZIP_PATH is not absolute"
|
||||||
|
|
|
||||||
|
|
@ -1824,10 +1824,10 @@ index 0000000000000000000000000000000000000000..2508cce41565023b7fee9c7b85afe8ec
|
||||||
+
|
+
|
||||||
diff --git a/testing/juggler/content/PageAgent.js b/testing/juggler/content/PageAgent.js
|
diff --git a/testing/juggler/content/PageAgent.js b/testing/juggler/content/PageAgent.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a76984ed4860
|
index 0000000000000000000000000000000000000000..37ab5f56739cfd16200a4ada9f4cf83436688eba
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/content/PageAgent.js
|
+++ b/testing/juggler/content/PageAgent.js
|
||||||
@@ -0,0 +1,721 @@
|
@@ -0,0 +1,843 @@
|
||||||
+"use strict";
|
+"use strict";
|
||||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
+const Ci = Components.interfaces;
|
+const Ci = Components.interfaces;
|
||||||
|
|
@ -1839,11 +1839,28 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+
|
+
|
||||||
+const helper = new Helper();
|
+const helper = new Helper();
|
||||||
+
|
+
|
||||||
|
+const registeredWorkerListeners = new Map();
|
||||||
|
+const workerListener = {
|
||||||
|
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIWorkerDebuggerListener]),
|
||||||
|
+ onMessage: (wrapped) => {
|
||||||
|
+ const message = JSON.parse(wrapped);
|
||||||
|
+ const listener = registeredWorkerListeners.get(message.workerId);
|
||||||
|
+ if (listener)
|
||||||
|
+ listener(message);
|
||||||
|
+ },
|
||||||
|
+ onClose: () => {
|
||||||
|
+ },
|
||||||
|
+ onError: (filename, lineno, message) => {
|
||||||
|
+ dump(`Error in worker: ${message} @${filename}:${lineno}\n`);
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
+class FrameData {
|
+class FrameData {
|
||||||
+ constructor(agent, frame) {
|
+ constructor(agent, frame) {
|
||||||
+ this._agent = agent;
|
+ this._agent = agent;
|
||||||
+ this._frame = frame;
|
+ this._frame = frame;
|
||||||
+ this._isolatedWorlds = new Map();
|
+ this._isolatedWorlds = new Map();
|
||||||
|
+ this._workers = new Map();
|
||||||
+ this.reset();
|
+ this.reset();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|
@ -1913,6 +1930,59 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+ }
|
+ }
|
||||||
+ throw new Error('Cannot find object with id = ' + objectId);
|
+ throw new Error('Cannot find object with id = ' + objectId);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ workerCreated(workerDebugger) {
|
||||||
|
+ const workerId = helper.generateId();
|
||||||
|
+ this._workers.set(workerId, workerDebugger);
|
||||||
|
+ this._agent._session.emitEvent('Page.workerCreated', {
|
||||||
|
+ workerId,
|
||||||
|
+ frameId: this._frame.id(),
|
||||||
|
+ url: workerDebugger.url,
|
||||||
|
+ });
|
||||||
|
+ // Note: this does not interoperate with firefox devtools.
|
||||||
|
+ if (!workerDebugger.isInitialized) {
|
||||||
|
+ workerDebugger.initialize('chrome://juggler/content/content/WorkerMain.js');
|
||||||
|
+ workerDebugger.addListener(workerListener);
|
||||||
|
+ }
|
||||||
|
+ registeredWorkerListeners.set(workerId, message => {
|
||||||
|
+ if (message.command === 'dispatch') {
|
||||||
|
+ this._agent._session.emitEvent('Page.dispatchMessageFromWorker', {
|
||||||
|
+ workerId,
|
||||||
|
+ message: message.message,
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+ if (message.command === 'console')
|
||||||
|
+ this._agent._runtime.filterConsoleMessage(message.hash);
|
||||||
|
+ });
|
||||||
|
+ workerDebugger.postMessage(JSON.stringify({command: 'connect', workerId}));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ workerDestroyed(wd) {
|
||||||
|
+ for (const [workerId, workerDebugger] of this._workers) {
|
||||||
|
+ if (workerDebugger === wd) {
|
||||||
|
+ this._agent._session.emitEvent('Page.workerDestroyed', {
|
||||||
|
+ workerId,
|
||||||
|
+ });
|
||||||
|
+ this._workers.delete(workerId);
|
||||||
|
+ registeredWorkerListeners.delete(workerId);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sendMessageToWorker(workerId, message) {
|
||||||
|
+ const workerDebugger = this._workers.get(workerId);
|
||||||
|
+ if (!workerDebugger)
|
||||||
|
+ throw new Error('Cannot find worker with id "' + workerId + '"');
|
||||||
|
+ workerDebugger.postMessage(JSON.stringify({command: 'dispatch', workerId, message}));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dispose() {
|
||||||
|
+ for (const [workerId, workerDebugger] of this._workers) {
|
||||||
|
+ workerDebugger.postMessage(JSON.stringify({command: 'disconnect', workerId}));
|
||||||
|
+ registeredWorkerListeners.delete(workerId);
|
||||||
|
+ }
|
||||||
|
+ this._workers.clear();
|
||||||
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+class PageAgent {
|
+class PageAgent {
|
||||||
|
|
@ -1934,6 +2004,24 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+ this._docShell = docShell;
|
+ this._docShell = docShell;
|
||||||
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
||||||
+ this._customScrollbars = null;
|
+ this._customScrollbars = null;
|
||||||
|
+
|
||||||
|
+ this._wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].createInstance(Ci.nsIWorkerDebuggerManager);
|
||||||
|
+ this._wdmListener = {
|
||||||
|
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIWorkerDebuggerManagerListener]),
|
||||||
|
+ onRegister: this._onWorkerCreated.bind(this),
|
||||||
|
+ onUnregister: this._onWorkerDestroyed.bind(this),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ this._runtime.setOnErrorFromWorker((domWindow, message, stack) => {
|
||||||
|
+ const frame = this._frameTree.frameForDocShell(domWindow.docShell);
|
||||||
|
+ if (!frame)
|
||||||
|
+ return;
|
||||||
|
+ this._session.emitEvent('Page.uncaughtError', {
|
||||||
|
+ frameId: frame.id(),
|
||||||
|
+ message,
|
||||||
|
+ stack,
|
||||||
|
+ });
|
||||||
|
+ });
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async awaitViewportDimensions({width, height}) {
|
+ async awaitViewportDimensions({width, height}) {
|
||||||
|
|
@ -2042,12 +2130,43 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+ helper.on(this._frameTree, 'navigationaborted', this._onNavigationAborted.bind(this)),
|
+ helper.on(this._frameTree, 'navigationaborted', this._onNavigationAborted.bind(this)),
|
||||||
+ helper.on(this._frameTree, 'samedocumentnavigation', this._onSameDocumentNavigation.bind(this)),
|
+ helper.on(this._frameTree, 'samedocumentnavigation', this._onSameDocumentNavigation.bind(this)),
|
||||||
+ ];
|
+ ];
|
||||||
|
+
|
||||||
|
+ this._wdm.addListener(this._wdmListener);
|
||||||
|
+ for (const workerDebugger of this._wdm.getWorkerDebuggerEnumerator())
|
||||||
|
+ this._onWorkerCreated(workerDebugger);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ setInterceptFileChooserDialog({enabled}) {
|
+ setInterceptFileChooserDialog({enabled}) {
|
||||||
+ this._docShell.fileInputInterceptionEnabled = !!enabled;
|
+ this._docShell.fileInputInterceptionEnabled = !!enabled;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ _frameForWorker(workerDebugger) {
|
||||||
|
+ if (workerDebugger.type !== Ci.nsIWorkerDebugger.TYPE_DEDICATED)
|
||||||
|
+ return null;
|
||||||
|
+ const docShell = workerDebugger.window.docShell;
|
||||||
|
+ const frame = this._frameTree.frameForDocShell(docShell);
|
||||||
|
+ return frame ? this._frameData.get(frame) : null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _onWorkerCreated(workerDebugger) {
|
||||||
|
+ const frameData = this._frameForWorker(workerDebugger);
|
||||||
|
+ if (frameData)
|
||||||
|
+ frameData.workerCreated(workerDebugger);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _onWorkerDestroyed(workerDebugger) {
|
||||||
|
+ const frameData = this._frameForWorker(workerDebugger);
|
||||||
|
+ if (frameData)
|
||||||
|
+ frameData.workerDestroyed(workerDebugger);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sendMessageToWorker({frameId, workerId, message}) {
|
||||||
|
+ const frame = this._frameTree.frame(frameId);
|
||||||
|
+ if (!frame)
|
||||||
|
+ throw new Error('Failed to find frame with id = ' + frameId);
|
||||||
|
+ this._frameData.get(frame).sendMessageToWorker(workerId, message);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ _filePickerShown(inputElement) {
|
+ _filePickerShown(inputElement) {
|
||||||
+ if (inputElement.ownerGlobal.docShell !== this._docShell)
|
+ if (inputElement.ownerGlobal.docShell !== this._docShell)
|
||||||
+ return;
|
+ return;
|
||||||
|
|
@ -2166,7 +2285,10 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ dispose() {
|
+ dispose() {
|
||||||
|
+ for (const frameData of this._frameData.values())
|
||||||
|
+ frameData.dispose();
|
||||||
+ helper.removeListeners(this._eventListeners);
|
+ helper.removeListeners(this._eventListeners);
|
||||||
|
+ this._wdm.removeListener(this._wdmListener);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async navigate({frameId, url, referer}) {
|
+ async navigate({frameId, url, referer}) {
|
||||||
|
|
@ -2551,20 +2673,24 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
||||||
+
|
+
|
||||||
diff --git a/testing/juggler/content/RuntimeAgent.js b/testing/juggler/content/RuntimeAgent.js
|
diff --git a/testing/juggler/content/RuntimeAgent.js b/testing/juggler/content/RuntimeAgent.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac357fb9b60
|
index 0000000000000000000000000000000000000000..5765d5c3b1de7b9383a80435b37b034d6951d981
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/content/RuntimeAgent.js
|
+++ b/testing/juggler/content/RuntimeAgent.js
|
||||||
@@ -0,0 +1,478 @@
|
@@ -0,0 +1,545 @@
|
||||||
+"use strict";
|
+"use strict";
|
||||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
+// Note: this file should be loadabale with eval() into worker environment.
|
||||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
+// Avoid Components.*, ChromeUtils and global const variables.
|
||||||
+const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm", {});
|
|
||||||
+
|
+
|
||||||
+const Ci = Components.interfaces;
|
+if (!this.Debugger) {
|
||||||
+const Cr = Components.results;
|
+ // Worker has a Debugger defined already.
|
||||||
+const Cu = Components.utils;
|
+ const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm", {});
|
||||||
+addDebuggerToGlobal(Cu.getGlobalForObject(this));
|
+ addDebuggerToGlobal(Components.utils.getGlobalForObject(this));
|
||||||
+const helper = new Helper();
|
+}
|
||||||
|
+
|
||||||
|
+let lastId = 0;
|
||||||
|
+function generateId() {
|
||||||
|
+ return 'id-' + (++lastId);
|
||||||
|
+}
|
||||||
+
|
+
|
||||||
+const consoleLevelToProtocolType = {
|
+const consoleLevelToProtocolType = {
|
||||||
+ 'dir': 'dir',
|
+ 'dir': 'dir',
|
||||||
|
|
@ -2603,13 +2729,39 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+]);
|
+]);
|
||||||
+
|
+
|
||||||
+class RuntimeAgent {
|
+class RuntimeAgent {
|
||||||
+ constructor(session) {
|
+ constructor(session, onWorkerConsoleMessage) {
|
||||||
+ this._debugger = new Debugger();
|
+ this._debugger = new Debugger();
|
||||||
+ this._pendingPromises = new Map();
|
+ this._pendingPromises = new Map();
|
||||||
+ this._session = session;
|
+ this._session = session;
|
||||||
+ this._executionContexts = new Map();
|
+ this._executionContexts = new Map();
|
||||||
+ this._windowToExecutionContext = new Map();
|
+ this._windowToExecutionContext = new Map();
|
||||||
+ this._consoleServiceListener = {
|
+ this._eventListeners = [];
|
||||||
|
+ this._enabled = false;
|
||||||
|
+ this._filteredConsoleMessageHashes = new Set();
|
||||||
|
+ this._onErrorFromWorker = null;
|
||||||
|
+ this._onWorkerConsoleMessage = onWorkerConsoleMessage;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ enable() {
|
||||||
|
+ if (this._enabled)
|
||||||
|
+ return;
|
||||||
|
+ this._enabled = true;
|
||||||
|
+ for (const executionContext of this._executionContexts.values())
|
||||||
|
+ this._notifyExecutionContextCreated(executionContext);
|
||||||
|
+
|
||||||
|
+ const isWorker = !!this._onWorkerConsoleMessage;
|
||||||
|
+ if (isWorker) {
|
||||||
|
+ this._registerConsoleEventHandler();
|
||||||
|
+ } else {
|
||||||
|
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
+ this._registerConsoleServiceListener(Services);
|
||||||
|
+ this._registerConsoleObserver(Services);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _registerConsoleServiceListener(Services) {
|
||||||
|
+ const Ci = Components.interfaces;
|
||||||
|
+ const consoleServiceListener = {
|
||||||
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleListener]),
|
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleListener]),
|
||||||
+
|
+
|
||||||
+ observe: message => {
|
+ observe: message => {
|
||||||
|
|
@ -2618,6 +2770,11 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ const errorWindow = Services.wm.getOuterWindowWithId(message.outerWindowID);
|
+ const errorWindow = Services.wm.getOuterWindowWithId(message.outerWindowID);
|
||||||
|
+ if (message.category === 'Web Worker' && (message.flags & Ci.nsIScriptError.exceptionFlag)) {
|
||||||
|
+ if (this._onErrorFromWorker)
|
||||||
|
+ this._onErrorFromWorker(errorWindow, message.message, '' + message.stack);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
+ const executionContext = this._windowToExecutionContext.get(errorWindow);
|
+ const executionContext = this._windowToExecutionContext.get(errorWindow);
|
||||||
+ if (!executionContext)
|
+ if (!executionContext)
|
||||||
+ return;
|
+ return;
|
||||||
|
|
@ -2641,47 +2798,67 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ });
|
+ });
|
||||||
+ },
|
+ },
|
||||||
+ };
|
+ };
|
||||||
+
|
+ Services.console.registerListener(consoleServiceListener);
|
||||||
+ this._eventListeners = [];
|
+ this._eventListeners.push(() => Services.console.unregisterListener(consoleServiceListener));
|
||||||
+ this._enabled = false;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ _consoleAPICalled({wrappedJSObject}, topic, data) {
|
+ _registerConsoleObserver(Services) {
|
||||||
+ const type = consoleLevelToProtocolType[wrappedJSObject.level];
|
+ const consoleObserver = ({wrappedJSObject}, topic, data) => {
|
||||||
+ if (!type)
|
+ const hash = this._consoleMessageHash(wrappedJSObject);
|
||||||
|
+ if (this._filteredConsoleMessageHashes.has(hash)) {
|
||||||
|
+ this._filteredConsoleMessageHashes.delete(hash);
|
||||||
+ return;
|
+ return;
|
||||||
|
+ }
|
||||||
+ const executionContext = Array.from(this._executionContexts.values()).find(context => {
|
+ const executionContext = Array.from(this._executionContexts.values()).find(context => {
|
||||||
+ const domWindow = context._domWindow;
|
+ const domWindow = context._domWindow;
|
||||||
+ return domWindow && domWindow.windowUtils.currentInnerWindowID === wrappedJSObject.innerID;
|
+ return domWindow && domWindow.windowUtils.currentInnerWindowID === wrappedJSObject.innerID;
|
||||||
+ });
|
+ });
|
||||||
+ if (!executionContext)
|
+ if (!executionContext)
|
||||||
+ return;
|
+ return;
|
||||||
+ const args = wrappedJSObject.arguments.map(arg => executionContext.rawValueToRemoteObject(arg));
|
+ this._onConsoleMessage(executionContext, wrappedJSObject);
|
||||||
|
+ };
|
||||||
|
+ Services.obs.addObserver(consoleObserver, "console-api-log-event");
|
||||||
|
+ this._eventListeners.push(() => Services.obs.removeObserver(consoleObserver, "console-api-log-event"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _registerConsoleEventHandler() {
|
||||||
|
+ setConsoleEventHandler(message => {
|
||||||
|
+ this._onWorkerConsoleMessage(this._consoleMessageHash(message));
|
||||||
|
+ const executionContext = Array.from(this._executionContexts.values())[0];
|
||||||
|
+ this._onConsoleMessage(executionContext, message);
|
||||||
|
+ });
|
||||||
|
+ this._eventListeners.push(() => setConsoleEventHandler(null));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ filterConsoleMessage(messageHash) {
|
||||||
|
+ this._filteredConsoleMessageHashes.add(messageHash);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ setOnErrorFromWorker(onErrorFromWorker) {
|
||||||
|
+ this._onErrorFromWorker = onErrorFromWorker;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _consoleMessageHash(message) {
|
||||||
|
+ return `${message.timeStamp}/${message.filename}/${message.lineNumber}/${message.columnNumber}/${message.sourceId}/${message.level}`;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _onConsoleMessage(executionContext, message) {
|
||||||
|
+ const type = consoleLevelToProtocolType[message.level];
|
||||||
|
+ if (!type)
|
||||||
|
+ return;
|
||||||
|
+ const args = message.arguments.map(arg => executionContext.rawValueToRemoteObject(arg));
|
||||||
+ this._session.emitEvent('Runtime.console', {
|
+ this._session.emitEvent('Runtime.console', {
|
||||||
+ args,
|
+ args,
|
||||||
+ type,
|
+ type,
|
||||||
+ executionContextId: executionContext.id(),
|
+ executionContextId: executionContext.id(),
|
||||||
+ location: {
|
+ location: {
|
||||||
+ lineNumber: wrappedJSObject.lineNumber - 1,
|
+ lineNumber: message.lineNumber - 1,
|
||||||
+ columnNumber: wrappedJSObject.columnNumber - 1,
|
+ columnNumber: message.columnNumber - 1,
|
||||||
+ url: wrappedJSObject.filename,
|
+ url: message.filename,
|
||||||
+ },
|
+ },
|
||||||
+ });
|
+ });
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ enable() {
|
|
||||||
+ if (this._enabled)
|
|
||||||
+ return;
|
|
||||||
+ this._enabled = true;
|
|
||||||
+ for (const executionContext of this._executionContexts.values())
|
|
||||||
+ this._notifyExecutionContextCreated(executionContext);
|
|
||||||
+ Services.console.registerListener(this._consoleServiceListener);
|
|
||||||
+ this._eventListeners = [
|
|
||||||
+ () => Services.console.unregisterListener(this._consoleServiceListener),
|
|
||||||
+ helper.addObserver(this._consoleAPICalled.bind(this), "console-api-log-event"),
|
|
||||||
+ ];
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ _notifyExecutionContextCreated(executionContext) {
|
+ _notifyExecutionContextCreated(executionContext) {
|
||||||
+ if (!this._enabled)
|
+ if (!this._enabled)
|
||||||
+ return;
|
+ return;
|
||||||
|
|
@ -2700,7 +2877,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ dispose() {
|
+ dispose() {
|
||||||
+ helper.removeListeners(this._eventListeners);
|
+ for (const tearDown of this._eventListeners)
|
||||||
|
+ tearDown.call(null);
|
||||||
|
+ this._eventListeners = [];
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async _awaitPromise(executionContext, obj, exceptionDetails = {}) {
|
+ async _awaitPromise(executionContext, obj, exceptionDetails = {}) {
|
||||||
|
|
@ -2742,8 +2921,10 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ createExecutionContext(domWindow, contextGlobal, auxData) {
|
+ createExecutionContext(domWindow, contextGlobal, auxData) {
|
||||||
+ const context = new ExecutionContext(this, domWindow, this._debugger.addDebuggee(contextGlobal), auxData);
|
+ // Note: domWindow is null for workers.
|
||||||
|
+ const context = new ExecutionContext(this, domWindow, contextGlobal, this._debugger.addDebuggee(contextGlobal), auxData);
|
||||||
+ this._executionContexts.set(context._id, context);
|
+ this._executionContexts.set(context._id, context);
|
||||||
|
+ if (domWindow)
|
||||||
+ this._windowToExecutionContext.set(domWindow, context);
|
+ this._windowToExecutionContext.set(domWindow, context);
|
||||||
+ this._notifyExecutionContextCreated(context);
|
+ this._notifyExecutionContextCreated(context);
|
||||||
+ return context;
|
+ return context;
|
||||||
|
|
@ -2765,8 +2946,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ }
|
+ }
|
||||||
+ if (!this._pendingPromises.size)
|
+ if (!this._pendingPromises.size)
|
||||||
+ this._debugger.onPromiseSettled = undefined;
|
+ this._debugger.onPromiseSettled = undefined;
|
||||||
+ this._debugger.removeDebuggee(destroyedContext._domWindow);
|
+ this._debugger.removeDebuggee(destroyedContext._contextGlobal);
|
||||||
+ this._executionContexts.delete(destroyedContext._id);
|
+ this._executionContexts.delete(destroyedContext._id);
|
||||||
|
+ if (destroyedContext._domWindow)
|
||||||
+ this._windowToExecutionContext.delete(destroyedContext._domWindow);
|
+ this._windowToExecutionContext.delete(destroyedContext._domWindow);
|
||||||
+ this._notifyExecutionContextDestroyed(destroyedContext);
|
+ this._notifyExecutionContextDestroyed(destroyedContext);
|
||||||
+ }
|
+ }
|
||||||
|
|
@ -2813,12 +2995,13 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+class ExecutionContext {
|
+class ExecutionContext {
|
||||||
+ constructor(runtime, domWindow, global, auxData) {
|
+ constructor(runtime, domWindow, contextGlobal, global, auxData) {
|
||||||
+ this._runtime = runtime;
|
+ this._runtime = runtime;
|
||||||
+ this._domWindow = domWindow;
|
+ this._domWindow = domWindow;
|
||||||
|
+ this._contextGlobal = contextGlobal;
|
||||||
+ this._global = global;
|
+ this._global = global;
|
||||||
+ this._remoteObjects = new Map();
|
+ this._remoteObjects = new Map();
|
||||||
+ this._id = helper.generateId();
|
+ this._id = generateId();
|
||||||
+ this._auxData = auxData;
|
+ this._auxData = auxData;
|
||||||
+ this._jsonStringifyObject = this._global.executeInGlobal(`((stringify, dateProto, object) => {
|
+ this._jsonStringifyObject = this._global.executeInGlobal(`((stringify, dateProto, object) => {
|
||||||
+ const oldToJson = dateProto.toJSON;
|
+ const oldToJson = dateProto.toJSON;
|
||||||
|
|
@ -2839,9 +3022,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async evaluateScript(script, exceptionDetails = {}) {
|
+ async evaluateScript(script, exceptionDetails = {}) {
|
||||||
+ const userInputHelper = this._domWindow.windowUtils.setHandlingUserInput(true);
|
+ const userInputHelper = this._domWindow ? this._domWindow.windowUtils.setHandlingUserInput(true) : null;
|
||||||
+ let {success, obj} = this._getResult(this._global.executeInGlobal(script), exceptionDetails);
|
+ let {success, obj} = this._getResult(this._global.executeInGlobal(script), exceptionDetails);
|
||||||
+ userInputHelper.destruct();
|
+ userInputHelper && userInputHelper.destruct();
|
||||||
+ if (!success)
|
+ if (!success)
|
||||||
+ return null;
|
+ return null;
|
||||||
+ if (obj && obj.isPromise) {
|
+ if (obj && obj.isPromise) {
|
||||||
|
|
@ -2873,9 +3056,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ default: return this._toDebugger(arg.value);
|
+ default: return this._toDebugger(arg.value);
|
||||||
+ }
|
+ }
|
||||||
+ });
|
+ });
|
||||||
+ const userInputHelper = this._domWindow.windowUtils.setHandlingUserInput(true);
|
+ const userInputHelper = this._domWindow ? this._domWindow.windowUtils.setHandlingUserInput(true) : null;
|
||||||
+ let {success, obj} = this._getResult(funEvaluation.obj.apply(null, args), exceptionDetails);
|
+ let {success, obj} = this._getResult(funEvaluation.obj.apply(null, args), exceptionDetails);
|
||||||
+ userInputHelper.destruct();
|
+ userInputHelper && userInputHelper.destruct();
|
||||||
+ if (!success)
|
+ if (!success)
|
||||||
+ return null;
|
+ return null;
|
||||||
+ if (obj && obj.isPromise) {
|
+ if (obj && obj.isPromise) {
|
||||||
|
|
@ -2898,9 +3081,15 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ return this._createRemoteObject(debuggerObj);
|
+ return this._createRemoteObject(debuggerObj);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ _instanceOf(debuggerObj, rawObj, className) {
|
||||||
|
+ if (this._domWindow)
|
||||||
|
+ return rawObj instanceof this._domWindow[className];
|
||||||
|
+ return this._global.executeInGlobalWithBindings('o instanceof this[className]', {o: debuggerObj, className: this._global.makeDebuggeeValue(className)}).return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ _createRemoteObject(debuggerObj) {
|
+ _createRemoteObject(debuggerObj) {
|
||||||
+ if (debuggerObj instanceof Debugger.Object) {
|
+ if (debuggerObj instanceof Debugger.Object) {
|
||||||
+ const objectId = helper.generateId();
|
+ const objectId = generateId();
|
||||||
+ this._remoteObjects.set(objectId, debuggerObj);
|
+ this._remoteObjects.set(objectId, debuggerObj);
|
||||||
+ const rawObj = debuggerObj.unsafeDereference();
|
+ const rawObj = debuggerObj.unsafeDereference();
|
||||||
+ const type = typeof rawObj;
|
+ const type = typeof rawObj;
|
||||||
|
|
@ -2911,35 +3100,35 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
||||||
+ subtype = 'array';
|
+ subtype = 'array';
|
||||||
+ else if (Object.is(rawObj, null))
|
+ else if (Object.is(rawObj, null))
|
||||||
+ subtype = 'null';
|
+ subtype = 'null';
|
||||||
+ else if (rawObj instanceof this._domWindow.Node)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Node'))
|
||||||
+ subtype = 'node';
|
+ subtype = 'node';
|
||||||
+ else if (rawObj instanceof this._domWindow.RegExp)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'RegExp'))
|
||||||
+ subtype = 'regexp';
|
+ subtype = 'regexp';
|
||||||
+ else if (rawObj instanceof this._domWindow.Date)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Date'))
|
||||||
+ subtype = 'date';
|
+ subtype = 'date';
|
||||||
+ else if (rawObj instanceof this._domWindow.Map)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Map'))
|
||||||
+ subtype = 'map';
|
+ subtype = 'map';
|
||||||
+ else if (rawObj instanceof this._domWindow.Set)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Set'))
|
||||||
+ subtype = 'set';
|
+ subtype = 'set';
|
||||||
+ else if (rawObj instanceof this._domWindow.WeakMap)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'WeakMap'))
|
||||||
+ subtype = 'weakmap';
|
+ subtype = 'weakmap';
|
||||||
+ else if (rawObj instanceof this._domWindow.WeakSet)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'WeakSet'))
|
||||||
+ subtype = 'weakset';
|
+ subtype = 'weakset';
|
||||||
+ else if (rawObj instanceof this._domWindow.Error)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Error'))
|
||||||
+ subtype = 'error';
|
+ subtype = 'error';
|
||||||
+ else if (rawObj instanceof this._domWindow.Promise)
|
+ else if (this._instanceOf(debuggerObj, rawObj, 'Promise'))
|
||||||
+ subtype = 'promise';
|
+ subtype = 'promise';
|
||||||
+ else if ((rawObj instanceof this._domWindow.Int8Array) || (rawObj instanceof this._domWindow.Uint8Array) ||
|
+ else if ((this._instanceOf(debuggerObj, rawObj, 'Int8Array')) || (this._instanceOf(debuggerObj, rawObj, 'Uint8Array')) ||
|
||||||
+ (rawObj instanceof this._domWindow.Uint8ClampedArray) || (rawObj instanceof this._domWindow.Int16Array) ||
|
+ (this._instanceOf(debuggerObj, rawObj, 'Uint8ClampedArray')) || (this._instanceOf(debuggerObj, rawObj, 'Int16Array')) ||
|
||||||
+ (rawObj instanceof this._domWindow.Uint16Array) || (rawObj instanceof this._domWindow.Int32Array) ||
|
+ (this._instanceOf(debuggerObj, rawObj, 'Uint16Array')) || (this._instanceOf(debuggerObj, rawObj, 'Int32Array')) ||
|
||||||
+ (rawObj instanceof this._domWindow.Uint32Array) || (rawObj instanceof this._domWindow.Float32Array) ||
|
+ (this._instanceOf(debuggerObj, rawObj, 'Uint32Array')) || (this._instanceOf(debuggerObj, rawObj, 'Float32Array')) ||
|
||||||
+ (rawObj instanceof this._domWindow.Float64Array)) {
|
+ (this._instanceOf(debuggerObj, rawObj, 'Float64Array'))) {
|
||||||
+ subtype = 'typedarray';
|
+ subtype = 'typedarray';
|
||||||
+ }
|
+ }
|
||||||
+ return {objectId, type, subtype};
|
+ return {objectId, type, subtype};
|
||||||
+ }
|
+ }
|
||||||
+ if (typeof debuggerObj === 'symbol') {
|
+ if (typeof debuggerObj === 'symbol') {
|
||||||
+ const objectId = helper.generateId();
|
+ const objectId = generateId();
|
||||||
+ this._remoteObjects.set(objectId, debuggerObj);
|
+ this._remoteObjects.set(objectId, debuggerObj);
|
||||||
+ return {objectId, type: 'symbol'};
|
+ return {objectId, type: 'symbol'};
|
||||||
+ }
|
+ }
|
||||||
|
|
@ -3124,6 +3313,79 @@ index 0000000000000000000000000000000000000000..caee4df323d0a526ed7e38947c41c643
|
||||||
+var EXPORTED_SYMBOLS = ['ScrollbarManager'];
|
+var EXPORTED_SYMBOLS = ['ScrollbarManager'];
|
||||||
+this.ScrollbarManager = ScrollbarManager;
|
+this.ScrollbarManager = ScrollbarManager;
|
||||||
+
|
+
|
||||||
|
diff --git a/testing/juggler/content/WorkerMain.js b/testing/juggler/content/WorkerMain.js
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..73cdce649608f068e59e1ff7808883c4482bff7e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/testing/juggler/content/WorkerMain.js
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+"use strict";
|
||||||
|
+loadSubScript('chrome://juggler/content/content/RuntimeAgent.js');
|
||||||
|
+
|
||||||
|
+class WorkerSession {
|
||||||
|
+ constructor(workerId) {
|
||||||
|
+ this._workerId = workerId;
|
||||||
|
+ this._agents = {
|
||||||
|
+ Runtime: new RuntimeAgent(this, hash => this._send({command: 'console', hash})),
|
||||||
|
+ };
|
||||||
|
+ this._agents.Runtime.enable();
|
||||||
|
+ this._agents.Runtime.createExecutionContext(null /* domWindow */, global, {});
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _send(command) {
|
||||||
|
+ postMessage(JSON.stringify({...command, workerId: this._workerId}));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _dispatchProtocolMessage(protocolMessage) {
|
||||||
|
+ this._send({command: 'dispatch', message: JSON.stringify(protocolMessage)});
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ emitEvent(eventName, params) {
|
||||||
|
+ this._dispatchProtocolMessage({method: eventName, params});
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ async _onMessage(message) {
|
||||||
|
+ const object = JSON.parse(message);
|
||||||
|
+ const id = object.id;
|
||||||
|
+ try {
|
||||||
|
+ const [domainName, methodName] = object.method.split('.');
|
||||||
|
+ const agent = this._agents[domainName];
|
||||||
|
+ if (!agent)
|
||||||
|
+ throw new Error(`unknown domain: ${domainName}`);
|
||||||
|
+ const handler = agent[methodName];
|
||||||
|
+ if (!handler)
|
||||||
|
+ throw new Error(`unknown method: ${domainName}.${methodName}`);
|
||||||
|
+ const result = await handler.call(agent, object.params);
|
||||||
|
+ this._dispatchProtocolMessage({id, result});
|
||||||
|
+ } catch (e) {
|
||||||
|
+ this._dispatchProtocolMessage({id, error: e.message + '\n' + e.stack});
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dispose() {
|
||||||
|
+ for (const agent of Object.values(this._agents))
|
||||||
|
+ agent.dispose();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const workerSessions = new Map();
|
||||||
|
+
|
||||||
|
+this.addEventListener('message', event => {
|
||||||
|
+ const data = JSON.parse(event.data);
|
||||||
|
+ if (data.command === 'connect') {
|
||||||
|
+ const session = new WorkerSession(data.workerId);
|
||||||
|
+ workerSessions.set(data.workerId, session);
|
||||||
|
+ }
|
||||||
|
+ if (data.command === 'disconnect') {
|
||||||
|
+ const session = workerSessions.get(data.workerId);
|
||||||
|
+ session.dispose();
|
||||||
|
+ workerSessions.delete(data.workerId);
|
||||||
|
+ }
|
||||||
|
+ if (data.command === 'dispatch') {
|
||||||
|
+ const session = workerSessions.get(data.workerId);
|
||||||
|
+ session._onMessage(data.message);
|
||||||
|
+ }
|
||||||
|
+});
|
||||||
diff --git a/testing/juggler/content/floating-scrollbars.css b/testing/juggler/content/floating-scrollbars.css
|
diff --git a/testing/juggler/content/floating-scrollbars.css b/testing/juggler/content/floating-scrollbars.css
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..7709bdd34c65062fc63684ef17fc792d3991d965
|
index 0000000000000000000000000000000000000000..7709bdd34c65062fc63684ef17fc792d3991d965
|
||||||
|
|
@ -3243,10 +3505,10 @@ index 0000000000000000000000000000000000000000..8585092e04e7e763a0c115c28363e505
|
||||||
+
|
+
|
||||||
diff --git a/testing/juggler/jar.mn b/testing/juggler/jar.mn
|
diff --git a/testing/juggler/jar.mn b/testing/juggler/jar.mn
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..27f5a15fd7f14385bb1f080d5965d90e60423d1a
|
index 0000000000000000000000000000000000000000..76377927a8c9af3cac3b028ff754491966d03ba3
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/jar.mn
|
+++ b/testing/juggler/jar.mn
|
||||||
@@ -0,0 +1,29 @@
|
@@ -0,0 +1,30 @@
|
||||||
+# This Source Code Form is subject to the terms of the Mozilla Public
|
+# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
+# License, v. 2.0. If a copy of the MPL was not distributed with this
|
+# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
@ -3272,6 +3534,7 @@ index 0000000000000000000000000000000000000000..27f5a15fd7f14385bb1f080d5965d90e
|
||||||
+ content/content/NetworkMonitor.js (content/NetworkMonitor.js)
|
+ content/content/NetworkMonitor.js (content/NetworkMonitor.js)
|
||||||
+ content/content/PageAgent.js (content/PageAgent.js)
|
+ content/content/PageAgent.js (content/PageAgent.js)
|
||||||
+ content/content/RuntimeAgent.js (content/RuntimeAgent.js)
|
+ content/content/RuntimeAgent.js (content/RuntimeAgent.js)
|
||||||
|
+ content/content/WorkerMain.js (content/WorkerMain.js)
|
||||||
+ content/content/ScrollbarManager.js (content/ScrollbarManager.js)
|
+ content/content/ScrollbarManager.js (content/ScrollbarManager.js)
|
||||||
+ content/content/floating-scrollbars.css (content/floating-scrollbars.css)
|
+ content/content/floating-scrollbars.css (content/floating-scrollbars.css)
|
||||||
+ content/content/hidden-scrollbars.css (content/hidden-scrollbars.css)
|
+ content/content/hidden-scrollbars.css (content/hidden-scrollbars.css)
|
||||||
|
|
@ -3392,10 +3655,10 @@ index 0000000000000000000000000000000000000000..708059a95b3a01f3d9c7b7ef4714ee6f
|
||||||
+this.BrowserHandler = BrowserHandler;
|
+this.BrowserHandler = BrowserHandler;
|
||||||
diff --git a/testing/juggler/protocol/Dispatcher.js b/testing/juggler/protocol/Dispatcher.js
|
diff --git a/testing/juggler/protocol/Dispatcher.js b/testing/juggler/protocol/Dispatcher.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..7b3a6fa4fe7a2b50a78ed446fbf5537504994798
|
index 0000000000000000000000000000000000000000..956988738079272be8d3998dcbbaa91abc415fcc
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/protocol/Dispatcher.js
|
+++ b/testing/juggler/protocol/Dispatcher.js
|
||||||
@@ -0,0 +1,255 @@
|
@@ -0,0 +1,254 @@
|
||||||
+const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
|
+const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
|
||||||
+const {protocol, checkScheme} = ChromeUtils.import("chrome://juggler/content/protocol/Protocol.js");
|
+const {protocol, checkScheme} = ChromeUtils.import("chrome://juggler/content/protocol/Protocol.js");
|
||||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||||
|
|
@ -3630,7 +3893,6 @@ index 0000000000000000000000000000000000000000..7b3a6fa4fe7a2b50a78ed446fbf55375
|
||||||
+
|
+
|
||||||
+ _onMessage({data}) {
|
+ _onMessage({data}) {
|
||||||
+ if (data.id) {
|
+ if (data.id) {
|
||||||
+ let id = data.id;
|
|
||||||
+ const {resolve, reject} = this._pendingMessages.get(data.id);
|
+ const {resolve, reject} = this._pendingMessages.get(data.id);
|
||||||
+ this._pendingMessages.delete(data.id);
|
+ this._pendingMessages.delete(data.id);
|
||||||
+ if (data.error)
|
+ if (data.error)
|
||||||
|
|
@ -3813,10 +4075,10 @@ index 0000000000000000000000000000000000000000..f5e7e919594b3778fd3046bf69d34878
|
||||||
+this.NetworkHandler = NetworkHandler;
|
+this.NetworkHandler = NetworkHandler;
|
||||||
diff --git a/testing/juggler/protocol/PageHandler.js b/testing/juggler/protocol/PageHandler.js
|
diff --git a/testing/juggler/protocol/PageHandler.js b/testing/juggler/protocol/PageHandler.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..bf59b2afa8692d02fd0ce664eec2e9827a8209d2
|
index 0000000000000000000000000000000000000000..23a32be2200e90e2e05d31aec85874a829cb1bbe
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/protocol/PageHandler.js
|
+++ b/testing/juggler/protocol/PageHandler.js
|
||||||
@@ -0,0 +1,281 @@
|
@@ -0,0 +1,285 @@
|
||||||
+"use strict";
|
+"use strict";
|
||||||
+
|
+
|
||||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||||
|
|
@ -4039,6 +4301,10 @@ index 0000000000000000000000000000000000000000..bf59b2afa8692d02fd0ce664eec2e982
|
||||||
+ async handleFileChooser(options) {
|
+ async handleFileChooser(options) {
|
||||||
+ return await this._contentSession.send('Page.handleFileChooser', options);
|
+ return await this._contentSession.send('Page.handleFileChooser', options);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ async sendMessageToWorker(options) {
|
||||||
|
+ return await this._contentSession.send('Page.sendMessageToWorker', options);
|
||||||
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+class Dialog {
|
+class Dialog {
|
||||||
|
|
@ -4249,10 +4515,10 @@ index 0000000000000000000000000000000000000000..78b6601b91d0b7fcda61114e6846aa07
|
||||||
+this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
|
+this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
|
||||||
diff --git a/testing/juggler/protocol/Protocol.js b/testing/juggler/protocol/Protocol.js
|
diff --git a/testing/juggler/protocol/Protocol.js b/testing/juggler/protocol/Protocol.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895ebec2438b6
|
index 0000000000000000000000000000000000000000..1eecb6120f101cb7506fcf8d40c177089e62671b
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/testing/juggler/protocol/Protocol.js
|
+++ b/testing/juggler/protocol/Protocol.js
|
||||||
@@ -0,0 +1,712 @@
|
@@ -0,0 +1,731 @@
|
||||||
+const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
|
+const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
|
||||||
+
|
+
|
||||||
+// Protocol-specific types.
|
+// Protocol-specific types.
|
||||||
|
|
@ -4738,6 +5004,18 @@ index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895eb
|
||||||
+ executionContextId: t.String,
|
+ executionContextId: t.String,
|
||||||
+ element: runtimeTypes.RemoteObject
|
+ element: runtimeTypes.RemoteObject
|
||||||
+ },
|
+ },
|
||||||
|
+ 'workerCreated': {
|
||||||
|
+ workerId: t.String,
|
||||||
|
+ frameId: t.String,
|
||||||
|
+ url: t.String,
|
||||||
|
+ },
|
||||||
|
+ 'workerDestroyed': {
|
||||||
|
+ workerId: t.String,
|
||||||
|
+ },
|
||||||
|
+ 'dispatchMessageFromWorker': {
|
||||||
|
+ workerId: t.String,
|
||||||
|
+ message: t.String,
|
||||||
|
+ },
|
||||||
+ },
|
+ },
|
||||||
+
|
+
|
||||||
+ methods: {
|
+ methods: {
|
||||||
|
|
@ -4940,6 +5218,13 @@ index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895eb
|
||||||
+ enabled: t.Boolean,
|
+ enabled: t.Boolean,
|
||||||
+ },
|
+ },
|
||||||
+ },
|
+ },
|
||||||
|
+ 'sendMessageToWorker': {
|
||||||
|
+ params: {
|
||||||
|
+ frameId: t.String,
|
||||||
|
+ workerId: t.String,
|
||||||
|
+ message: t.String,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
+ },
|
+ },
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,15 @@ FFOX_ALIASES=(
|
||||||
|
|
||||||
WK_REVISION=$(cat ../webkit/BUILD_NUMBER)
|
WK_REVISION=$(cat ../webkit/BUILD_NUMBER)
|
||||||
WK_ARCHIVES=(
|
WK_ARCHIVES=(
|
||||||
"$HOST/webkit/%s/minibrowser-linux.zip"
|
"$HOST/webkit/%s/minibrowser-gtk.zip"
|
||||||
|
"$HOST/webkit/%s/minibrowser-wpe.zip"
|
||||||
"$HOST/webkit/%s/minibrowser-mac-10.14.zip"
|
"$HOST/webkit/%s/minibrowser-mac-10.14.zip"
|
||||||
"$HOST/webkit/%s/minibrowser-mac-10.15.zip"
|
"$HOST/webkit/%s/minibrowser-mac-10.15.zip"
|
||||||
"$HOST/webkit/%s/minibrowser-win64.zip"
|
"$HOST/webkit/%s/minibrowser-win64.zip"
|
||||||
)
|
)
|
||||||
WK_ALIASES=(
|
WK_ALIASES=(
|
||||||
"WK-LINUX"
|
"WK-GTK"
|
||||||
|
"WK-WPE"
|
||||||
"WK-MAC-10.14"
|
"WK-MAC-10.14"
|
||||||
"WK-MAC-10.15"
|
"WK-MAC-10.15"
|
||||||
"WK-WIN64"
|
"WK-WIN64"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ trap "cd $(pwd -P)" EXIT
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
|
||||||
echo "usage: $(basename $0) [firefox|firefox-win64|webkit] [--check] [zip-path]"
|
echo "usage: $(basename $0) [firefox-linux|firefox-win32|firefox-win64|webkit-gtk|webkit-wpe|webkit-gtk-wpe|webkit-win64|webkit-mac-10.14|webkit-mac-10.15] [--check] [zip-path]"
|
||||||
echo
|
echo
|
||||||
echo "Upload .zip as a browser build."
|
echo "Upload .zip as a browser build."
|
||||||
echo
|
echo
|
||||||
|
|
@ -30,65 +30,48 @@ if [[ $# < 1 ]]; then
|
||||||
echo "try '$(basename $0) --help' for more information"
|
echo "try '$(basename $0) --help' for more information"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
BUILD_FLAVOR="$1"
|
||||||
BROWSER_NAME=""
|
BROWSER_NAME=""
|
||||||
BUILD_NUMBER=""
|
|
||||||
BLOB_NAME=""
|
BLOB_NAME=""
|
||||||
ALIAS=""
|
if [[ "$BUILD_FLAVOR" == "firefox-linux" ]]; then
|
||||||
|
|
||||||
if [[ ("$1" == "firefox") || ("$1" == "firefox/") ]]; then
|
|
||||||
BUILD_NUMBER=$(cat "$PWD/firefox/BUILD_NUMBER")
|
|
||||||
BROWSER_NAME="firefox"
|
BROWSER_NAME="firefox"
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
|
||||||
BLOB_NAME="firefox-mac.zip"
|
|
||||||
ALIAS="firefox-mac r$BUILD_NUMBER"
|
|
||||||
elif [[ "$(uname)" == "Linux" ]]; then
|
|
||||||
BLOB_NAME="firefox-linux.zip"
|
BLOB_NAME="firefox-linux.zip"
|
||||||
ALIAS="ff-linux r$BUILD_NUMBER"
|
elif [[ "$BUILD_FLAVOR" == "firefox-mac" ]]; then
|
||||||
elif [[ "$(uname)" == MINGW* ]]; then
|
BROWSER_NAME="firefox"
|
||||||
BLOB_NAME="firefox-win32.zip"
|
BLOB_NAME="firefox-mac.zip"
|
||||||
ALIAS="ff-win32 r$BUILD_NUMBER"
|
elif [[ "$BUILD_FLAVOR" == "firefox-win32" ]]; then
|
||||||
else
|
BROWSER_NAME="firefox"
|
||||||
echo "ERROR: unsupported platform - $(uname)"
|
BLOB_NAME="firefox-win32.zip"
|
||||||
exit 1
|
elif [[ "$BUILD_FLAVOR" == "firefox-win64" ]]; then
|
||||||
fi
|
|
||||||
elif [[ ("$1" == "firefox-win64") || ("$1" == "firefox-win64/") ]]; then
|
|
||||||
BUILD_NUMBER=$(cat "$PWD/firefox/BUILD_NUMBER")
|
|
||||||
BROWSER_NAME="firefox"
|
BROWSER_NAME="firefox"
|
||||||
if [[ "$(uname)" == MINGW* ]]; then
|
|
||||||
BLOB_NAME="firefox-win64.zip"
|
BLOB_NAME="firefox-win64.zip"
|
||||||
ALIAS="ff-win64 r$BUILD_NUMBER"
|
elif [[ "$BUILD_FLAVOR" == "webkit-gtk" ]]; then
|
||||||
else
|
BROWSER_NAME="webkit"
|
||||||
echo "ERROR: unsupported platform for browser '$1' - $(uname)"
|
BLOB_NAME="minibrowser-gtk.zip"
|
||||||
exit 1
|
elif [[ "$BUILD_FLAVOR" == "webkit-wpe" ]]; then
|
||||||
fi
|
BROWSER_NAME="webkit"
|
||||||
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") ]]; then
|
BLOB_NAME="minibrowser-wpe.zip"
|
||||||
BUILD_NUMBER=$(cat "$PWD/webkit/BUILD_NUMBER")
|
elif [[ "$BUILD_FLAVOR" == "webkit-gtk-wpe" ]]; then
|
||||||
|
BROWSER_NAME="webkit"
|
||||||
|
BLOB_NAME="minibrowser-gtk-wpe.zip"
|
||||||
|
elif [[ "$BUILD_FLAVOR" == "webkit-win64" ]]; then
|
||||||
BROWSER_NAME="webkit"
|
BROWSER_NAME="webkit"
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
|
||||||
MAC_MAJOR_MINOR_VERSION=$(sw_vers -productVersion | grep -o '^\d\+.\d\+')
|
|
||||||
BLOB_NAME="minibrowser-mac-$MAC_MAJOR_MINOR_VERSION.zip"
|
|
||||||
ALIAS="webkit-mac-$MAC_MAJOR_MINOR_VERSION r$BUILD_NUMBER"
|
|
||||||
elif [[ "$(uname)" == "Linux" ]]; then
|
|
||||||
BLOB_NAME="minibrowser-linux.zip"
|
|
||||||
ALIAS="webkit-linux r$BUILD_NUMBER"
|
|
||||||
elif [[ "$(uname)" == MINGW* ]]; then
|
|
||||||
BLOB_NAME="minibrowser-win64.zip"
|
BLOB_NAME="minibrowser-win64.zip"
|
||||||
ALIAS="webkit-win64 r$BUILD_NUMBER"
|
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.14" ]]; then
|
||||||
else
|
BROWSER_NAME="webkit"
|
||||||
echo "ERROR: unsupported platform - $(uname)"
|
BLOB_NAME="minibrowser-mac-10.14.zip"
|
||||||
exit 1
|
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.15" ]]; then
|
||||||
fi
|
BROWSER_NAME="webkit"
|
||||||
|
BLOB_NAME="minibrowser-mac-10.15.zip"
|
||||||
else
|
else
|
||||||
echo ERROR: unknown browser to export - "$1"
|
echo ERROR: unknown build flavor - "$BUILD_FLAVOR"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ("$2" == '--show-alias') || ("$3" == '--show-alias') ]]; then
|
BUILD_NUMBER=$(cat ./$BROWSER_NAME/BUILD_NUMBER)
|
||||||
echo $ALIAS
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
BLOB_PATH="$BROWSER_NAME/$BUILD_NUMBER/$BLOB_NAME"
|
BLOB_PATH="$BROWSER_NAME/$BUILD_NUMBER/$BLOB_NAME"
|
||||||
|
|
||||||
if [[ ("$2" == '--check') || ("$3" == '--check') ]]; then
|
if [[ ("$2" == '--check') || ("$3" == '--check') ]]; then
|
||||||
EXISTS=$(az storage blob exists -c builds --account-key $AZ_ACCOUNT_KEY --account-name $AZ_ACCOUNT_NAME -n "$BLOB_PATH" --query "exists")
|
EXISTS=$(az storage blob exists -c builds --account-key $AZ_ACCOUNT_KEY --account-name $AZ_ACCOUNT_NAME -n "$BLOB_PATH" --query "exists")
|
||||||
if [[ $EXISTS == "true" ]]; then
|
if [[ $EXISTS == "true" ]]; then
|
||||||
|
|
@ -103,7 +86,9 @@ if [[ $# < 2 ]]; then
|
||||||
echo "try '$(basename $0) --help' for more information"
|
echo "try '$(basename $0) --help' for more information"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
ZIP_PATH=$2
|
|
||||||
|
ZIP_PATH="$2"
|
||||||
|
|
||||||
if ! [[ -f $ZIP_PATH ]]; then
|
if ! [[ -f $ZIP_PATH ]]; then
|
||||||
echo "ERROR: $ZIP_PATH does not exist"
|
echo "ERROR: $ZIP_PATH does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1097
|
1100
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,15 @@ set -e
|
||||||
set +x
|
set +x
|
||||||
|
|
||||||
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
|
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
|
||||||
echo "usage: $(basename $0) [output-absolute-path]"
|
echo "usage: $(basename $0) [output-absolute-path] [--wpe]"
|
||||||
echo
|
echo
|
||||||
echo "Generate distributable .zip archive from ./checkout folder that was previously built."
|
echo "Generate distributable .zip archive from ./checkout folder that was previously built."
|
||||||
echo
|
echo
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $# != 1 ]]; then
|
|
||||||
echo "error: missing zip output path"
|
|
||||||
echo "try '$(basename $0) --help' for details"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ZIP_PATH=$1
|
ZIP_PATH=$1
|
||||||
|
USE_WPE=$2
|
||||||
if [[ $ZIP_PATH != /* ]]; then
|
if [[ $ZIP_PATH != /* ]]; then
|
||||||
echo "ERROR: path $ZIP_PATH is not absolute"
|
echo "ERROR: path $ZIP_PATH is not absolute"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -55,20 +50,35 @@ createZipForLinux() {
|
||||||
local tmpdir=$(mktemp -d -t webkit-deploy-XXXXXXXXXX)
|
local tmpdir=$(mktemp -d -t webkit-deploy-XXXXXXXXXX)
|
||||||
mkdir -p $tmpdir
|
mkdir -p $tmpdir
|
||||||
|
|
||||||
# copy all relevant binaries
|
|
||||||
cp -t $tmpdir ./WebKitBuild/Release/bin/MiniBrowser ./WebKitBuild/Release/bin/WebKit*Process
|
|
||||||
# copy runner
|
# copy runner
|
||||||
cp -t $tmpdir ../pw_run.sh
|
cp -t $tmpdir ../pw_run.sh
|
||||||
# copy protocol
|
# copy protocol
|
||||||
node ../concat_protocol.js > $tmpdir/protocol.json
|
node ../concat_protocol.js > $tmpdir/protocol.json
|
||||||
|
|
||||||
|
if [[ -n $USE_WPE ]]; then
|
||||||
|
# copy all relevant binaries
|
||||||
|
cp -t $tmpdir ./WebKitBuild/Release/bin/MiniBrowser ./WebKitBuild/Release/bin/WPE*Process
|
||||||
|
# copy all relevant shared objects
|
||||||
|
LD_LIBRARY_PATH="$PWD/WebKitBuild/DependenciesWPE/Root/lib" ldd WebKitBuild/Release/bin/MiniBrowser | grep -o '[^ ]*WebKitBuild/[^ ]*' | xargs cp -t $tmpdir
|
||||||
|
LD_LIBRARY_PATH="$PWD/WebKitBuild/DependenciesWPE/Root/lib" ldd WebKitBuild/Release/bin/WPENetworkProcess | grep -o '[^ ]*WebKitBuild/[^ ]*' | xargs cp -t $tmpdir
|
||||||
|
LD_LIBRARY_PATH="$PWD/WebKitBuild/DependenciesWPE/Root/lib" ldd WebKitBuild/Release/bin/WPEWebProcess | grep -o '[^ ]*WebKitBuild/[^ ]*' | xargs cp -t $tmpdir
|
||||||
|
cd $tmpdir
|
||||||
|
ln -s libWPEBackend-fdo-1.0.so.1 libWPEBackend-fdo-1.0.so
|
||||||
|
cd -
|
||||||
|
else
|
||||||
|
# copy all relevant binaries
|
||||||
|
cp -t $tmpdir ./WebKitBuild/Release/bin/MiniBrowser ./WebKitBuild/Release/bin/WebKit*Process
|
||||||
# copy all relevant shared objects
|
# 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
|
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
|
# we failed to nicely build libgdk_pixbuf - expect it in the env
|
||||||
rm $tmpdir/libgdk_pixbuf*
|
rm $tmpdir/libgdk_pixbuf*
|
||||||
|
fi
|
||||||
|
|
||||||
# tar resulting directory and cleanup TMP.
|
# tar resulting directory and cleanup TMP.
|
||||||
zip -jr $ZIP_PATH $tmpdir
|
cd $tmpdir
|
||||||
|
zip --symlinks -r $ZIP_PATH ./
|
||||||
|
cd -
|
||||||
rm -rf $tmpdir
|
rm -rf $tmpdir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,9 +90,12 @@ createZipForWindows() {
|
||||||
cp -t $tmpdir ./WebKitLibraries/win/bin64/*.dll
|
cp -t $tmpdir ./WebKitLibraries/win/bin64/*.dll
|
||||||
cd WebKitBuild/Release/bin64
|
cd WebKitBuild/Release/bin64
|
||||||
cp -r -t $tmpdir WebKit.resources
|
cp -r -t $tmpdir WebKit.resources
|
||||||
cp -t $tmpdir JavaScriptCore.dll MiniBrowserLib.dll WTF.dll WebKit.dll WebKit2.dll libEGL.dll libGLESv2.dll
|
cp -t $tmpdir JavaScriptCore.dll MiniBrowserLib.dll WTF.dll WebKit2.dll libEGL.dll libGLESv2.dll
|
||||||
cp -t $tmpdir MiniBrowser.exe WebKitNetworkProcess.exe WebKitWebProcess.exe
|
cp -t $tmpdir MiniBrowser.exe WebKitNetworkProcess.exe WebKitWebProcess.exe
|
||||||
cd -
|
cd -
|
||||||
|
cd /c/WEBKIT_WIN64_LIBS
|
||||||
|
cp -t $tmpdir msvcp140.dll vcruntime140.dll vcruntime140_1.dll
|
||||||
|
cd -
|
||||||
|
|
||||||
# copy protocol
|
# copy protocol
|
||||||
node ../concat_protocol.js > $tmpdir/protocol.json
|
node ../concat_protocol.js > $tmpdir/protocol.json
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,17 @@ if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
./Tools/Scripts/build-webkit --release --touch-events
|
./Tools/Scripts/build-webkit --release --touch-events
|
||||||
elif [[ "$(uname)" == "Linux" ]]; then
|
elif [[ "$(uname)" == "Linux" ]]; then
|
||||||
cd "checkout"
|
cd "checkout"
|
||||||
# Check that WebKitBuild exists and is not empty.
|
if [[ "$1" == "--wpe" ]]; then
|
||||||
if ! [[ (-d ./WebKitBuild) && (-n $(ls -1 ./WebKitBuild/)) ]]; then
|
if ! [[ -d ./WebKitBuild/DependenciesWPE ]]; then
|
||||||
|
yes | DEBIAN_FRONTEND=noninteractive ./Tools/Scripts/update-webkitwpe-libs
|
||||||
|
fi
|
||||||
|
./Tools/Scripts/build-webkit --wpe --release --touch-events MiniBrowser
|
||||||
|
else
|
||||||
|
if ! [[ -d ./WebKitBuild/DependenciesGTK ]]; then
|
||||||
yes | DEBIAN_FRONTEND=noninteractive ./Tools/Scripts/update-webkitgtk-libs
|
yes | DEBIAN_FRONTEND=noninteractive ./Tools/Scripts/update-webkitgtk-libs
|
||||||
fi
|
fi
|
||||||
./Tools/Scripts/build-webkit --gtk --release --touch-events MiniBrowser
|
./Tools/Scripts/build-webkit --gtk --release --touch-events MiniBrowser
|
||||||
|
fi
|
||||||
elif [[ "$(uname)" == MINGW* ]]; then
|
elif [[ "$(uname)" == MINGW* ]]; then
|
||||||
/c/Windows/System32/cmd.exe "/c buildwin.bat"
|
/c/Windows/System32/cmd.exe "/c buildwin.bat"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
79
browser_patches/webkit/download_gtk_and_wpe_and_zip_together.sh
Executable file
79
browser_patches/webkit/download_gtk_and_wpe_and_zip_together.sh
Executable file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set +x
|
||||||
|
|
||||||
|
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
|
||||||
|
echo "usage: $(basename $0) [ZIP-PATH]"
|
||||||
|
echo
|
||||||
|
echo "Generate a single .zip archive that contains both gtk and wpe builds"
|
||||||
|
echo
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$(uname)" != "Linux" ]]; then
|
||||||
|
echo "ERROR: this script works only on linux"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ZIP_PATH="$1"
|
||||||
|
if [[ $ZIP_PATH != /* ]]; then
|
||||||
|
echo "ERROR: path $ZIP_PATH is not absolute"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ $ZIP_PATH != *.zip ]]; then
|
||||||
|
echo "ERROR: path $ZIP_PATH must have .zip extension"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -f $ZIP_PATH ]]; then
|
||||||
|
echo "ERROR: path $ZIP_PATH exists; can't do anything."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! [[ -d $(dirname $ZIP_PATH) ]]; then
|
||||||
|
echo "ERROR: folder for path $($ZIP_PATH) does not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap "cd $(pwd -P)" EXIT
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# create a TMP directory to copy all necessary files
|
||||||
|
TMPDIR=$(mktemp -d -t webkit-deploy-XXXXXXXXXX)
|
||||||
|
GTK_ZIP_PATH=$(mktemp -t -u minibrowser-gtk-XXXXXX.zip)
|
||||||
|
WPE_ZIP_PATH=$(mktemp -t -u minibrowser-wpe-XXXXXX.zip)
|
||||||
|
../download.sh webkit-gtk $GTK_ZIP_PATH
|
||||||
|
../download.sh webkit-wpe $WPE_ZIP_PATH
|
||||||
|
|
||||||
|
# Create directory
|
||||||
|
mkdir -p $TMPDIR
|
||||||
|
|
||||||
|
# copy runner
|
||||||
|
cp -t $TMPDIR ./pw_run.sh
|
||||||
|
|
||||||
|
pushd $TMPDIR
|
||||||
|
|
||||||
|
# Copy MiniBrowser-GTK
|
||||||
|
mkdir minibrowser-gtk
|
||||||
|
pushd minibrowser-gtk
|
||||||
|
cp $GTK_ZIP_PATH archive.zip
|
||||||
|
unzip archive.zip
|
||||||
|
rm archive.zip
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Copy MiniBrowser-WPE
|
||||||
|
mkdir minibrowser-wpe
|
||||||
|
pushd minibrowser-wpe
|
||||||
|
cp $WPE_ZIP_PATH archive.zip
|
||||||
|
unzip archive.zip
|
||||||
|
rm archive.zip
|
||||||
|
popd
|
||||||
|
|
||||||
|
mv minibrowser-gtk/protocol.json .
|
||||||
|
rm minibrowser-wpe/protocol.json
|
||||||
|
|
||||||
|
zip --symlinks -r $ZIP_PATH ./
|
||||||
|
popd
|
||||||
|
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
rm -rf $WPE_ZIP_PATH
|
||||||
|
rm -rf $GTK_ZIP_PATH
|
||||||
|
|
@ -11147,11 +11147,31 @@ index 4c41864d89f40567ed81ed2efefb501f6753db84..b9cab7c400c0c129ea4a9851dc397682
|
||||||
|
|
||||||
// For backwards compatibility with the WebBackForwardList API, we honor both
|
// For backwards compatibility with the WebBackForwardList API, we honor both
|
||||||
// a per-WebView and a per-preferences setting for whether to use the back/forward cache.
|
// a per-WebView and a per-preferences setting for whether to use the back/forward cache.
|
||||||
|
diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
|
||||||
|
index ba7f352a2adcf7180511cd0a404a015c138adfd9..c27a7f1a2faa8189dbf6c53a915f44e2abdffdb0 100644
|
||||||
|
--- a/Source/cmake/OptionsGTK.cmake
|
||||||
|
+++ b/Source/cmake/OptionsGTK.cmake
|
||||||
|
@@ -3,6 +3,7 @@ include(VersioningUtils)
|
||||||
|
|
||||||
|
SET_PROJECT_VERSION(2 27 3)
|
||||||
|
set(WEBKITGTK_API_VERSION 4.0)
|
||||||
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
||||||
|
|
||||||
|
CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 79 0 42)
|
||||||
|
CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 33 2 15)
|
||||||
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
|
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
|
||||||
index 2fbbb581c02b6f4834ae8affa554df0fb2e311e1..1dd53b7970105b3e1191dbfb9545f406ef097646 100644
|
index 2fbbb581c02b6f4834ae8affa554df0fb2e311e1..d4e2956db6b1ff83ddf5641436770e09fe0c2df7 100644
|
||||||
--- a/Source/cmake/OptionsWPE.cmake
|
--- a/Source/cmake/OptionsWPE.cmake
|
||||||
+++ b/Source/cmake/OptionsWPE.cmake
|
+++ b/Source/cmake/OptionsWPE.cmake
|
||||||
@@ -49,6 +49,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON)
|
@@ -3,6 +3,7 @@ include(VersioningUtils)
|
||||||
|
|
||||||
|
SET_PROJECT_VERSION(2 27 3)
|
||||||
|
set(WPE_API_VERSION 1.0)
|
||||||
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
||||||
|
|
||||||
|
CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 11 0 8)
|
||||||
|
|
||||||
|
@@ -49,6 +50,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON)
|
||||||
# Changing these options is completely unsupported.
|
# Changing these options is completely unsupported.
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ASYNC_SCROLLING PRIVATE ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ASYNC_SCROLLING PRIVATE ON)
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CONTENT_EXTENSIONS PRIVATE ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CONTENT_EXTENSIONS PRIVATE ON)
|
||||||
|
|
@ -11160,10 +11180,21 @@ index 2fbbb581c02b6f4834ae8affa554df0fb2e311e1..1dd53b7970105b3e1191dbfb9545f406
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
|
||||||
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
|
diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake
|
||||||
index 1019fce94d5389a1f7b15675199dc02ccc68fcc3..5335aed3b8fba48b92407d988d5c7b49b94bc0ce 100644
|
index 1019fce94d5389a1f7b15675199dc02ccc68fcc3..785cc43328c8f306e73382a7aaba619f8fc91fe4 100644
|
||||||
--- a/Source/cmake/OptionsWin.cmake
|
--- a/Source/cmake/OptionsWin.cmake
|
||||||
+++ b/Source/cmake/OptionsWin.cmake
|
+++ b/Source/cmake/OptionsWin.cmake
|
||||||
@@ -79,6 +79,8 @@ if (${WTF_PLATFORM_WIN_CAIRO})
|
@@ -7,8 +7,9 @@ add_definitions(-D_WINDOWS -DWINVER=0x601 -D_WIN32_WINNT=0x601)
|
||||||
|
add_definitions(-DNOMINMAX)
|
||||||
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
|
|
||||||
|
+set(ENABLE_WEBKIT_LEGACY OFF)
|
||||||
|
+
|
||||||
|
if ((NOT DEFINED ENABLE_WEBKIT_LEGACY) OR ENABLE_WEBKIT_LEGACY)
|
||||||
|
- set(ENABLE_WEBKIT_LEGACY ON)
|
||||||
|
set(ENABLE_WEBKIT OFF)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
@@ -79,6 +80,8 @@ if (${WTF_PLATFORM_WIN_CAIRO})
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE ON)
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE ON)
|
||||||
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PUBLIC ON)
|
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PUBLIC ON)
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
function runOSX() {
|
function runOSX() {
|
||||||
# if script is run as-is
|
# if script is run as-is
|
||||||
if [ -d $SCRIPT_PATH/checkout/WebKitBuild/Release/MiniBrowser.app ]; then
|
if [[ -d $SCRIPT_PATH/checkout/WebKitBuild/Release/MiniBrowser.app ]]; then
|
||||||
DYLIB_PATH="$SCRIPT_PATH/checkout/WebKitBuild/Release"
|
DYLIB_PATH="$SCRIPT_PATH/checkout/WebKitBuild/Release"
|
||||||
elif [ -d $SCRIPT_PATH/MiniBrowser.app ]; then
|
elif [[ -d $SCRIPT_PATH/MiniBrowser.app ]]; then
|
||||||
DYLIB_PATH="$SCRIPT_PATH"
|
DYLIB_PATH="$SCRIPT_PATH"
|
||||||
elif [ -d $SCRIPT_PATH/WebKitBuild/Release/MiniBrowser.app ]; then
|
elif [[ -d $SCRIPT_PATH/WebKitBuild/Release/MiniBrowser.app ]]; then
|
||||||
DYLIB_PATH="$SCRIPT_PATH/WebKitBuild/Release"
|
DYLIB_PATH="$SCRIPT_PATH/WebKitBuild/Release"
|
||||||
else
|
else
|
||||||
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
|
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
|
||||||
|
|
@ -18,14 +18,23 @@ function runOSX() {
|
||||||
|
|
||||||
function runLinux() {
|
function runLinux() {
|
||||||
# if script is run as-is
|
# if script is run as-is
|
||||||
if [ -d $SCRIPT_PATH/checkout/WebKitBuild ]; then
|
DEPENDENCIES_FOLDER="DependenciesGTK"
|
||||||
LD_PATH="$SCRIPT_PATH/checkout/WebKitBuild/DependenciesGTK/Root/lib:$SCRIPT_PATH/checkout/WebKitBuild/Release/bin"
|
MINIBROWSER_FOLDER="minibrowser-gtk";
|
||||||
|
if [[ "$*" == *--headless* ]]; then
|
||||||
|
DEPENDENCIES_FOLDER="DependenciesWPE";
|
||||||
|
MINIBROWSER_FOLDER="minibrowser-wpe";
|
||||||
|
fi
|
||||||
|
if [[ -d $SCRIPT_PATH/$MINIBROWSER_FOLDER ]]; then
|
||||||
|
LD_PATH="$SCRIPT_PATH/$MINIBROWSER_FOLDER"
|
||||||
|
MINIBROWSER="$SCRIPT_PATH/$MINIBROWSER_FOLDER/MiniBrowser"
|
||||||
|
elif [[ -d $SCRIPT_PATH/checkout/WebKitBuild ]]; then
|
||||||
|
LD_PATH="$SCRIPT_PATH/checkout/WebKitBuild/$DEPENDENCIES_FOLDER/Root/lib:$SCRIPT_PATH/checkout/WebKitBuild/Release/bin"
|
||||||
MINIBROWSER="$SCRIPT_PATH/checkout/WebKitBuild/Release/bin/MiniBrowser"
|
MINIBROWSER="$SCRIPT_PATH/checkout/WebKitBuild/Release/bin/MiniBrowser"
|
||||||
elif [ -f $SCRIPT_PATH/MiniBrowser ]; then
|
elif [[ -f $SCRIPT_PATH/MiniBrowser ]]; then
|
||||||
LD_PATH="$SCRIPT_PATH"
|
LD_PATH="$SCRIPT_PATH"
|
||||||
MINIBROWSER="$SCRIPT_PATH/MiniBrowser"
|
MINIBROWSER="$SCRIPT_PATH/MiniBrowser"
|
||||||
elif [ -d $SCRIPT_PATH/WebKitBuild ]; then
|
elif [[ -d $SCRIPT_PATH/WebKitBuild ]]; then
|
||||||
LD_PATH="$SCRIPT_PATH/WebKitBuild/DependenciesGTK/Root/lib:$SCRIPT_PATH/WebKitBuild/Release/bin"
|
LD_PATH="$SCRIPT_PATH/WebKitBuild/$DEPENDENCIES_FOLDER/Root/lib:$SCRIPT_PATH/WebKitBuild/Release/bin"
|
||||||
MINIBROWSER="$SCRIPT_PATH/WebKitBuild/Release/bin/MiniBrowser"
|
MINIBROWSER="$SCRIPT_PATH/WebKitBuild/Release/bin/MiniBrowser"
|
||||||
else
|
else
|
||||||
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
|
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
|
||||||
|
|
@ -35,9 +44,9 @@ function runLinux() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
|
||||||
if [ "$(uname)" == "Darwin" ]; then
|
if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
runOSX "$@"
|
runOSX "$@"
|
||||||
elif [ "$(uname)" == "Linux" ]; then
|
elif [[ "$(uname)" == "Linux" ]]; then
|
||||||
runLinux "$@"
|
runLinux "$@"
|
||||||
else
|
else
|
||||||
echo "ERROR: cannot run on this platform!" 1>&2
|
echo "ERROR: cannot run on this platform!" 1>&2
|
||||||
|
|
|
||||||
|
|
@ -3565,6 +3565,8 @@ Browser websocket endpoint which can be used as an argument to [firefoxPlaywrigh
|
||||||
|
|
||||||
#### webkitPlaywright.defaultArgs([options])
|
#### webkitPlaywright.defaultArgs([options])
|
||||||
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
||||||
|
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
||||||
|
- `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
|
||||||
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
||||||
- returns: <[Array]<[string]>>
|
- returns: <[Array]<[string]>>
|
||||||
|
|
||||||
|
|
@ -3575,6 +3577,7 @@ The default flags that WebKit will be launched with.
|
||||||
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
||||||
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
||||||
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
||||||
|
- `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
|
||||||
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
||||||
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
|
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
|
||||||
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
|
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
|
||||||
|
|
@ -3598,6 +3601,7 @@ const browser = await playwright.launch({
|
||||||
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
||||||
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
||||||
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
||||||
|
- `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
|
||||||
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
|
||||||
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
|
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
|
||||||
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
|
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"chromium_revision": "724623",
|
"chromium_revision": "724623",
|
||||||
"firefox_revision": "1015",
|
"firefox_revision": "1016",
|
||||||
"webkit_revision": "1097"
|
"webkit_revision": "1099"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"unit": "node test/test.js",
|
"unit": "node test/test.js",
|
||||||
|
|
|
||||||
|
|
@ -191,15 +191,18 @@ export class FrameManager {
|
||||||
for (const watcher of this._lifecycleWatchers)
|
for (const watcher of this._lifecycleWatchers)
|
||||||
watcher._onNavigationRequest(frame, request);
|
watcher._onNavigationRequest(frame, request);
|
||||||
}
|
}
|
||||||
|
if (!request._isFavicon)
|
||||||
this._page.emit(Events.Page.Request, request);
|
this._page.emit(Events.Page.Request, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestReceivedResponse(response: network.Response) {
|
requestReceivedResponse(response: network.Response) {
|
||||||
|
if (!response.request()._isFavicon)
|
||||||
this._page.emit(Events.Page.Response, response);
|
this._page.emit(Events.Page.Response, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestFinished(request: network.Request) {
|
requestFinished(request: network.Request) {
|
||||||
this._inflightRequestFinished(request);
|
this._inflightRequestFinished(request);
|
||||||
|
if (!request._isFavicon)
|
||||||
this._page.emit(Events.Page.RequestFinished, request);
|
this._page.emit(Events.Page.RequestFinished, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,6 +219,7 @@ export class FrameManager {
|
||||||
watcher._onAbortedNewDocumentNavigation(frame, request._documentId, errorText);
|
watcher._onAbortedNewDocumentNavigation(frame, request._documentId, errorText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!request._isFavicon)
|
||||||
this._page.emit(Events.Page.RequestFailed, request);
|
this._page.emit(Events.Page.RequestFailed, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +240,7 @@ export class FrameManager {
|
||||||
|
|
||||||
private _inflightRequestFinished(request: network.Request) {
|
private _inflightRequestFinished(request: network.Request) {
|
||||||
const frame = request.frame();
|
const frame = request.frame();
|
||||||
if (!frame || request.url().endsWith('favicon.ico'))
|
if (!frame || request._isFavicon)
|
||||||
return;
|
return;
|
||||||
if (!frame._inflightRequests.has(request))
|
if (!frame._inflightRequests.has(request))
|
||||||
return;
|
return;
|
||||||
|
|
@ -249,7 +253,7 @@ export class FrameManager {
|
||||||
|
|
||||||
private _inflightRequestStarted(request: network.Request) {
|
private _inflightRequestStarted(request: network.Request) {
|
||||||
const frame = request.frame();
|
const frame = request.frame();
|
||||||
if (!frame || request.url().endsWith('favicon.ico'))
|
if (!frame || request._isFavicon)
|
||||||
return;
|
return;
|
||||||
frame._inflightRequests.add(request);
|
frame._inflightRequests.add(request);
|
||||||
if (frame._inflightRequests.size === 1)
|
if (frame._inflightRequests.size === 1)
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ export class Request {
|
||||||
_redirectChain: Request[];
|
_redirectChain: Request[];
|
||||||
_finalRequest: Request;
|
_finalRequest: Request;
|
||||||
readonly _documentId?: string;
|
readonly _documentId?: string;
|
||||||
|
readonly _isFavicon: boolean;
|
||||||
private _failureText: string | null = null;
|
private _failureText: string | null = null;
|
||||||
private _url: string;
|
private _url: string;
|
||||||
private _resourceType: string;
|
private _resourceType: string;
|
||||||
|
|
@ -127,6 +128,7 @@ export class Request {
|
||||||
this._headers = headers;
|
this._headers = headers;
|
||||||
this._waitForResponsePromise = new Promise(f => this._waitForResponsePromiseCallback = f);
|
this._waitForResponsePromise = new Promise(f => this._waitForResponsePromiseCallback = f);
|
||||||
this._waitForFinishedPromise = new Promise(f => this._waitForFinishedPromiseCallback = f);
|
this._waitForFinishedPromise = new Promise(f => this._waitForFinishedPromiseCallback = f);
|
||||||
|
this._isFavicon = url.endsWith('/favicon.ico');
|
||||||
}
|
}
|
||||||
|
|
||||||
_setFailureText(failureText: string) {
|
_setFailureText(failureText: string) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
/**
|
||||||
// Licensed under the MIT license.
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
// Note: this is the only file outside of src/server which can import external dependencies.
|
// Note: this is the only file outside of src/server which can import external dependencies.
|
||||||
// All dependencies must be listed in web.webpack.config.js to avoid bundling them.
|
// All dependencies must be listed in web.webpack.config.js to avoid bundling them.
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ export class WKPlaywright implements Playwright {
|
||||||
|
|
||||||
_createBrowserFetcher(options?: BrowserFetcherOptions): BrowserFetcher {
|
_createBrowserFetcher(options?: BrowserFetcherOptions): BrowserFetcher {
|
||||||
const downloadURLs = {
|
const downloadURLs = {
|
||||||
linux: '%s/builds/webkit/%s/minibrowser-linux.zip',
|
linux: '%s/builds/webkit/%s/minibrowser-gtk-wpe.zip',
|
||||||
mac: '%s/builds/webkit/%s/minibrowser-mac-%s.zip',
|
mac: '%s/builds/webkit/%s/minibrowser-mac-%s.zip',
|
||||||
win64: '%s/builds/webkit/%s/minibrowser-win64.zip',
|
win64: '%s/builds/webkit/%s/minibrowser-win64.zip',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ export class WKNetworkManager {
|
||||||
helper.removeEventListeners(this._sessionListeners);
|
helper.removeEventListeners(this._sessionListeners);
|
||||||
this._session = session;
|
this._session = session;
|
||||||
this._sessionListeners = [
|
this._sessionListeners = [
|
||||||
helper.addEventListener(this._session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this)),
|
helper.addEventListener(session, 'Network.requestWillBeSent', e => this._onRequestWillBeSent(session, e)),
|
||||||
helper.addEventListener(this._session, 'Network.requestIntercepted', this._onRequestIntercepted.bind(this)),
|
helper.addEventListener(session, 'Network.requestIntercepted', e => this._onRequestIntercepted(e)),
|
||||||
helper.addEventListener(this._session, 'Network.responseReceived', this._onResponseReceived.bind(this)),
|
helper.addEventListener(session, 'Network.responseReceived', e => this._onResponseReceived(e)),
|
||||||
helper.addEventListener(this._session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)),
|
helper.addEventListener(session, 'Network.loadingFinished', e => this._onLoadingFinished(e)),
|
||||||
helper.addEventListener(this._session, 'Network.loadingFailed', this._onLoadingFailed.bind(this)),
|
helper.addEventListener(session, 'Network.loadingFailed', e => this._onLoadingFailed(e)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,13 +77,13 @@ export class WKNetworkManager {
|
||||||
await this._session.send('Network.setInterceptionEnabled', { enabled, interceptRequests: enabled });
|
await this._session.send('Network.setInterceptionEnabled', { enabled, interceptRequests: enabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
async _updateProtocolCacheDisabled() {
|
private async _updateProtocolCacheDisabled() {
|
||||||
await this._session.send('Network.setResourceCachingDisabled', {
|
await this._session.send('Network.setResourceCachingDisabled', {
|
||||||
disabled: this._userCacheDisabled
|
disabled: this._userCacheDisabled
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload) {
|
_onRequestWillBeSent(session: WKSession, event: Protocol.Network.requestWillBeSentPayload) {
|
||||||
if (event.request.url.startsWith('data:'))
|
if (event.request.url.startsWith('data:'))
|
||||||
return;
|
return;
|
||||||
let redirectChain: network.Request[] = [];
|
let redirectChain: network.Request[] = [];
|
||||||
|
|
@ -99,7 +99,7 @@ export class WKNetworkManager {
|
||||||
// TODO(einbinder) this will fail if we are an XHR document request
|
// TODO(einbinder) this will fail if we are an XHR document request
|
||||||
const isNavigationRequest = event.type === 'Document';
|
const isNavigationRequest = event.type === 'Document';
|
||||||
const documentId = isNavigationRequest ? event.loaderId : undefined;
|
const documentId = isNavigationRequest ? event.loaderId : undefined;
|
||||||
const request = new InterceptableRequest(this._session, !!this._page._state.interceptNetwork, frame, event, redirectChain, documentId);
|
const request = new InterceptableRequest(session, !!this._page._state.interceptNetwork, frame, event, redirectChain, documentId);
|
||||||
this._requestIdToRequest.set(event.requestId, request);
|
this._requestIdToRequest.set(event.requestId, request);
|
||||||
this._page._frameManager.requestStarted(request.request);
|
this._page._frameManager.requestStarted(request.request);
|
||||||
}
|
}
|
||||||
|
|
@ -110,17 +110,17 @@ export class WKNetworkManager {
|
||||||
request._interceptedCallback();
|
request._interceptedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): network.Response {
|
private static _createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): network.Response {
|
||||||
const remoteAddress: network.RemoteAddress = { ip: '', port: 0 };
|
const remoteAddress: network.RemoteAddress = { ip: '', port: 0 };
|
||||||
const getResponseBody = async () => {
|
const getResponseBody = async () => {
|
||||||
const response = await this._session.send('Network.getResponseBody', { requestId: request._requestId });
|
const response = await request._session.send('Network.getResponseBody', { requestId: request._requestId });
|
||||||
return platform.Buffer.from(response.body, response.base64Encoded ? 'base64' : 'utf8');
|
return platform.Buffer.from(response.body, response.base64Encoded ? 'base64' : 'utf8');
|
||||||
};
|
};
|
||||||
return new network.Response(request.request, responsePayload.status, responsePayload.statusText, headersObject(responsePayload.headers), remoteAddress, getResponseBody);
|
return new network.Response(request.request, responsePayload.status, responsePayload.statusText, headersObject(responsePayload.headers), remoteAddress, getResponseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleRequestRedirect(request: InterceptableRequest, responsePayload: Protocol.Network.Response) {
|
private _handleRequestRedirect(request: InterceptableRequest, responsePayload: Protocol.Network.Response) {
|
||||||
const response = this._createResponse(request, responsePayload);
|
const response = WKNetworkManager._createResponse(request, responsePayload);
|
||||||
request.request._redirectChain.push(request.request);
|
request.request._redirectChain.push(request.request);
|
||||||
response._requestFinished(new Error('Response body is unavailable for redirect responses'));
|
response._requestFinished(new Error('Response body is unavailable for redirect responses'));
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
|
|
@ -133,7 +133,7 @@ export class WKNetworkManager {
|
||||||
// FileUpload sends a response without a matching request.
|
// FileUpload sends a response without a matching request.
|
||||||
if (!request)
|
if (!request)
|
||||||
return;
|
return;
|
||||||
const response = this._createResponse(request, event.response);
|
const response = WKNetworkManager._createResponse(request, event.response);
|
||||||
this._page._frameManager.requestReceivedResponse(response);
|
this._page._frameManager.requestReceivedResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ const errorReasons: { [reason: string]: string } = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterceptableRequest implements network.RequestDelegate {
|
class InterceptableRequest implements network.RequestDelegate {
|
||||||
private _session: WKSession;
|
readonly _session: WKSession;
|
||||||
readonly request: network.Request;
|
readonly request: network.Request;
|
||||||
_requestId: string;
|
_requestId: string;
|
||||||
_documentId: string | undefined;
|
_documentId: string | undefined;
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,9 @@ export class WKPage implements PageDelegate {
|
||||||
_session: WKSession;
|
_session: WKSession;
|
||||||
readonly _page: Page;
|
readonly _page: Page;
|
||||||
private readonly _pageProxySession: WKSession;
|
private readonly _pageProxySession: WKSession;
|
||||||
private readonly _networkManager: WKNetworkManager;
|
readonly _networkManager: WKNetworkManager;
|
||||||
private readonly _workers: WKWorkers;
|
private readonly _workers: WKWorkers;
|
||||||
private readonly _contextIdToContext: Map<number, dom.FrameExecutionContext>;
|
private readonly _contextIdToContext: Map<number, dom.FrameExecutionContext>;
|
||||||
private _isolatedWorlds: Set<string>;
|
|
||||||
private _sessionListeners: RegisteredListener[] = [];
|
private _sessionListeners: RegisteredListener[] = [];
|
||||||
private readonly _bootstrapScripts: string[] = [];
|
private readonly _bootstrapScripts: string[] = [];
|
||||||
|
|
||||||
|
|
@ -55,14 +54,13 @@ export class WKPage implements PageDelegate {
|
||||||
this.rawKeyboard = new RawKeyboardImpl(pageProxySession);
|
this.rawKeyboard = new RawKeyboardImpl(pageProxySession);
|
||||||
this.rawMouse = new RawMouseImpl(pageProxySession);
|
this.rawMouse = new RawMouseImpl(pageProxySession);
|
||||||
this._contextIdToContext = new Map();
|
this._contextIdToContext = new Map();
|
||||||
this._isolatedWorlds = new Set();
|
|
||||||
this._page = new Page(this, browserContext);
|
this._page = new Page(this, browserContext);
|
||||||
this._networkManager = new WKNetworkManager(this._page, pageProxySession);
|
this._networkManager = new WKNetworkManager(this._page, pageProxySession);
|
||||||
this._workers = new WKWorkers(this._page);
|
this._workers = new WKWorkers(this._page);
|
||||||
this._session = undefined as any as WKSession;
|
this._session = undefined as any as WKSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initializePageProxySession() {
|
private async _initializePageProxySession() {
|
||||||
const promises : Promise<any>[] = [
|
const promises : Promise<any>[] = [
|
||||||
this._pageProxySession.send('Dialog.enable'),
|
this._pageProxySession.send('Dialog.enable'),
|
||||||
this._networkManager.initializePageProxySession(this._page._state.credentials)
|
this._networkManager.initializePageProxySession(this._page._state.credentials)
|
||||||
|
|
@ -83,38 +81,46 @@ export class WKPage implements PageDelegate {
|
||||||
this._addSessionListeners();
|
this._addSessionListeners();
|
||||||
this._networkManager.setSession(session);
|
this._networkManager.setSession(session);
|
||||||
this._workers.setSession(session);
|
this._workers.setSession(session);
|
||||||
this._isolatedWorlds = new Set();
|
|
||||||
// New bootstrap scripts may have been added during provisional load, push them
|
// New bootstrap scripts may have been added during provisional load, push them
|
||||||
// again to be on the safe side.
|
// again to be on the safe side.
|
||||||
if (this._bootstrapScripts.length)
|
if (this._bootstrapScripts.length)
|
||||||
this._setBootstrapScripts(session).catch(e => debugError(e));
|
this._setBootstrapScripts(session).catch(e => debugError(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async initialize() {
|
||||||
|
await Promise.all([
|
||||||
|
this._initializePageProxySession(),
|
||||||
|
this._initializeSession(this._session, ({frameTree}) => this._handleFrameTree(frameTree)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// This method is called for provisional targets as well. The session passed as the parameter
|
// This method is called for provisional targets as well. The session passed as the parameter
|
||||||
// may be different from the current session and may be destroyed without becoming current.
|
// may be different from the current session and may be destroyed without becoming current.
|
||||||
async _initializeSession(session: WKSession, isProvisional: boolean) {
|
async _initializeSession(session: WKSession, resourceTreeHandler: (r: Protocol.Page.getResourceTreeReturnValue) => void) {
|
||||||
|
const isProvisional = this._session !== session;
|
||||||
const promises : Promise<any>[] = [
|
const promises : Promise<any>[] = [
|
||||||
// Page agent must be enabled before Runtime.
|
// Page agent must be enabled before Runtime.
|
||||||
session.send('Page.enable'),
|
session.send('Page.enable'),
|
||||||
session.send('Page.getResourceTree').then(({frameTree}) => this._handleFrameTree(frameTree)),
|
session.send('Page.getResourceTree').then(resourceTreeHandler),
|
||||||
// Resource tree should be received before first execution context.
|
// Resource tree should be received before first execution context.
|
||||||
session.send('Runtime.enable').then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
|
session.send('Runtime.enable'),
|
||||||
|
session.send('Page.createIsolatedWorld', { name: UTILITY_WORLD_NAME, source: `//# sourceURL=${EVALUATION_SCRIPT_URL}` }),
|
||||||
session.send('Console.enable'),
|
session.send('Console.enable'),
|
||||||
session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
|
session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
|
||||||
this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode),
|
this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode),
|
||||||
this._workers.initializeSession(session),
|
this._workers.initializeSession(session)
|
||||||
];
|
];
|
||||||
const contextOptions = this._page.browserContext()._options;
|
const contextOptions = this._page.browserContext()._options;
|
||||||
if (contextOptions.userAgent)
|
if (contextOptions.userAgent)
|
||||||
promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent }));
|
promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent }));
|
||||||
if (this._page._state.mediaType || this._page._state.colorScheme)
|
if (this._page._state.mediaType || this._page._state.colorScheme)
|
||||||
promises.push(this._setEmulateMedia(session, this._page._state.mediaType, this._page._state.colorScheme));
|
promises.push(WKPage._setEmulateMedia(session, this._page._state.mediaType, this._page._state.colorScheme));
|
||||||
if (isProvisional)
|
if (isProvisional)
|
||||||
promises.push(this._setBootstrapScripts(session));
|
promises.push(this._setBootstrapScripts(session));
|
||||||
if (contextOptions.bypassCSP)
|
if (contextOptions.bypassCSP)
|
||||||
promises.push(session.send('Page.setBypassCSP', { enabled: true }));
|
promises.push(session.send('Page.setBypassCSP', { enabled: true }));
|
||||||
if (this._page._state.extraHTTPHeaders !== null)
|
if (this._page._state.extraHTTPHeaders !== null)
|
||||||
promises.push(this._setExtraHTTPHeaders(session, this._page._state.extraHTTPHeaders));
|
promises.push(WKPage._setExtraHTTPHeaders(session, this._page._state.extraHTTPHeaders));
|
||||||
if (this._page._state.hasTouch)
|
if (this._page._state.hasTouch)
|
||||||
promises.push(session.send('Page.setTouchEmulationEnabled', { enabled: true }));
|
promises.push(session.send('Page.setTouchEmulationEnabled', { enabled: true }));
|
||||||
await Promise.all(promises).catch(e => {
|
await Promise.all(promises).catch(e => {
|
||||||
|
|
@ -285,21 +291,11 @@ export class WKPage implements PageDelegate {
|
||||||
this._page._onFileChooserOpened(handle);
|
this._page._onFileChooserOpened(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _ensureIsolatedWorld(name: string) {
|
private static async _setExtraHTTPHeaders(session: WKSession, headers: network.Headers): Promise<void> {
|
||||||
if (this._isolatedWorlds.has(name))
|
|
||||||
return;
|
|
||||||
this._isolatedWorlds.add(name);
|
|
||||||
await this._session.send('Page.createIsolatedWorld', {
|
|
||||||
name,
|
|
||||||
source: `//# sourceURL=${EVALUATION_SCRIPT_URL}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _setExtraHTTPHeaders(session: WKSession, headers: network.Headers): Promise<void> {
|
|
||||||
await session.send('Network.setExtraHTTPHeaders', { headers });
|
await session.send('Network.setExtraHTTPHeaders', { headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _setEmulateMedia(session: WKSession, mediaType: types.MediaType | null, colorScheme: types.ColorScheme | null): Promise<void> {
|
private static async _setEmulateMedia(session: WKSession, mediaType: types.MediaType | null, colorScheme: types.ColorScheme | null): Promise<void> {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
promises.push(session.send('Page.setEmulatedMedia', { media: mediaType || '' }));
|
promises.push(session.send('Page.setEmulatedMedia', { media: mediaType || '' }));
|
||||||
if (colorScheme !== null) {
|
if (colorScheme !== null) {
|
||||||
|
|
@ -314,11 +310,11 @@ export class WKPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setExtraHTTPHeaders(headers: network.Headers): Promise<void> {
|
async setExtraHTTPHeaders(headers: network.Headers): Promise<void> {
|
||||||
await this._setExtraHTTPHeaders(this._session, headers);
|
await WKPage._setExtraHTTPHeaders(this._session, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setEmulateMedia(mediaType: types.MediaType | null, colorScheme: types.ColorScheme | null): Promise<void> {
|
async setEmulateMedia(mediaType: types.MediaType | null, colorScheme: types.ColorScheme | null): Promise<void> {
|
||||||
await this._setEmulateMedia(this._session, mediaType, colorScheme);
|
await WKPage._setEmulateMedia(this._session, mediaType, colorScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setViewport(viewport: types.Viewport): Promise<void> {
|
async setViewport(viewport: types.Viewport): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
/**
|
||||||
// Licensed under the MIT license.
|
* 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 { BrowserContext } from '../browserContext';
|
import { BrowserContext } from '../browserContext';
|
||||||
|
|
@ -9,17 +22,16 @@ import { WKSession } from './wkConnection';
|
||||||
import { WKPage } from './wkPage';
|
import { WKPage } from './wkPage';
|
||||||
import { RegisteredListener, helper, assert, debugError } from '../helper';
|
import { RegisteredListener, helper, assert, debugError } from '../helper';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
|
import { WKProvisionalPage } from './wkProvisionalPage';
|
||||||
|
|
||||||
// We keep provisional messages on the session instace until provisional
|
const isPovisionalSymbol = Symbol('isPovisional');
|
||||||
// target is committed. Non-provisional target (there should be just one)
|
|
||||||
// has undefined instead.
|
|
||||||
const provisionalMessagesSymbol = Symbol('provisionalMessages');
|
|
||||||
|
|
||||||
export class WKPageProxy {
|
export class WKPageProxy {
|
||||||
private readonly _pageProxySession: WKSession;
|
private readonly _pageProxySession: WKSession;
|
||||||
readonly _browserContext: BrowserContext;
|
readonly _browserContext: BrowserContext;
|
||||||
private _pagePromise: Promise<Page> | null = null;
|
private _pagePromise: Promise<Page> | null = null;
|
||||||
private _wkPage: WKPage | null = null;
|
private _wkPage: WKPage | null = null;
|
||||||
|
private _provisionalPage: WKProvisionalPage | null = null;
|
||||||
private readonly _firstTargetPromise: Promise<void>;
|
private readonly _firstTargetPromise: Promise<void>;
|
||||||
private _firstTargetCallback?: () => void;
|
private _firstTargetCallback?: () => void;
|
||||||
private readonly _sessions = new Map<string, WKSession>();
|
private readonly _sessions = new Map<string, WKSession>();
|
||||||
|
|
@ -56,6 +68,10 @@ export class WKPageProxy {
|
||||||
for (const session of this._sessions.values())
|
for (const session of this._sessions.values())
|
||||||
session.dispose();
|
session.dispose();
|
||||||
this._sessions.clear();
|
this._sessions.clear();
|
||||||
|
if (this._provisionalPage) {
|
||||||
|
this._provisionalPage.dispose();
|
||||||
|
this._provisionalPage = null;
|
||||||
|
}
|
||||||
if (this._wkPage)
|
if (this._wkPage)
|
||||||
this._wkPage.didDisconnect();
|
this._wkPage.didDisconnect();
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +82,7 @@ export class WKPageProxy {
|
||||||
|
|
||||||
private _isProvisionalCrossProcessLoadInProgress() : boolean {
|
private _isProvisionalCrossProcessLoadInProgress() : boolean {
|
||||||
for (const anySession of this._sessions.values()) {
|
for (const anySession of this._sessions.values()) {
|
||||||
if ((anySession as any)[provisionalMessagesSymbol])
|
if ((anySession as any)[isPovisionalSymbol])
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -100,7 +116,7 @@ export class WKPageProxy {
|
||||||
await this._firstTargetPromise;
|
await this._firstTargetPromise;
|
||||||
let session: WKSession | undefined;
|
let session: WKSession | undefined;
|
||||||
for (const anySession of this._sessions.values()) {
|
for (const anySession of this._sessions.values()) {
|
||||||
if (!(anySession as any)[provisionalMessagesSymbol]) {
|
if (!(anySession as any)[isPovisionalSymbol]) {
|
||||||
session = anySession;
|
session = anySession;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -108,10 +124,7 @@ export class WKPageProxy {
|
||||||
assert(session, 'One non-provisional target session must exist');
|
assert(session, 'One non-provisional target session must exist');
|
||||||
this._wkPage = new WKPage(this._browserContext, this._pageProxySession);
|
this._wkPage = new WKPage(this._browserContext, this._pageProxySession);
|
||||||
this._wkPage.setSession(session!);
|
this._wkPage.setSession(session!);
|
||||||
await Promise.all([
|
await this._wkPage.initialize();
|
||||||
this._wkPage._initializePageProxySession(),
|
|
||||||
this._wkPage._initializeSession(session!, false),
|
|
||||||
]);
|
|
||||||
return this._wkPage._page;
|
return this._wkPage._page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,9 +144,11 @@ export class WKPageProxy {
|
||||||
this._firstTargetCallback = undefined;
|
this._firstTargetCallback = undefined;
|
||||||
}
|
}
|
||||||
if (targetInfo.isProvisional)
|
if (targetInfo.isProvisional)
|
||||||
(session as any)[provisionalMessagesSymbol] = [];
|
(session as any)[isPovisionalSymbol] = true;
|
||||||
if (targetInfo.isProvisional && this._wkPage)
|
if (targetInfo.isProvisional && this._wkPage) {
|
||||||
this._wkPage._initializeSession(session, true);
|
assert(!this._provisionalPage);
|
||||||
|
this._provisionalPage = new WKProvisionalPage(session, this._wkPage);
|
||||||
|
}
|
||||||
if (targetInfo.isPaused)
|
if (targetInfo.isPaused)
|
||||||
this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError);
|
this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
@ -144,6 +159,10 @@ export class WKPageProxy {
|
||||||
if (session)
|
if (session)
|
||||||
session.dispose();
|
session.dispose();
|
||||||
this._sessions.delete(targetId);
|
this._sessions.delete(targetId);
|
||||||
|
if (this._provisionalPage && this._provisionalPage._session === session) {
|
||||||
|
this._provisionalPage.dispose();
|
||||||
|
this._provisionalPage = null;
|
||||||
|
}
|
||||||
if (this._wkPage && this._wkPage._session === session && crashed)
|
if (this._wkPage && this._wkPage._session === session && crashed)
|
||||||
this._wkPage.didClose(crashed);
|
this._wkPage.didClose(crashed);
|
||||||
}
|
}
|
||||||
|
|
@ -152,10 +171,6 @@ export class WKPageProxy {
|
||||||
const { targetId, message } = event;
|
const { targetId, message } = event;
|
||||||
const session = this._sessions.get(targetId);
|
const session = this._sessions.get(targetId);
|
||||||
assert(session, 'Unknown target: ' + targetId);
|
assert(session, 'Unknown target: ' + targetId);
|
||||||
const provisionalMessages = (session as any)[provisionalMessagesSymbol];
|
|
||||||
if (provisionalMessages)
|
|
||||||
provisionalMessages.push(message);
|
|
||||||
else
|
|
||||||
session!.dispatchMessage(JSON.parse(message));
|
session!.dispatchMessage(JSON.parse(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +182,13 @@ export class WKPageProxy {
|
||||||
assert(oldSession, 'Unknown old target: ' + oldTargetId);
|
assert(oldSession, 'Unknown old target: ' + oldTargetId);
|
||||||
// TODO: make some calls like screenshot catch swapped out error and retry.
|
// TODO: make some calls like screenshot catch swapped out error and retry.
|
||||||
oldSession!.errorText = 'Target was swapped out.';
|
oldSession!.errorText = 'Target was swapped out.';
|
||||||
const provisionalMessages = (newSession as any)[provisionalMessagesSymbol];
|
(newSession as any)[isPovisionalSymbol] = undefined;
|
||||||
assert(provisionalMessages, 'Committing target must be provisional');
|
if (this._provisionalPage) {
|
||||||
(newSession as any)[provisionalMessagesSymbol] = undefined;
|
this._provisionalPage.commit();
|
||||||
for (const message of provisionalMessages)
|
this._provisionalPage.dispose();
|
||||||
newSession!.dispatchMessage(JSON.parse(message));
|
this._provisionalPage = null;
|
||||||
this._wkPage!.setSession(newSession!);
|
}
|
||||||
|
if (this._wkPage)
|
||||||
|
this._wkPage.setSession(newSession!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
src/webkit/wkProvisionalPage.ts
Normal file
67
src/webkit/wkProvisionalPage.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* 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 { WKSession } from './wkConnection';
|
||||||
|
import { WKPage } from './wkPage';
|
||||||
|
import { RegisteredListener, helper, assert } from '../helper';
|
||||||
|
import { Protocol } from './protocol';
|
||||||
|
|
||||||
|
export class WKProvisionalPage {
|
||||||
|
readonly _session: WKSession;
|
||||||
|
private readonly _wkPage: WKPage;
|
||||||
|
private _sessionListeners: RegisteredListener[] = [];
|
||||||
|
private _mainFrameId: string | null = null;
|
||||||
|
|
||||||
|
constructor(session: WKSession, page: WKPage) {
|
||||||
|
this._session = session;
|
||||||
|
this._wkPage = page;
|
||||||
|
|
||||||
|
const overrideFrameId = (handler: (p: any) => void) => {
|
||||||
|
return (payload: any) => {
|
||||||
|
// Pretend that the events happened in the same process.
|
||||||
|
if (payload.frameId)
|
||||||
|
payload.frameId = this._wkPage._page._frameManager.mainFrame()._id;
|
||||||
|
handler(payload);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const networkManager = this._wkPage._networkManager;
|
||||||
|
|
||||||
|
this._sessionListeners = [
|
||||||
|
helper.addEventListener(session, 'Network.requestWillBeSent', overrideFrameId(e => networkManager._onRequestWillBeSent(session, e))),
|
||||||
|
helper.addEventListener(session, 'Network.requestIntercepted', overrideFrameId(e => networkManager._onRequestIntercepted(e))),
|
||||||
|
helper.addEventListener(session, 'Network.responseReceived', overrideFrameId(e => networkManager._onResponseReceived(e))),
|
||||||
|
helper.addEventListener(session, 'Network.loadingFinished', overrideFrameId(e => networkManager._onLoadingFinished(e))),
|
||||||
|
helper.addEventListener(session, 'Network.loadingFailed', overrideFrameId(e => networkManager._onLoadingFailed(e))),
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
this._wkPage._initializeSession(session, ({frameTree}) => this._handleFrameTree(frameTree));
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
helper.removeEventListeners(this._sessionListeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
commit() {
|
||||||
|
assert(this._mainFrameId);
|
||||||
|
this._wkPage._onFrameAttached(this._mainFrameId!, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree) {
|
||||||
|
assert(!frameTree.frame.parentId);
|
||||||
|
this._mainFrameId = frameTree.frame.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,10 +28,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
it('should intercept', async({page, server}) => {
|
it('should intercept', async({page, server}) => {
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (utils.isFavicon(request)) {
|
|
||||||
request.continue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
expect(request.url()).toContain('empty.html');
|
expect(request.url()).toContain('empty.html');
|
||||||
expect(request.headers()['user-agent']).toBeTruthy();
|
expect(request.headers()['user-agent']).toBeTruthy();
|
||||||
expect(request.method()).toBe('GET');
|
expect(request.method()).toBe('GET');
|
||||||
|
|
@ -94,7 +90,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
|
|
@ -217,7 +212,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
request.continue();
|
request.continue();
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
});
|
});
|
||||||
server.setRedirect('/non-existing-page.html', '/non-existing-page-2.html');
|
server.setRedirect('/non-existing-page.html', '/non-existing-page-2.html');
|
||||||
|
|
@ -245,7 +239,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
request.continue();
|
request.continue();
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
});
|
});
|
||||||
server.setRedirect('/one-style.css', '/two-style.css');
|
server.setRedirect('/one-style.css', '/two-style.css');
|
||||||
|
|
@ -274,10 +267,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
let spinner = false;
|
let spinner = false;
|
||||||
// Cancel 2nd request.
|
// Cancel 2nd request.
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (utils.isFavicon(request)) {
|
|
||||||
request.continue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spinner ? request.abort() : request.continue();
|
spinner ? request.abort() : request.continue();
|
||||||
spinner = !spinner;
|
spinner = !spinner;
|
||||||
});
|
});
|
||||||
|
|
@ -292,7 +281,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
|
|
@ -306,7 +294,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
|
|
@ -319,7 +306,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
|
|
@ -351,7 +337,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
request.continue();
|
request.continue();
|
||||||
if (!utils.isFavicon(request))
|
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
});
|
});
|
||||||
const response = await page.goto(`data:text/html,<link rel="stylesheet" href="${server.PREFIX}/fonts?helvetica|arial"/>`);
|
const response = await page.goto(`data:text/html,<link rel="stylesheet" href="${server.PREFIX}/fonts?helvetica|arial"/>`);
|
||||||
|
|
@ -386,7 +371,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(error.message).toContain('Request Interception is not enabled');
|
expect(error.message).toContain('Request Interception is not enabled');
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should intercept main resource during cross-process navigation', async({page, server}) => {
|
it('should intercept main resource during cross-process navigation', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
let intercepted = false;
|
let intercepted = false;
|
||||||
|
|
@ -414,7 +399,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
const notAnError = await request.continue().then(() => null).catch(e => e);
|
const notAnError = await request.continue().then(() => null).catch(e => e);
|
||||||
expect(notAnError).toBe(null);
|
expect(notAnError).toBe(null);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should not throw when continued after cross-process navigation', async({page, server}) => {
|
it('should not throw when continued after cross-process navigation', async({page, server}) => {
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
page.on('request', request => {
|
page.on('request', request => {
|
||||||
if (request.url() !== server.PREFIX + '/one-style.css')
|
if (request.url() !== server.PREFIX + '/one-style.css')
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||||
const response = await page.goto(server.EMPTY_PAGE, {waitUntil: 'domcontentloaded'});
|
const response = await page.goto(server.EMPTY_PAGE, {waitUntil: 'domcontentloaded'});
|
||||||
expect(response.status()).toBe(200);
|
expect(response.status()).toBe(200);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work when page calls history API in beforeunload', async({page, server}) => {
|
it('should work when page calls history API in beforeunload', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false);
|
window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false);
|
||||||
|
|
@ -280,7 +280,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||||
});
|
});
|
||||||
it('should navigate to dataURL and not fire dataURL requests', async({page, server}) => {
|
it('should navigate to dataURL and not fire dataURL requests', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
const dataURL = 'data:text/html,<div>yo</div>';
|
const dataURL = 'data:text/html,<div>yo</div>';
|
||||||
const response = await page.goto(dataURL);
|
const response = await page.goto(dataURL);
|
||||||
expect(response).toBe(null);
|
expect(response).toBe(null);
|
||||||
|
|
@ -288,7 +288,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||||
});
|
});
|
||||||
it('should navigate to URL with hash and fire requests without hash', async({page, server}) => {
|
it('should navigate to URL with hash and fire requests without hash', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
const response = await page.goto(server.EMPTY_PAGE + '#hash');
|
const response = await page.goto(server.EMPTY_PAGE + '#hash');
|
||||||
expect(response.status()).toBe(200);
|
expect(response.status()).toBe(200);
|
||||||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||||
|
|
|
||||||
|
|
@ -27,20 +27,20 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
describe('Page.Events.Request', function() {
|
describe('Page.Events.Request', function() {
|
||||||
it('should fire for navigation requests', async({page, server}) => {
|
it('should fire for navigation requests', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
});
|
});
|
||||||
it('should fire for iframes', async({page, server}) => {
|
it('should fire for iframes', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(2);
|
expect(requests.length).toBe(2);
|
||||||
});
|
});
|
||||||
it('should fire for fetches', async({page, server}) => {
|
it('should fire for fetches', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.evaluate(() => fetch('/empty.html'));
|
await page.evaluate(() => fetch('/empty.html'));
|
||||||
expect(requests.length).toBe(2);
|
expect(requests.length).toBe(2);
|
||||||
|
|
@ -50,7 +50,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
describe('Request.frame', function() {
|
describe('Request.frame', function() {
|
||||||
it('should work for main frame navigation request', async({page, server}) => {
|
it('should work for main frame navigation request', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
expect(requests[0].frame()).toBe(page.mainFrame());
|
expect(requests[0].frame()).toBe(page.mainFrame());
|
||||||
|
|
@ -58,7 +58,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
it('should work for subframe navigation request', async({page, server}) => {
|
it('should work for subframe navigation request', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
expect(requests[0].frame()).toBe(page.frames()[1]);
|
expect(requests[0].frame()).toBe(page.frames()[1]);
|
||||||
|
|
@ -66,7 +66,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
it('should work for fetch requests', async({page, server}) => {
|
it('should work for fetch requests', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
let requests = [];
|
let requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.evaluate(() => fetch('/digits/1.png'));
|
await page.evaluate(() => fetch('/digits/1.png'));
|
||||||
requests = requests.filter(request => !request.url().includes('favicon'));
|
requests = requests.filter(request => !request.url().includes('favicon'));
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
|
|
@ -151,7 +151,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
page.on('requestfinished', r => requestFinished = requestFinished || r.url().includes('/get'));
|
page.on('requestfinished', r => requestFinished = requestFinished || r.url().includes('/get'));
|
||||||
// send request and wait for server response
|
// send request and wait for server response
|
||||||
const [pageResponse] = await Promise.all([
|
const [pageResponse] = await Promise.all([
|
||||||
page.waitForEvent('response', { predicate: r => !utils.isFavicon(r.request()) }),
|
page.waitForEvent('response'),
|
||||||
page.evaluate(() => fetch('./get', { method: 'GET'})),
|
page.evaluate(() => fetch('./get', { method: 'GET'})),
|
||||||
server.waitForRequest('/get'),
|
server.waitForRequest('/get'),
|
||||||
]);
|
]);
|
||||||
|
|
@ -207,7 +207,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
describe('Network Events', function() {
|
describe('Network Events', function() {
|
||||||
it('Page.Events.Request', async({page, server}) => {
|
it('Page.Events.Request', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('request', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
||||||
|
|
@ -220,7 +220,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
// FIXME: WebKit doesn't provide remoteIPAddress in the response.
|
// FIXME: WebKit doesn't provide remoteIPAddress in the response.
|
||||||
it.skip(WEBKIT)('Page.Events.Response', async({page, server}) => {
|
it.skip(WEBKIT)('Page.Events.Response', async({page, server}) => {
|
||||||
const responses = [];
|
const responses = [];
|
||||||
page.on('response', response => !utils.isFavicon(response.request()) && responses.push(response));
|
page.on('response', response => responses.push(response));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(responses.length).toBe(1);
|
expect(responses.length).toBe(1);
|
||||||
expect(responses[0].url()).toBe(server.EMPTY_PAGE);
|
expect(responses[0].url()).toBe(server.EMPTY_PAGE);
|
||||||
|
|
@ -261,7 +261,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
});
|
});
|
||||||
it('Page.Events.RequestFinished', async({page, server}) => {
|
it('Page.Events.RequestFinished', async({page, server}) => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
page.on('requestfinished', request => !utils.isFavicon(request) && requests.push(request));
|
page.on('requestfinished', request => requests.push(request));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(requests.length).toBe(1);
|
expect(requests.length).toBe(1);
|
||||||
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
||||||
|
|
@ -271,18 +271,18 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
});
|
});
|
||||||
it('should fire events in proper order', async({page, server}) => {
|
it('should fire events in proper order', async({page, server}) => {
|
||||||
const events = [];
|
const events = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && events.push('request'));
|
page.on('request', request => events.push('request'));
|
||||||
page.on('response', response => !utils.isFavicon(response.request()) && events.push('response'));
|
page.on('response', response => events.push('response'));
|
||||||
page.on('requestfinished', request => !utils.isFavicon(request) && events.push('requestfinished'));
|
page.on('requestfinished', request => events.push('requestfinished'));
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(events).toEqual(['request', 'response', 'requestfinished']);
|
expect(events).toEqual(['request', 'response', 'requestfinished']);
|
||||||
});
|
});
|
||||||
it('should support redirects', async({page, server}) => {
|
it('should support redirects', async({page, server}) => {
|
||||||
const events = [];
|
const events = [];
|
||||||
page.on('request', request => !utils.isFavicon(request) && events.push(`${request.method()} ${request.url()}`));
|
page.on('request', request => events.push(`${request.method()} ${request.url()}`));
|
||||||
page.on('response', response => !utils.isFavicon(response.request()) && events.push(`${response.status()} ${response.url()}`));
|
page.on('response', response => events.push(`${response.status()} ${response.url()}`));
|
||||||
page.on('requestfinished', request => !utils.isFavicon(request) && events.push(`DONE ${request.url()}`));
|
page.on('requestfinished', request => events.push(`DONE ${request.url()}`));
|
||||||
page.on('requestfailed', request => !utils.isFavicon(request) && events.push(`FAIL ${request.url()}`));
|
page.on('requestfailed', request => events.push(`FAIL ${request.url()}`));
|
||||||
server.setRedirect('/foo.html', '/empty.html');
|
server.setRedirect('/foo.html', '/empty.html');
|
||||||
const FOO_URL = server.PREFIX + '/foo.html';
|
const FOO_URL = server.PREFIX + '/foo.html';
|
||||||
const response = await page.goto(FOO_URL);
|
const response = await page.goto(FOO_URL);
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF
|
||||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||||
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT || FFOX)('should not treat navigations as new popups', async({page, server}) => {
|
it.skip(FFOX)('should not treat navigations as new popups', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.setContent('<a target=_blank rel=noopener href="/one-style.html">yo</a>');
|
await page.setContent('<a target=_blank rel=noopener href="/one-style.html">yo</a>');
|
||||||
const [popup] = await Promise.all([
|
const [popup] = await Promise.all([
|
||||||
|
|
|
||||||
|
|
@ -122,19 +122,11 @@ const utils = module.exports = {
|
||||||
frame.src = url;
|
frame.src = url;
|
||||||
frame.id = frameId;
|
frame.id = frameId;
|
||||||
document.body.appendChild(frame);
|
document.body.appendChild(frame);
|
||||||
// TODO(einbinder) do this right
|
|
||||||
// Access a scriptable global object to ensure JS context is
|
|
||||||
// initialized. WebKit will create it lazily only as need be.
|
|
||||||
frame.contentWindow;
|
|
||||||
await new Promise(x => frame.onload = x);
|
await new Promise(x => frame.onload = x);
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isFavicon: function(request) {
|
|
||||||
return request.url().includes('favicon.ico');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!Page} page
|
* @param {!Page} page
|
||||||
* @param {string} frameId
|
* @param {string} frameId
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
/**
|
||||||
// Licensed under the MIT license.
|
* 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 fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue