diff --git a/packages/playwright-core/src/server/android/android.ts b/packages/playwright-core/src/server/android/android.ts index 7819f2af1a..1263bfa58f 100644 --- a/packages/playwright-core/src/server/android/android.ts +++ b/packages/playwright-core/src/server/android/android.ts @@ -266,7 +266,8 @@ export class AndroidDevice extends SdkObject { const socketName = isUnderTest() ? 'webview_devtools_remote_playwright_test' : ('playwright-' + createGuid()); const commandLine = this._defaultArgs(options, socketName).join(' '); debug('pw:android')('Starting', pkg, commandLine); - await this._backend.runCommand(`shell:echo "${commandLine}" > /data/local/tmp/chrome-command-line`); + // encode commandLine to base64 to avoid issues (bash encoding) with special characters + await this._backend.runCommand(`shell:echo "${Buffer.from(commandLine).toString('base64')}" | base64 -d > /data/local/tmp/chrome-command-line`); await this._backend.runCommand(`shell:am start -a android.intent.action.VIEW -d about:blank ${pkg}`); return await this._connectToBrowser(socketName, options); } diff --git a/tests/android/browser.spec.ts b/tests/android/browser.spec.ts index 9a189fe16a..5ec09c6a57 100644 --- a/tests/android/browser.spec.ts +++ b/tests/android/browser.spec.ts @@ -32,12 +32,19 @@ test('androidDevice.launchBrowser', async function({ androidDevice }) { await context.close(); }); -test('androidDevice.launchBrowser should pass args with spaces', async ({ androidDevice }) => { - const context = await androidDevice.launchBrowser({ args: ['--user-agent=I am Foo'] }); - const page = await context.newPage(); - const userAgent = await page.evaluate(() => navigator.userAgent); - await context.close(); - expect(userAgent).toBe('I am Foo'); +test('androidDevice.launchBrowser should treat args correctly', async ({ androidDevice }) => { + for (const arg of [ + "--user-agent='I am Foo'", + '--user-agent="I am Foo"', + ]) { + await test.step(`arg: ${arg}`, async () => { + const context = await androidDevice.launchBrowser({ args: [arg] }); + const page = await context.newPage(); + const userAgent = await page.evaluate(() => navigator.userAgent); + await context.close(); + expect(userAgent).toBe('I am Foo'); + }); + } }); test('androidDevice.launchBrowser should throw for bad proxy server value', async ({ androidDevice }) => { @@ -48,12 +55,12 @@ test('androidDevice.launchBrowser should throw for bad proxy server value', asyn expect(error.message).toContain('proxy.server: expected string, got number'); }); -test('androidDevice.launchBrowser should pass proxy config', async ({ androidDevice, server, mode }) => { +test('androidDevice.launchBrowser should pass proxy config', async ({ androidDevice, server, mode, loopback }) => { test.skip(mode === 'docker', 'proxy is not supported for remote connection'); server.setRoute('/target.html', async (req, res) => { res.end('Served by the proxy'); }); - const context = await androidDevice.launchBrowser({ proxy: { server: `localhost:${server.PORT}` } }); + const context = await androidDevice.launchBrowser({ proxy: { server: `${loopback}:${server.PORT}` } }); const page = await context.newPage(); await page.goto('http://non-existent.com/target.html'); expect(await page.title()).toBe('Served by the proxy'); diff --git a/utils/avd_recreate.sh b/utils/avd_recreate.sh index a69d986a37..f0724f5bec 100755 --- a/utils/avd_recreate.sh +++ b/utils/avd_recreate.sh @@ -8,7 +8,14 @@ if [[ -z "${ANDROID_HOME}" ]]; then export ANDROID_SDK_ROOT=${SDKDIR} fi +ANDROID_ARCH="x86_64" + +# on MacOS M1 we need to use arm64 (can't emulate x86_64) +if [[ "$(uname -m)" == "arm64" ]]; then + ANDROID_ARCH="arm64-v8a" +fi + ${ANDROID_HOME}/tools/bin/avdmanager delete avd --name android33 || true -echo "y" | ${ANDROID_HOME}/tools/bin/sdkmanager --install "system-images;android-33;google_apis;x86_64" -echo "no" | ${ANDROID_HOME}/tools/bin/avdmanager create avd --force --name android33 --device "Nexus 5X" --package "system-images;android-33;google_apis;x86_64" +echo "y" | ${ANDROID_HOME}/tools/bin/sdkmanager --install "system-images;android-33;google_apis;$ANDROID_ARCH" +echo "no" | ${ANDROID_HOME}/tools/bin/avdmanager create avd --force --name android33 --device "Nexus 5X" --package "system-images;android-33;google_apis;$ANDROID_ARCH" ${ANDROID_HOME}/emulator/emulator -list-avds