test(adb): fix browser tests (#4700)
This commit is contained in:
parent
f89dcc7ba7
commit
1596b53da2
3
.github/workflows/tests.yml
vendored
3
.github/workflows/tests.yml
vendored
|
|
@ -232,7 +232,7 @@ jobs:
|
||||||
name: video-${{ matrix.browser }}-linux-test-results
|
name: video-${{ matrix.browser }}-linux-test-results
|
||||||
path: test-results
|
path: test-results
|
||||||
test_android:
|
test_android:
|
||||||
name: Android on macOS
|
name: Android Emulator
|
||||||
runs-on: macos-10.15
|
runs-on: macos-10.15
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
@ -250,6 +250,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
FOLIO_JSON_OUTPUT_NAME: "test-results/report.json"
|
FOLIO_JSON_OUTPUT_NAME: "test-results/report.json"
|
||||||
PW_ANDROID_TESTS: 1
|
PW_ANDROID_TESTS: 1
|
||||||
|
DEBUG: pw:api
|
||||||
- run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json
|
- run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json
|
||||||
if: always() && github.ref == 'refs/heads/master'
|
if: always() && github.ref == 'refs/heads/master'
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ export class AndroidDevice extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async open(command: string): Promise<SocketBackend> {
|
async open(command: string): Promise<SocketBackend> {
|
||||||
return await this._backend.open(`shell:${command}`);
|
return await this._backend.open(`${command}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _driver(): Promise<Transport> {
|
private async _driver(): Promise<Transport> {
|
||||||
|
|
@ -167,18 +167,7 @@ export class AndroidDevice extends EventEmitter {
|
||||||
|
|
||||||
debug('pw:android')('Starting the new driver');
|
debug('pw:android')('Starting the new driver');
|
||||||
this.shell(`am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner`);
|
this.shell(`am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner`);
|
||||||
|
const socket = await this._waitForLocalAbstract('playwright_android_driver_socket');
|
||||||
debug('pw:android')('Polling the socket');
|
|
||||||
let socket;
|
|
||||||
while (!socket) {
|
|
||||||
try {
|
|
||||||
socket = await this._backend.open(`localabstract:playwright_android_driver_socket`);
|
|
||||||
} catch (e) {
|
|
||||||
await new Promise(f => setTimeout(f, 100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug('pw:android')('Connected to driver');
|
|
||||||
const transport = new Transport(socket, socket, socket, 'be');
|
const transport = new Transport(socket, socket, socket, 'be');
|
||||||
transport.onmessage = message => {
|
transport.onmessage = message => {
|
||||||
const response = JSON.parse(message);
|
const response = JSON.parse(message);
|
||||||
|
|
@ -197,6 +186,20 @@ export class AndroidDevice extends EventEmitter {
|
||||||
return this._driverPromise;
|
return this._driverPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _waitForLocalAbstract(socketName: string): Promise<SocketBackend> {
|
||||||
|
let socket: SocketBackend | undefined;
|
||||||
|
debug('pw:android')(`Polling the socket localabstract:${socketName}`);
|
||||||
|
while (!socket) {
|
||||||
|
try {
|
||||||
|
socket = await this._backend.open(`localabstract:${socketName}`);
|
||||||
|
} catch (e) {
|
||||||
|
await new Promise(f => setTimeout(f, 250));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug('pw:android')(`Connected to localabstract:${socketName}`);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
async send(method: string, params: any): Promise<any> {
|
async send(method: string, params: any): Promise<any> {
|
||||||
const driver = await this._driver();
|
const driver = await this._driver();
|
||||||
const id = ++this._lastId;
|
const id = ++this._lastId;
|
||||||
|
|
@ -224,20 +227,11 @@ export class AndroidDevice extends EventEmitter {
|
||||||
debug('pw:android')('Force-stopping', pkg);
|
debug('pw:android')('Force-stopping', pkg);
|
||||||
await this._backend.runCommand(`shell:am force-stop ${pkg}`);
|
await this._backend.runCommand(`shell:am force-stop ${pkg}`);
|
||||||
|
|
||||||
const socketName = createGuid();
|
const socketName = 'playwright-' + createGuid();
|
||||||
const commandLine = `_ --disable-fre --no-default-browser-check --no-first-run --remote-debugging-socket-name=${socketName}`;
|
const commandLine = `_ --disable-fre --no-default-browser-check --no-first-run --remote-debugging-socket-name=${socketName}`;
|
||||||
debug('pw:android')('Starting', pkg, commandLine);
|
debug('pw:android')('Starting', pkg, commandLine);
|
||||||
await this._backend.runCommand(`shell:echo "${commandLine}" > /data/local/tmp/chrome-command-line`);
|
await this._backend.runCommand(`shell:echo "${commandLine}" > /data/local/tmp/chrome-command-line`);
|
||||||
await this._backend.runCommand(`shell:am start -n ${pkg}/com.google.android.apps.chrome.Main about:blank`);
|
await this._backend.runCommand(`shell:am start -n ${pkg}/com.google.android.apps.chrome.Main about:blank`);
|
||||||
|
|
||||||
debug('pw:android')('Polling for socket', socketName);
|
|
||||||
while (true) {
|
|
||||||
const net = await this._backend.runCommand(`shell:cat /proc/net/unix | grep ${socketName}$`);
|
|
||||||
if (net)
|
|
||||||
break;
|
|
||||||
await new Promise(f => setTimeout(f, 100));
|
|
||||||
}
|
|
||||||
debug('pw:android')('Got the socket, connecting');
|
|
||||||
return await this._connectToBrowser(socketName, options);
|
return await this._connectToBrowser(socketName, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,8 +243,9 @@ export class AndroidDevice extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _connectToBrowser(socketName: string, options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
private async _connectToBrowser(socketName: string, options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||||
const androidBrowser = new AndroidBrowser(this, socketName);
|
const socket = await this._waitForLocalAbstract(socketName);
|
||||||
await androidBrowser._open();
|
const androidBrowser = new AndroidBrowser(this, socket);
|
||||||
|
await androidBrowser._init();
|
||||||
this._browserConnections.add(androidBrowser);
|
this._browserConnections.add(androidBrowser);
|
||||||
|
|
||||||
const browserOptions: BrowserOptions = {
|
const browserOptions: BrowserOptions = {
|
||||||
|
|
@ -357,17 +352,22 @@ export class AndroidDevice extends EventEmitter {
|
||||||
|
|
||||||
class AndroidBrowser extends EventEmitter {
|
class AndroidBrowser extends EventEmitter {
|
||||||
readonly device: AndroidDevice;
|
readonly device: AndroidDevice;
|
||||||
readonly socketName: string;
|
private _socket: SocketBackend;
|
||||||
private _socket: SocketBackend | undefined;
|
|
||||||
private _receiver: stream.Writable;
|
private _receiver: stream.Writable;
|
||||||
private _waitForNextTask = makeWaitForNextTask();
|
private _waitForNextTask = makeWaitForNextTask();
|
||||||
onmessage?: (message: any) => void;
|
onmessage?: (message: any) => void;
|
||||||
onclose?: () => void;
|
onclose?: () => void;
|
||||||
|
|
||||||
constructor(device: AndroidDevice, socketName: string) {
|
constructor(device: AndroidDevice, socket: SocketBackend) {
|
||||||
super();
|
super();
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.socketName = socketName;
|
this._socket = socket;
|
||||||
|
this._socket.on('close', () => {
|
||||||
|
this._waitForNextTask(() => {
|
||||||
|
if (this.onclose)
|
||||||
|
this.onclose();
|
||||||
|
});
|
||||||
|
});
|
||||||
this._receiver = new (ws as any).Receiver() as stream.Writable;
|
this._receiver = new (ws as any).Receiver() as stream.Writable;
|
||||||
this._receiver.on('message', message => {
|
this._receiver.on('message', message => {
|
||||||
this._waitForNextTask(() => {
|
this._waitForNextTask(() => {
|
||||||
|
|
@ -377,14 +377,7 @@ class AndroidBrowser extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _open() {
|
async _init() {
|
||||||
this._socket = await this.device._backend.open(`localabstract:${this.socketName}`);
|
|
||||||
this._socket.on('close', () => {
|
|
||||||
this._waitForNextTask(() => {
|
|
||||||
if (this.onclose)
|
|
||||||
this.onclose();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
await this._socket.write(Buffer.from(`GET /devtools/browser HTTP/1.1\r
|
await this._socket.write(Buffer.from(`GET /devtools/browser HTTP/1.1\r
|
||||||
Upgrade: WebSocket\r
|
Upgrade: WebSocket\r
|
||||||
Connection: Upgrade\r
|
Connection: Upgrade\r
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ if (process.env.PW_ANDROID_TESTS) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open a ADB socket', async function({ device }) {
|
it('should open a ADB socket', async function({ device }) {
|
||||||
const socket = await device.open('/bin/cat');
|
const socket = await device.open('shell:/bin/cat');
|
||||||
await socket.write(Buffer.from('321\n'));
|
await socket.write(Buffer.from('321\n'));
|
||||||
const output = await new Promise(resolve => socket.on('data', resolve));
|
const output = await new Promise(resolve => socket.on('data', resolve));
|
||||||
expect(output.toString()).toBe('321\n');
|
expect(output.toString()).toBe('321\n');
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,5 @@ fi
|
||||||
|
|
||||||
${ANDROID_HOME}/tools/bin/avdmanager delete avd --name android30 || true
|
${ANDROID_HOME}/tools/bin/avdmanager delete avd --name android30 || true
|
||||||
echo "y" | ${ANDROID_HOME}/tools/bin/sdkmanager --install "system-images;android-30;google_apis;x86"
|
echo "y" | ${ANDROID_HOME}/tools/bin/sdkmanager --install "system-images;android-30;google_apis;x86"
|
||||||
echo "no" | ${ANDROID_HOME}/tools/bin/avdmanager create avd --force --name android30 --device "Nexus 5X" -k 'system-images;android-30;google_apis;x86'
|
echo "no" | ${ANDROID_HOME}/tools/bin/avdmanager create avd --force --name android30 --device pixel_4 --package "system-images;android-30;google_apis;x86"
|
||||||
${ANDROID_HOME}/emulator/emulator -list-avds
|
${ANDROID_HOME}/emulator/emulator -list-avds
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ if [[ -z "${ANDROID_HOME}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Killing previous emulators"
|
echo "Killing previous emulators"
|
||||||
adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done
|
${ANDROID_HOME}/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done
|
||||||
|
|
||||||
echo "Starting emulator"
|
echo "Starting emulator"
|
||||||
nohup ${ANDROID_HOME}/emulator/emulator -avd android30 -no-audio -no-snapshot -no-window -gpu swiftshader_indirect &
|
nohup ${ANDROID_HOME}/emulator/emulator -avd android30 -no-audio -no-snapshot -no-window -gpu swiftshader_indirect &
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue