diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4367730a1a..08423d1afc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -246,7 +246,7 @@ jobs: run: utils/avd_recreate.sh - name: Start Android Emulator run: utils/avd_start.sh - - run: npx folio test/android -p browserName=chromium --workers=1 --forbid-only --timeout=60000 --global-timeout=5400000 --retries=3 --reporter=dot,json + - run: npx folio test/android -p browserName=chromium --workers=1 --forbid-only --timeout=120000 --global-timeout=5400000 --retries=3 --reporter=dot,json env: FOLIO_JSON_OUTPUT_NAME: "test-results/report.json" PW_ANDROID_TESTS: 1 diff --git a/.gitignore b/.gitignore index d67be88ba1..c37f7c5578 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ jest-report.json drivers/ /docs/api.json .android-sdk/ -.gradle/ \ No newline at end of file +.gradle/ +nohup.out \ No newline at end of file diff --git a/bin/android-driver-target.apk b/bin/android-driver-target.apk index a326d2549f..3ae99e75ff 100644 Binary files a/bin/android-driver-target.apk and b/bin/android-driver-target.apk differ diff --git a/bin/android-driver.apk b/bin/android-driver.apk index 1f3e389b99..eb6eb77499 100644 Binary files a/bin/android-driver.apk and b/bin/android-driver.apk differ diff --git a/src/dispatchers/androidDispatcher.ts b/src/dispatchers/androidDispatcher.ts index 28172a188c..1f675515d5 100644 --- a/src/dispatchers/androidDispatcher.ts +++ b/src/dispatchers/androidDispatcher.ts @@ -60,10 +60,8 @@ export class AndroidDeviceDispatcher extends Dispatcher { - if (this._driverPromise) - return this._driverPromise; - let callback: any; - this._driverPromise = new Promise(f => callback = f); + if (!this._driverPromise) + this._driverPromise = this._installDriver(); + return this._driverPromise; + } + private async _installDriver(): Promise { debug('pw:android')('Stopping the old driver'); await this.shell(`am force-stop com.microsoft.playwright.androiddriver`); @@ -185,9 +186,7 @@ export class AndroidDevice extends EventEmitter { callback.fulfill(result); this._callbacks.delete(id); }; - - callback(transport); - return this._driverPromise; + return transport; } private async _waitForLocalAbstract(socketName: string): Promise { @@ -204,7 +203,9 @@ export class AndroidDevice extends EventEmitter { return socket; } - async send(method: string, params: any): Promise { + async send(method: string, params: any = {}): Promise { + // Patch the timeout in! + params.timeout = this._timeoutSettings.timeout(params); const driver = await this._driver(); const id = ++this._lastId; const result = new Promise((fulfill, reject) => this._callbacks.set(id, { fulfill, reject })); diff --git a/src/server/android/driver/app/build.gradle b/src/server/android/driver/app/build.gradle index 48823ef079..d9fe9dffea 100644 --- a/src/server/android/driver/app/build.gradle +++ b/src/server/android/driver/app/build.gradle @@ -28,10 +28,6 @@ android { } dependencies { - - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.2.1' - testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' diff --git a/src/server/android/driver/app/src/androidTest/java/com/microsoft/playwright/androiddriver/InstrumentedTest.java b/src/server/android/driver/app/src/androidTest/java/com/microsoft/playwright/androiddriver/InstrumentedTest.java index 4c7519003a..5875cb7115 100644 --- a/src/server/android/driver/app/src/androidTest/java/com/microsoft/playwright/androiddriver/InstrumentedTest.java +++ b/src/server/android/driver/app/src/androidTest/java/com/microsoft/playwright/androiddriver/InstrumentedTest.java @@ -23,7 +23,6 @@ import android.net.LocalSocket; import android.view.accessibility.AccessibilityNodeInfo; import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SdkSuppress; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; @@ -53,7 +52,6 @@ import java.util.regex.Pattern; * @see Testing documentation */ @RunWith(AndroidJUnit4.class) -@SdkSuppress(minSdkVersion = 21) public class InstrumentedTest { @SuppressWarnings("ConstantConditions") diff --git a/src/server/android/driver/app/src/main/AndroidManifest.xml b/src/server/android/driver/app/src/main/AndroidManifest.xml index c9df74d240..ef59bebe4e 100644 --- a/src/server/android/driver/app/src/main/AndroidManifest.xml +++ b/src/server/android/driver/app/src/main/AndroidManifest.xml @@ -5,9 +5,8 @@ + android:supportsRtl="true" /> \ No newline at end of file diff --git a/src/server/android/driver/app/src/main/res/values-night/themes.xml b/src/server/android/driver/app/src/main/res/values-night/themes.xml deleted file mode 100644 index 335c89b667..0000000000 --- a/src/server/android/driver/app/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/server/android/driver/app/src/main/res/values/colors.xml b/src/server/android/driver/app/src/main/res/values/colors.xml deleted file mode 100644 index f8c6127d32..0000000000 --- a/src/server/android/driver/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/src/server/android/driver/app/src/main/res/values/strings.xml b/src/server/android/driver/app/src/main/res/values/strings.xml deleted file mode 100644 index 4feaf3acd9..0000000000 --- a/src/server/android/driver/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Playwright Android Driver - \ No newline at end of file diff --git a/src/server/android/driver/app/src/main/res/values/themes.xml b/src/server/android/driver/app/src/main/res/values/themes.xml deleted file mode 100644 index a6f83506b1..0000000000 --- a/src/server/android/driver/app/src/main/res/values/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - \ No newline at end of file diff --git a/test/android/android.fixtures.ts b/test/android/android.fixtures.ts index c747a9d992..b5c3122edb 100644 --- a/test/android/android.fixtures.ts +++ b/test/android/android.fixtures.ts @@ -27,6 +27,7 @@ fixtures.device.init(async ({ playwright }, runTest) => { const [device] = await playwright._android.devices(); await device.shell('am force-stop org.chromium.webview_shell'); await device.shell('am force-stop com.android.chrome'); + device.setDefaultTimeout(120000); await runTest(device); device.close(); }); diff --git a/test/android/device.spec.ts b/test/android/device.spec.ts index 1536e07da8..3f49a0c441 100644 --- a/test/android/device.spec.ts +++ b/test/android/device.spec.ts @@ -49,4 +49,12 @@ if (process.env.PW_ANDROID_TESTS) { const data = await device.shell('cat /data/local/tmp/hello-world'); expect(data).toEqual(Buffer.from('hello world')); }); + + it('androidDevice.fill', test => { + test.fixme(!!process.env.CI, 'Hangs on the bots'); + }, async function({ device }) { + await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity'); + await device.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'Hello'); + expect((await device.info({ res: 'org.chromium.webview_shell:id/url_field' })).text).toBe('Hello'); + }); } diff --git a/test/android/webview.spec.ts b/test/android/webview.spec.ts index 184bc9ef20..0b7a0e8ffd 100644 --- a/test/android/webview.spec.ts +++ b/test/android/webview.spec.ts @@ -45,7 +45,7 @@ if (process.env.PW_ANDROID_TESTS) { it('should navigate page externally', test => { test.fixme(!!process.env.CI, 'Hangs on the bots'); - }, async function({ device, server }) { + }, async function({ device }) { expect(device.webViews().length).toBe(0); await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity'); const webview = await device.webView({ pkg: 'org.chromium.webview_shell' }); diff --git a/utils/avd_start.sh b/utils/avd_start.sh index cc629d8d57..d0d4356364 100755 --- a/utils/avd_start.sh +++ b/utils/avd_start.sh @@ -9,10 +9,10 @@ if [[ -z "${ANDROID_HOME}" ]]; then fi echo "Killing previous emulators" -${ANDROID_HOME}/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done +${ANDROID_HOME}/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do ${ANDROID_HOME}/platform-tools/adb -s $line emu kill; done echo "Starting emulator" -nohup ${ANDROID_HOME}/emulator/emulator -avd android30 -no-audio -no-snapshot -no-window -gpu swiftshader_indirect & +nohup ${ANDROID_HOME}/emulator/emulator -avd android30 -no-audio -no-snapshot & ${ANDROID_HOME}/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82' ${ANDROID_HOME}/platform-tools/adb devices echo "Emulator started" \ No newline at end of file