mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-24 06:49:04 +03:00
feat(scopes): make page a scope (#4385)
This commit is contained in:
parent
58b5872ecb
commit
2158d6d073
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ lib/
|
||||
jest-report.json
|
||||
drivers/
|
||||
/docs/api.json
|
||||
.android-sdk/
|
||||
|
@ -18,7 +18,7 @@ import * as debug from 'debug';
|
||||
import { EventEmitter } from 'events';
|
||||
import * as stream from 'stream';
|
||||
import * as ws from 'ws';
|
||||
import { makeWaitForNextTask } from '../../utils/utils';
|
||||
import { createGuid, makeWaitForNextTask } from '../../utils/utils';
|
||||
|
||||
export interface Backend {
|
||||
devices(): Promise<DeviceBackend[]>;
|
||||
@ -69,20 +69,13 @@ export class AndroidDevice {
|
||||
async launchBrowser(packageName: string): Promise<AndroidBrowser> {
|
||||
debug('pw:android')('Force-stopping', packageName);
|
||||
await this.backend.runCommand(`shell:am force-stop ${packageName}`);
|
||||
const hasDefaultSocket = !!(await this.backend.runCommand(`shell:cat /proc/net/unix | grep chrome_devtools_remote$`));
|
||||
debug('pw:android')('Starting', packageName);
|
||||
|
||||
const socketName = createGuid();
|
||||
const commandLine = `_ --disable-fre --no-default-browser-check --no-first-run --remote-debugging-socket-name=${socketName}`;
|
||||
debug('pw:android')('Starting', packageName, commandLine);
|
||||
await this.backend.runCommand(`shell:echo "${commandLine}" > /data/local/tmp/chrome-command-line`);
|
||||
await this.backend.runCommand(`shell:am start -n ${packageName}/com.google.android.apps.chrome.Main about:blank`);
|
||||
let pid = 0;
|
||||
debug('pw:android')('Polling pid for', packageName);
|
||||
while (!pid) {
|
||||
const ps = (await this.backend.runCommand(`shell:ps -A | grep ${packageName}`)).split('\n');
|
||||
const proc = ps.find(line => line.endsWith(packageName));
|
||||
if (proc)
|
||||
pid = +proc.replace(/\s+/g, ' ').split(' ')[1];
|
||||
await new Promise(f => setTimeout(f, 100));
|
||||
}
|
||||
debug('pw:android')('PID=' + pid);
|
||||
const socketName = hasDefaultSocket ? `chrome_devtools_remote_${pid}` : 'chrome_devtools_remote';
|
||||
|
||||
debug('pw:android')('Polling for socket', socketName);
|
||||
while (true) {
|
||||
const net = await this.backend.runCommand(`shell:cat /proc/net/unix | grep ${socketName}$`);
|
||||
@ -91,7 +84,7 @@ export class AndroidDevice {
|
||||
await new Promise(f => setTimeout(f, 100));
|
||||
}
|
||||
debug('pw:android')('Got the socket, connecting');
|
||||
const browser = new AndroidBrowser(this, packageName, socketName, pid);
|
||||
const browser = new AndroidBrowser(this, packageName, socketName);
|
||||
await browser._open();
|
||||
return browser;
|
||||
}
|
||||
@ -104,7 +97,6 @@ export class AndroidDevice {
|
||||
export class AndroidBrowser extends EventEmitter {
|
||||
readonly device: AndroidDevice;
|
||||
readonly socketName: string;
|
||||
readonly pid: number;
|
||||
private _socket: SocketBackend | undefined;
|
||||
private _receiver: stream.Writable;
|
||||
private _waitForNextTask = makeWaitForNextTask();
|
||||
@ -112,12 +104,11 @@ export class AndroidBrowser extends EventEmitter {
|
||||
onclose?: () => void;
|
||||
private _packageName: string;
|
||||
|
||||
constructor(device: AndroidDevice, packageName: string, socketName: string, pid: number) {
|
||||
constructor(device: AndroidDevice, packageName: string, socketName: string) {
|
||||
super();
|
||||
this._packageName = packageName;
|
||||
this.device = device;
|
||||
this.socketName = socketName;
|
||||
this.pid = pid;
|
||||
this._receiver = new (ws as any).Receiver() as stream.Writable;
|
||||
this._receiver.on('message', message => {
|
||||
this._waitForNextTask(() => {
|
||||
|
27
utils/avd_install.sh
Executable file
27
utils/avd_install.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
SDKDIR=$PWD/.android-sdk
|
||||
export ANDROID_SDK_ROOT=${SDKDIR}
|
||||
export ANDROID_HOME=${SDKDIR}
|
||||
export ANDROID_AVD_HOME=${SDKDIR}/avd
|
||||
|
||||
mkdir ${SDKDIR}
|
||||
mkdir ${SDKDIR}/cmdline-tools
|
||||
|
||||
echo Downloading Android SDK...
|
||||
cd ${SDKDIR}/cmdline-tools
|
||||
curl https://dl.google.com/android/repository/commandlinetools-mac-6858069_latest.zip -o commandlinetools-mac-6858069_latest.zip
|
||||
unzip commandlinetools-mac-6858069_latest.zip
|
||||
mv cmdline-tools latest
|
||||
|
||||
echo Installing emulator...
|
||||
yes | ${SDKDIR}/cmdline-tools/latest/bin/sdkmanager platform-tools emulator
|
||||
|
||||
echo Installing system image...
|
||||
${SDKDIR}/cmdline-tools/latest/bin/sdkmanager "system-images;android-30;google_apis;x86"
|
||||
|
||||
echo Installing platform SDK...
|
||||
${SDKDIR}/cmdline-tools/latest/bin/sdkmanager "platforms;android-30"
|
||||
|
||||
echo Starting ADB...
|
||||
${SDKDIR}/platform-tools/adb devices
|
9
utils/avd_recreate.sh
Executable file
9
utils/avd_recreate.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
SDKDIR=$PWD/.android-sdk
|
||||
export ANDROID_SDK_ROOT=${SDKDIR}
|
||||
export ANDROID_HOME=${SDKDIR}
|
||||
export ANDROID_AVD_HOME=${SDKDIR}/avd
|
||||
|
||||
${SDKDIR}/cmdline-tools/latest/bin/avdmanager delete avd --name android30
|
||||
echo -ne '\n' | ${SDKDIR}/cmdline-tools/latest/bin/avdmanager create avd --name android30 --device pixel_4_xl --package "system-images;android-30;google_apis;x86"
|
8
utils/avd_start.sh
Executable file
8
utils/avd_start.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
SDKDIR=$PWD/.android-sdk
|
||||
export ANDROID_SDK_ROOT=${SDKDIR}
|
||||
export ANDROID_HOME=${SDKDIR}
|
||||
export ANDROID_AVD_HOME=${SDKDIR}/avd
|
||||
|
||||
${SDKDIR}/emulator/emulator -avd android30
|
63
utils/avd_test.js
Normal file
63
utils/avd_test.js
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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 { _clank } = require('..');
|
||||
const assert = require('assert');
|
||||
const childProcess = require('child_process');
|
||||
const path = require('path');
|
||||
const readline = require('readline');
|
||||
|
||||
(async () => {
|
||||
setTimeout(() => {
|
||||
console.error('Timed out starting emulator');
|
||||
process.exit(1);
|
||||
}, 60000);
|
||||
const proc = childProcess.spawn(path.join(process.cwd(), '.android-sdk/emulator/emulator'), ['-no-window', '-avd', 'android30', '-verbose'], {
|
||||
env: {
|
||||
...process.env,
|
||||
ANDROID_SDK_ROOT: path.join(process.cwd(), '.android-sdk'),
|
||||
ANDROID_HOME: path.join(process.cwd(), '.android-sdk'),
|
||||
}
|
||||
});
|
||||
proc.stdout.on('data', data => console.log(data.toString()));
|
||||
proc.stderr.on('data', data => console.log(data.toString()));
|
||||
await waitForLine(proc, /boot completed/);
|
||||
|
||||
const context = await _clank.launchPersistentContext('');
|
||||
const [page] = context.pages();
|
||||
await page.goto('data:text/html,<title>Hello world</title>');
|
||||
assert(await page.title() === 'Hello world');
|
||||
await context.close();
|
||||
process.exit(0);
|
||||
})();
|
||||
|
||||
async function waitForLine(proc, regex) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({ input: proc.stdout });
|
||||
const failError = new Error('Process failed to launch!');
|
||||
rl.on('line', onLine);
|
||||
rl.on('close', reject.bind(null, failError));
|
||||
proc.on('exit', reject.bind(null, failError));
|
||||
proc.on('error', reject.bind(null, failError));
|
||||
|
||||
function onLine(line) {
|
||||
const match = line.match(regex);
|
||||
if (!match)
|
||||
return;
|
||||
resolve(match);
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user