2022-10-25 03:23:11 +03:00
|
|
|
/**
|
|
|
|
* Copyright 2020 Microsoft Corporation. All rights reserved.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import ws from 'ws';
|
|
|
|
import { androidTest as test, expect } from './androidTest';
|
2023-10-13 00:58:19 +03:00
|
|
|
import { kTargetClosedErrorMessage } from '../config/errors';
|
2022-10-25 03:23:11 +03:00
|
|
|
|
2022-11-08 02:35:21 +03:00
|
|
|
// Force a separate worker to avoid messing up with `androidDevice` fixture.
|
|
|
|
test.use({ launchOptions: {} });
|
|
|
|
|
2022-10-25 03:23:11 +03:00
|
|
|
test('android.launchServer should connect to a device', async ({ playwright }) => {
|
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
const output = await device.shell('echo 123');
|
|
|
|
expect(output.toString()).toBe('123\n');
|
|
|
|
await device.close();
|
|
|
|
await browserServer.close();
|
|
|
|
});
|
|
|
|
|
2022-10-26 04:18:14 +03:00
|
|
|
test('android.launchServer should handle close event correctly', async ({ playwright }) => {
|
2023-10-23 19:31:30 +03:00
|
|
|
const receivedEvents: string[] = [];
|
2022-10-26 04:18:14 +03:00
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
device.on('close', () => receivedEvents.push('device'));
|
|
|
|
browserServer.on('close', () => receivedEvents.push('browserServer'));
|
|
|
|
{
|
|
|
|
const waitForDeviceClose = new Promise(f => device.on('close', f));
|
|
|
|
await device.close();
|
|
|
|
await waitForDeviceClose;
|
|
|
|
}
|
|
|
|
expect(receivedEvents).toEqual(['device']);
|
|
|
|
await device.close();
|
|
|
|
expect(receivedEvents).toEqual(['device']);
|
|
|
|
await browserServer.close();
|
|
|
|
expect(receivedEvents).toEqual(['device', 'browserServer']);
|
|
|
|
await browserServer.close();
|
|
|
|
expect(receivedEvents).toEqual(['device', 'browserServer']);
|
|
|
|
await device.close();
|
|
|
|
expect(receivedEvents).toEqual(['device', 'browserServer']);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer should be able to reconnect to a device', async ({ playwright }) => {
|
2022-10-25 03:23:11 +03:00
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
try {
|
|
|
|
{
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
await device.push(Buffer.from('hello world'), '/data/local/tmp/hello-world');
|
|
|
|
await device.close();
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
const data = await device.shell('cat /data/local/tmp/hello-world');
|
|
|
|
expect(data).toEqual(Buffer.from('hello world'));
|
|
|
|
await device.close();
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
// Cleanup
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
await device.shell('rm /data/local/tmp/hello-world');
|
|
|
|
await device.close();
|
|
|
|
await browserServer.close();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer should throw if there is no device with a specified serial number', async ({ playwright }) => {
|
|
|
|
await expect(playwright._android.launchServer({
|
|
|
|
deviceSerialNumber: 'does-not-exist',
|
|
|
|
})).rejects.toThrow(`No device with serial number 'does-not-exist'`);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer should not allow multiple connections', async ({ playwright }) => {
|
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
try {
|
|
|
|
await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
await expect(playwright._android.connect(browserServer.wsEndpoint(), { timeout: 2_000 })).rejects.toThrow('android.connect: Timeout 2000ms exceeded');
|
|
|
|
} finally {
|
|
|
|
await browserServer.close();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer BrowserServer.close() will disconnect the device', async ({ playwright }) => {
|
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
try {
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
await browserServer.close();
|
2023-10-13 00:58:19 +03:00
|
|
|
await expect(device.shell('echo 123')).rejects.toThrow('androidDevice.shell: ' + kTargetClosedErrorMessage);
|
2022-10-25 03:23:11 +03:00
|
|
|
} finally {
|
|
|
|
await browserServer.close();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer BrowserServer.kill() will disconnect the device', async ({ playwright }) => {
|
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
try {
|
|
|
|
const device = await playwright._android.connect(browserServer.wsEndpoint());
|
|
|
|
await browserServer.kill();
|
2023-10-13 00:58:19 +03:00
|
|
|
await expect(device.shell('echo 123')).rejects.toThrow('androidDevice.shell: ' + kTargetClosedErrorMessage);
|
2022-10-25 03:23:11 +03:00
|
|
|
} finally {
|
|
|
|
await browserServer.close();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('android.launchServer should terminate WS connection when device gets disconnected', async ({ playwright }) => {
|
|
|
|
const browserServer = await playwright._android.launchServer();
|
|
|
|
const forwardingServer = new ws.Server({ port: 0, path: '/connect' });
|
2023-10-23 19:31:30 +03:00
|
|
|
let receivedConnection: ws.WebSocket | undefined;
|
2022-10-25 03:23:11 +03:00
|
|
|
forwardingServer.on('connection', connection => {
|
|
|
|
receivedConnection = connection;
|
|
|
|
const actualConnection = new ws.WebSocket(browserServer.wsEndpoint());
|
2022-10-26 04:18:14 +03:00
|
|
|
actualConnection.on('open', () => {
|
|
|
|
actualConnection.on('message', message => connection.send(message));
|
|
|
|
connection.on('message', message => actualConnection.send(message));
|
|
|
|
connection.on('close', () => actualConnection.close());
|
|
|
|
actualConnection.on('close', () => connection.close());
|
|
|
|
});
|
2022-10-25 03:23:11 +03:00
|
|
|
});
|
|
|
|
try {
|
|
|
|
const device = await playwright._android.connect(`ws://localhost:${(forwardingServer.address() as ws.AddressInfo).port}/connect`);
|
|
|
|
expect((await device.shell('echo 123')).toString()).toBe('123\n');
|
2023-10-23 19:31:30 +03:00
|
|
|
expect(receivedConnection!.readyState).toBe(ws.OPEN);
|
|
|
|
const waitToClose = new Promise(f => receivedConnection!.on('close', f));
|
2022-10-25 03:23:11 +03:00
|
|
|
await device.close();
|
|
|
|
await waitToClose;
|
2023-10-23 19:31:30 +03:00
|
|
|
expect(receivedConnection!.readyState).toBe(ws.CLOSED);
|
2022-10-25 03:23:11 +03:00
|
|
|
} finally {
|
|
|
|
await browserServer.close();
|
|
|
|
await new Promise(f => forwardingServer.close(f));
|
|
|
|
}
|
|
|
|
});
|