diff --git a/packages/playwright-core/bin/android-driver-target.apk b/packages/playwright-core/bin/android-driver-target.apk deleted file mode 100644 index 3ae99e75ff..0000000000 Binary files a/packages/playwright-core/bin/android-driver-target.apk and /dev/null differ diff --git a/packages/playwright-core/bin/android-driver.apk b/packages/playwright-core/bin/android-driver.apk deleted file mode 100644 index eb6eb77499..0000000000 Binary files a/packages/playwright-core/bin/android-driver.apk and /dev/null differ diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index b8dc73e6e1..af0761ddeb 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -46,6 +46,11 @@ "name": "ffmpeg", "revision": "1008", "installByDefault": true + }, + { + "name": "android", + "revision": "1000", + "installByDefault": false } ] } diff --git a/packages/playwright-core/src/server/android/DEPS.list b/packages/playwright-core/src/server/android/DEPS.list index faf582bf1e..10e75d06f0 100644 --- a/packages/playwright-core/src/server/android/DEPS.list +++ b/packages/playwright-core/src/server/android/DEPS.list @@ -5,3 +5,4 @@ ../../utils/ ../../utilsBundle.ts ../chromium/ +../registry/ \ No newline at end of file diff --git a/packages/playwright-core/src/server/android/android.ts b/packages/playwright-core/src/server/android/android.ts index 1065d8c273..ae0aa9644c 100644 --- a/packages/playwright-core/src/server/android/android.ts +++ b/packages/playwright-core/src/server/android/android.ts @@ -36,6 +36,7 @@ import { TimeoutSettings } from '../../common/timeoutSettings'; import type * as channels from '@protocol/channels'; import { SdkObject, serverSideCallMetadata } from '../instrumentation'; import { DEFAULT_ARGS } from '../chromium/chromium'; +import { registry } from '../registry'; const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-'); @@ -186,8 +187,13 @@ export class AndroidDevice extends SdkObject { await this.shell(`cmd package uninstall com.microsoft.playwright.androiddriver.test`); debug('pw:android')('Installing the new driver'); - for (const file of ['android-driver.apk', 'android-driver-target.apk']) - await this.installApk(await fs.promises.readFile(require.resolve(`../../../bin/${file}`))); + const executable = registry.findExecutable('android')!; + for (const file of ['android-driver.apk', 'android-driver-target.apk']) { + const fullName = path.join(executable.directory!, file); + if (!fs.existsSync(fullName)) + throw new Error('Please install Android driver apk using `npx playwright install android`'); + await this.installApk(await fs.promises.readFile(fullName)); + } } else { debug('pw:android')('Skipping the driver installation'); } diff --git a/packages/playwright-core/src/server/registry/browserFetcher.ts b/packages/playwright-core/src/server/registry/browserFetcher.ts index 4c958e87c3..89aa058547 100644 --- a/packages/playwright-core/src/server/registry/browserFetcher.ts +++ b/packages/playwright-core/src/server/registry/browserFetcher.ts @@ -26,7 +26,7 @@ import { extract } from '../../zipBundle'; import { ManualPromise } from '../../utils/manualPromise'; import { colors } from '../../utilsBundle'; -export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string, downloadURLs: string[], downloadFileName: string, downloadConnectionTimeout: number): Promise { +export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string | undefined, downloadURLs: string[], downloadFileName: string, downloadConnectionTimeout: number): Promise { if (await existsAsync(browserDirectory)) { // Already downloaded. debugLogger.log('install', `${title} is already downloaded.`); @@ -54,8 +54,10 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec debugLogger.log('install', `-- zip: ${zipPath}`); debugLogger.log('install', `-- location: ${browserDirectory}`); await extract(zipPath, { dir: browserDirectory }); - debugLogger.log('install', `fixing permissions at ${executablePath}`); - await fs.promises.chmod(executablePath, 0o755); + if (executablePath) { + debugLogger.log('install', `fixing permissions at ${executablePath}`); + await fs.promises.chmod(executablePath, 0o755); + } } catch (e) { debugLogger.log('install', `FAILED installation ${title} with error: ${e}`); process.exitCode = 1; diff --git a/packages/playwright-core/src/server/registry/index.ts b/packages/playwright-core/src/server/registry/index.ts index 91c3893434..ae036f5d83 100644 --- a/packages/playwright-core/src/server/registry/index.ts +++ b/packages/playwright-core/src/server/registry/index.ts @@ -214,6 +214,9 @@ const DOWNLOAD_PATHS = { 'mac12-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip', 'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip', }, + 'android': { + '': 'builds/android/%s/android.zip', + }, }; export const registryDirectory = (() => { @@ -300,7 +303,7 @@ function readDescriptors(browsersJSON: BrowsersJSON) { } export type BrowserName = 'chromium' | 'firefox' | 'webkit'; -type InternalTool = 'ffmpeg' | 'firefox-beta' | 'chromium-with-symbols' | 'chromium-tip-of-tree'; +type InternalTool = 'ffmpeg' | 'firefox-beta' | 'chromium-with-symbols' | 'chromium-tip-of-tree' | 'android'; type ChromiumChannel = 'chrome' | 'chrome-beta' | 'chrome-dev' | 'chrome-canary' | 'msedge' | 'msedge-beta' | 'msedge-dev' | 'msedge-canary'; const allDownloadable = ['chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-with-symbols', 'chromium-tip-of-tree']; @@ -569,6 +572,21 @@ export class Registry { _dependencyGroup: 'tools', _isHermeticInstallation: true, }); + const android = descriptors.find(d => d.name === 'android')!; + this._executables.push({ + type: 'tool', + name: 'android', + browserName: undefined, + directory: android.dir, + executablePath: () => undefined, + executablePathOrDie: () => '', + installType: 'download-on-demand', + validateHostRequirements: () => Promise.resolve(), + downloadURLs: this._downloadURLs(android), + _install: () => this._downloadExecutable(android), + _dependencyGroup: 'tools', + _isHermeticInstallation: true, + }); } private _createChromiumChannel(name: ChromiumChannel, lookAt: Record<'linux' | 'darwin' | 'win32', string>, install?: () => Promise): ExecutableImpl { @@ -743,7 +761,8 @@ export class Registry { } private _downloadURLs(descriptor: BrowsersJSONDescriptor): string[] { - const downloadPathTemplate: string|undefined = (DOWNLOAD_PATHS as any)[descriptor.name][hostPlatform]; + const paths = (DOWNLOAD_PATHS as any)[descriptor.name]; + const downloadPathTemplate: string|undefined = paths[hostPlatform] || paths['']; if (!downloadPathTemplate) return []; const downloadPath = util.format(downloadPathTemplate, descriptor.revision); @@ -763,9 +782,9 @@ export class Registry { return downloadURLs; } - private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath: string | undefined) { + private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath?: string) { const downloadURLs = this._downloadURLs(descriptor); - if (!downloadURLs.length || !executablePath) + if (!downloadURLs.length) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${hostPlatform}`); if (hostPlatform === 'generic-linux' || hostPlatform === 'generic-linux-arm64') logPolitely('BEWARE: your OS is not officially supported by Playwright; downloading fallback build.'); diff --git a/utils/build_android_driver.sh b/utils/build_android_driver.sh index 92b8c66c8f..46d313b115 100755 --- a/utils/build_android_driver.sh +++ b/utils/build_android_driver.sh @@ -10,5 +10,6 @@ if [ "$?" -ne "0" ]; then exit 1 fi -cp src/server/android/driver/app/build/outputs/apk/debug/app-debug.apk ./bin/android-driver-target.apk -cp src/server/android/driver/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk ./bin/android-driver.apk +# These should be uploaded to the CDN +# cp src/server/android/driver/app/build/outputs/apk/debug/app-debug.apk ./bin/android-driver-target.apk +# cp src/server/android/driver/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk ./bin/android-driver.apk