mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(adb): implement push (#4697)
This commit is contained in:
parent
b8112dedca
commit
f89dcc7ba7
1
android-types-internal.d.ts
vendored
1
android-types-internal.d.ts
vendored
@ -30,6 +30,7 @@ export interface AndroidDevice<BrowserContextOptions, BrowserContext, Page> exte
|
||||
shell(command: string): Promise<Buffer>;
|
||||
open(command: string): Promise<AndroidSocket>;
|
||||
installApk(file: string | Buffer, options?: { args?: string[] }): Promise<void>;
|
||||
push(file: string | Buffer, path: string, options?: { mode?: number }): Promise<void>;
|
||||
launchBrowser(options?: BrowserContextOptions & { packageName?: string }): Promise<BrowserContext>;
|
||||
close(): Promise<void>;
|
||||
|
||||
|
||||
@ -213,7 +213,13 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
|
||||
|
||||
async installApk(file: string | Buffer, options?: { args: string[] }): Promise<void> {
|
||||
return this._wrapApiCall('androidDevice.installApk', async () => {
|
||||
await this._channel.installApk({ file: await readApkFile(file), args: options && options.args });
|
||||
await this._channel.installApk({ file: await loadFile(file), args: options && options.args });
|
||||
});
|
||||
}
|
||||
|
||||
async push(file: string | Buffer, path: string, options?: { mode: number }): Promise<void> {
|
||||
return this._wrapApiCall('androidDevice.push', async () => {
|
||||
await this._channel.push({ file: await loadFile(file), path, mode: options ? options.mode : undefined });
|
||||
});
|
||||
}
|
||||
|
||||
@ -261,7 +267,7 @@ export class AndroidSocket extends ChannelOwner<channels.AndroidSocketChannel, c
|
||||
}
|
||||
}
|
||||
|
||||
async function readApkFile(file: string | Buffer): Promise<string> {
|
||||
async function loadFile(file: string | Buffer): Promise<string> {
|
||||
if (isString(file))
|
||||
return (await util.promisify(fs.readFile)(file)).toString('base64');
|
||||
return file.toString('base64');
|
||||
|
||||
@ -149,6 +149,10 @@ export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.
|
||||
await this._object.installApk(Buffer.from(params.file, 'base64'), { args: params.args });
|
||||
}
|
||||
|
||||
async push(params: channels.AndroidDevicePushParams) {
|
||||
await this._object.push(Buffer.from(params.file, 'base64'), params.path, params.mode);
|
||||
}
|
||||
|
||||
async launchBrowser(params: channels.AndroidDeviceLaunchBrowserParams): Promise<channels.AndroidDeviceLaunchBrowserResult> {
|
||||
const context = await this._object.launchBrowser(params.packageName, params);
|
||||
return { context: new BrowserContextDispatcher(this._scope, context) };
|
||||
|
||||
@ -2471,6 +2471,7 @@ export interface AndroidDeviceChannel extends Channel {
|
||||
open(params: AndroidDeviceOpenParams, metadata?: Metadata): Promise<AndroidDeviceOpenResult>;
|
||||
shell(params: AndroidDeviceShellParams, metadata?: Metadata): Promise<AndroidDeviceShellResult>;
|
||||
installApk(params: AndroidDeviceInstallApkParams, metadata?: Metadata): Promise<AndroidDeviceInstallApkResult>;
|
||||
push(params: AndroidDevicePushParams, metadata?: Metadata): Promise<AndroidDevicePushResult>;
|
||||
setDefaultTimeoutNoReply(params: AndroidDeviceSetDefaultTimeoutNoReplyParams, metadata?: Metadata): Promise<AndroidDeviceSetDefaultTimeoutNoReplyResult>;
|
||||
connectToWebView(params: AndroidDeviceConnectToWebViewParams, metadata?: Metadata): Promise<AndroidDeviceConnectToWebViewResult>;
|
||||
close(params?: AndroidDeviceCloseParams, metadata?: Metadata): Promise<AndroidDeviceCloseResult>;
|
||||
@ -2757,6 +2758,15 @@ export type AndroidDeviceInstallApkOptions = {
|
||||
args?: string[],
|
||||
};
|
||||
export type AndroidDeviceInstallApkResult = void;
|
||||
export type AndroidDevicePushParams = {
|
||||
file: Binary,
|
||||
path: string,
|
||||
mode?: number,
|
||||
};
|
||||
export type AndroidDevicePushOptions = {
|
||||
mode?: number,
|
||||
};
|
||||
export type AndroidDevicePushResult = void;
|
||||
export type AndroidDeviceSetDefaultTimeoutNoReplyParams = {
|
||||
timeout: number,
|
||||
};
|
||||
|
||||
@ -2312,6 +2312,12 @@ AndroidDevice:
|
||||
type: array?
|
||||
items: string
|
||||
|
||||
push:
|
||||
parameters:
|
||||
file: binary
|
||||
path: string
|
||||
mode: number?
|
||||
|
||||
setDefaultTimeoutNoReply:
|
||||
parameters:
|
||||
timeout: number
|
||||
|
||||
@ -1039,6 +1039,11 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||
file: tBinary,
|
||||
args: tOptional(tArray(tString)),
|
||||
});
|
||||
scheme.AndroidDevicePushParams = tObject({
|
||||
file: tBinary,
|
||||
path: tString,
|
||||
mode: tOptional(tNumber),
|
||||
});
|
||||
scheme.AndroidDeviceSetDefaultTimeoutNoReplyParams = tObject({
|
||||
timeout: tNumber,
|
||||
});
|
||||
|
||||
@ -287,6 +287,30 @@ export class AndroidDevice extends EventEmitter {
|
||||
debug('pw:android')('Written driver bytes: ' + success);
|
||||
}
|
||||
|
||||
async push(content: Buffer, path: string, mode = 0o644): Promise<void> {
|
||||
const socket = await this._backend.open(`sync:`);
|
||||
const sendHeader = async (command: string, length: number) => {
|
||||
const buffer = Buffer.alloc(command.length + 4);
|
||||
buffer.write(command, 0);
|
||||
buffer.writeUInt32LE(length, command.length);
|
||||
await socket.write(buffer);
|
||||
};
|
||||
const send = async (command: string, data: Buffer) => {
|
||||
await sendHeader(command, data.length);
|
||||
await socket.write(data);
|
||||
};
|
||||
await send('SEND', Buffer.from(`${path},${mode}`));
|
||||
const maxChunk = 65535;
|
||||
for (let i = 0; i < content.length; i += maxChunk)
|
||||
await send('DATA', content.slice(i, i + maxChunk));
|
||||
await sendHeader('DONE', (Date.now() / 1000) | 0);
|
||||
const result = await new Promise<Buffer>(f => socket.once('data', f));
|
||||
const code = result.slice(0, 4).toString();
|
||||
if (code !== 'OKAY')
|
||||
throw new Error('Could not push: ' + code);
|
||||
await socket.close();
|
||||
}
|
||||
|
||||
private async _refreshWebViews() {
|
||||
const sockets = (await this._backend.runCommand(`shell:cat /proc/net/unix | grep webview_devtools_remote`)).toString().split('\n');
|
||||
if (this._isClosed)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user