Skip to content

Commit 6cc695d

Browse files
authored
test(adb): fix the adb tests (microsoft#4691)
1 parent 2ba60e9 commit 6cc695d

File tree

4 files changed

+29
-6
lines changed

4 files changed

+29
-6
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"roll-browser": "node utils/roll_browser.js",
3232
"coverage": "node test/checkCoverage.js",
3333
"check-deps": "node utils/check_deps.js",
34-
"build-android-driver": "./utils/build_android_driver.sh"
34+
"build-android-driver": "./utils/build_android_driver.sh",
35+
"test-android-driver": "PW_ANDROID_TESTS=1 npx folio test/android -p browserName=chromium --workers=1"
3536
},
3637
"author": {
3738
"name": "Microsoft Corporation"

src/dispatchers/androidDispatcher.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { Dispatcher, DispatcherScope } from './dispatcher';
17+
import { Dispatcher, DispatcherScope, existingDispatcher } from './dispatcher';
1818
import { Android, AndroidDevice } from '../server/android/android';
1919
import * as channels from '../protocol/channels';
2020
import { BrowserContextDispatcher } from './browserContextDispatcher';
@@ -27,7 +27,7 @@ export class AndroidDispatcher extends Dispatcher<Android, channels.AndroidIniti
2727
async devices(params: channels.AndroidDevicesParams): Promise<channels.AndroidDevicesResult> {
2828
const devices = await this._object.devices();
2929
return {
30-
devices: devices.map(d => new AndroidDeviceDispatcher(this._scope, d))
30+
devices: devices.map(d => AndroidDeviceDispatcher.from(this._scope, d))
3131
};
3232
}
3333

@@ -37,6 +37,12 @@ export class AndroidDispatcher extends Dispatcher<Android, channels.AndroidIniti
3737
}
3838

3939
export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.AndroidDeviceInitializer> implements channels.AndroidDeviceChannel {
40+
41+
static from(scope: DispatcherScope, device: AndroidDevice): AndroidDeviceDispatcher {
42+
const result = existingDispatcher<AndroidDeviceDispatcher>(device);
43+
return result || new AndroidDeviceDispatcher(scope, device);
44+
}
45+
4046
constructor(scope: DispatcherScope, device: AndroidDevice) {
4147
super(scope, device, 'AndroidDevice', {
4248
model: device.model,

src/server/android/android.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ export class Android {
8282
}
8383
return [...this._devices.values()];
8484
}
85+
86+
_deviceClosed(device: AndroidDevice) {
87+
this._devices.delete(device.serial);
88+
}
8589
}
8690

8791
export class AndroidDevice extends EventEmitter {
@@ -98,12 +102,16 @@ export class AndroidDevice extends EventEmitter {
98102
static Events = {
99103
WebViewAdded: 'webViewAdded',
100104
WebViewRemoved: 'webViewRemoved',
105+
Closed: 'closed'
101106
};
102107

103108
private _browserConnections = new Set<AndroidBrowser>();
109+
private _android: Android;
110+
private _isClosed = false;
104111

105112
constructor(android: Android, backend: DeviceBackend, model: string) {
106113
super();
114+
this._android = android;
107115
this._backend = backend;
108116
this.model = model;
109117
this.serial = backend.serial;
@@ -202,6 +210,7 @@ export class AndroidDevice extends EventEmitter {
202210
}
203211

204212
async close() {
213+
this._isClosed = true;
205214
if (this._pollingWebViews)
206215
clearTimeout(this._pollingWebViews);
207216
for (const connection of this._browserConnections)
@@ -211,6 +220,8 @@ export class AndroidDevice extends EventEmitter {
211220
driver.close();
212221
}
213222
await this._backend.close();
223+
this._android._deviceClosed(this);
224+
this.emit(AndroidDevice.Events.Closed);
214225
}
215226

216227
async launchBrowser(pkg: string = 'com.android.chrome', options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
@@ -234,11 +245,11 @@ export class AndroidDevice extends EventEmitter {
234245
return await this._connectToBrowser(socketName, options);
235246
}
236247

237-
connectToWebView(pid: number): Promise<BrowserContext> {
248+
async connectToWebView(pid: number): Promise<BrowserContext> {
238249
const webView = this._webViews.get(pid);
239250
if (!webView)
240251
throw new Error('WebView has been closed');
241-
return this._connectToBrowser(`webview_devtools_remote_${pid}`);
252+
return await this._connectToBrowser(`webview_devtools_remote_${pid}`);
242253
}
243254

244255
private async _connectToBrowser(socketName: string, options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
@@ -272,6 +283,8 @@ export class AndroidDevice extends EventEmitter {
272283

273284
private async _refreshWebViews() {
274285
const sockets = (await this._backend.runCommand(`shell:cat /proc/net/unix | grep webview_devtools_remote`)).split('\n');
286+
if (this._isClosed)
287+
return;
275288

276289
const newPids = new Set<number>();
277290
for (const line of sockets) {
@@ -286,6 +299,8 @@ export class AndroidDevice extends EventEmitter {
286299
continue;
287300

288301
const procs = (await this._backend.runCommand(`shell:ps -A | grep ${pid}`)).split('\n');
302+
if (this._isClosed)
303+
return;
289304
let pkg = '';
290305
for (const proc of procs) {
291306
const match = proc.match(/[^\s]+\s+(\d+).*$/);

test/android/webview.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ if (process.env.PW_ANDROID_TESTS) {
2323
await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
2424
const webview = await device.webView({ pkg: 'org.chromium.webview_shell' });
2525
expect(webview.pkg()).toBe('org.chromium.webview_shell');
26+
expect(device.webViews().length).toBe(1);
2627
});
2728

2829
it('should connect to page', async function({ device }) {
@@ -33,7 +34,7 @@ if (process.env.PW_ANDROID_TESTS) {
3334
expect(page.url()).toBe('about:blank');
3435
});
3536

36-
it('should navigate page externally', async function({ device, server }) {
37+
it('should navigate page internally', async function({ device, server }) {
3738
expect(device.webViews().length).toBe(0);
3839
await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
3940
const webview = await device.webView({ pkg: 'org.chromium.webview_shell' });

0 commit comments

Comments
 (0)