test: android test enhancements (#15797)
This commit is contained in:
Родитель
35a7be24a3
Коммит
501b24a078
|
@ -11,7 +11,7 @@ on:
|
|||
- release-*
|
||||
paths:
|
||||
- "**android**"
|
||||
- "utils/avd_*.js"
|
||||
- "utils/avd_*"
|
||||
- ".github/workflows/tests_android.yml"
|
||||
|
||||
env:
|
||||
|
@ -38,7 +38,6 @@ jobs:
|
|||
env:
|
||||
DEBUG: pw:install
|
||||
- run: npm run build
|
||||
- run: npx playwright install-deps
|
||||
- name: Create Android Emulator
|
||||
run: utils/avd_recreate.sh
|
||||
- name: Start Android Emulator
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
import net from 'net';
|
||||
import { androidTest as test, expect } from './androidTest';
|
||||
|
||||
test.afterAll(async ({ androidDevice }) => {
|
||||
await androidDevice.shell('am force-stop com.android.chrome');
|
||||
});
|
||||
|
||||
test('androidDevice.model', async function({ androidDevice }) {
|
||||
expect(androidDevice.model()).toBe('sdk_gphone64_x86_64');
|
||||
});
|
||||
|
@ -55,6 +59,7 @@ test('should be able to send CDP messages', async ({ androidDevice }) => {
|
|||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', { expression: '1 + 2', returnByValue: true });
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
test('should be able to use a custom port', async function({ playwright }) {
|
||||
|
@ -102,4 +107,5 @@ test('should be able to pass context options', async ({ androidDevice, httpsServ
|
|||
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(false);
|
||||
await context.close();
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ test('androidDevice.push', async function({ androidDevice }) {
|
|||
});
|
||||
|
||||
test('androidDevice.fill', async function({ androidDevice }) {
|
||||
test.fixme(!!process.env.CI, 'Hangs on the bots');
|
||||
test.fixme(true, 'Hangs on the bots');
|
||||
|
||||
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
|
||||
await androidDevice.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'Hello');
|
||||
|
@ -81,7 +81,7 @@ test('androidDevice.options.omitDriverInstall', async function({ playwright }) {
|
|||
const filePath = join(require.resolve('playwright-core'), '..', 'bin', file);
|
||||
await androidDevice.installApk(await fs.promises.readFile(filePath));
|
||||
}
|
||||
androidDevice.shell('am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner').catch(e => console.error);
|
||||
androidDevice.shell('am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner').catch(e => console.error(e));
|
||||
|
||||
// wait for finishing fill operation
|
||||
while (!fillStatus)
|
||||
|
|
|
@ -48,7 +48,7 @@ test('should navigate page internally', async function({ androidDevice }) {
|
|||
});
|
||||
|
||||
test('should navigate page externally', async function({ androidDevice }) {
|
||||
test.fixme(!!process.env.CI, 'Hangs on the bots');
|
||||
test.fixme(true, 'Hangs on the bots');
|
||||
|
||||
expect(androidDevice.webViews().length).toBe(0);
|
||||
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
|
||||
|
|
|
@ -202,7 +202,9 @@ it('allInnerTexts should work', async ({ page }) => {
|
|||
expect(await page.locator('div').allInnerTexts()).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
|
||||
it('isVisible and isHidden should work with details', async ({ page }) => {
|
||||
it('isVisible and isHidden should work with details', async ({ page, isAndroid }) => {
|
||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10674' });
|
||||
it.skip(isAndroid, 'We can\'t disable the AutoExpandDetailsElement feature on Android');
|
||||
await page.setContent(`<details>
|
||||
<summary>click to open</summary>
|
||||
<ul>
|
||||
|
|
|
@ -16,16 +16,34 @@
|
|||
|
||||
import { test as it, expect } from './pageTest';
|
||||
import { waitForTestLog } from '../config/utils';
|
||||
import type { Locator } from 'playwright-core';
|
||||
|
||||
type BoundingBox = Awaited<ReturnType<Locator['boundingBox']>>;
|
||||
|
||||
it.skip(({ mode }) => mode !== 'default', 'Highlight element has a closed shadow-root on != default');
|
||||
|
||||
it('should highlight locator', async ({ page }) => {
|
||||
it('should highlight locator', async ({ page, isAndroid }) => {
|
||||
await page.setContent(`<input type='text' />`);
|
||||
const textPromise = waitForTestLog<string>(page, 'Highlight text for test: ');
|
||||
const boxPromise = waitForTestLog<{ x: number, y: number, width: number, height: number }>(page, 'Highlight box for test: ');
|
||||
await page.locator('input').highlight();
|
||||
expect(await textPromise).toBe('input');
|
||||
const box1 = await page.locator('input').boundingBox();
|
||||
const box2 = await boxPromise;
|
||||
let box1 = await page.locator('input').boundingBox();
|
||||
let box2 = await boxPromise;
|
||||
|
||||
if (isAndroid) {
|
||||
box1 = roundBox(box1);
|
||||
box2 = roundBox(box2);
|
||||
}
|
||||
|
||||
expect(box1).toEqual(box2);
|
||||
});
|
||||
|
||||
function roundBox(box: BoundingBox): BoundingBox {
|
||||
return {
|
||||
x: Math.round(box.x),
|
||||
y: Math.round(box.y),
|
||||
width: Math.round(box.width),
|
||||
height: Math.round(box.height),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ mkdir ${SDKDIR}/cmdline-tools
|
|||
echo Downloading Android SDK...
|
||||
cd ${SDKDIR}/cmdline-tools
|
||||
COMMAND_LINE_TOOLS_ZIP=${SDKDIR}/commandlinetools.zip
|
||||
curl https://dl.google.com/android/repository/commandlinetools-mac-7583922_latest.zip -o ${COMMAND_LINE_TOOLS_ZIP}
|
||||
# https://developer.android.com/studio#command-tools
|
||||
curl https://dl.google.com/android/repository/commandlinetools-mac-8512546_latest.zip -o ${COMMAND_LINE_TOOLS_ZIP}
|
||||
unzip ${COMMAND_LINE_TOOLS_ZIP}
|
||||
rm ${COMMAND_LINE_TOOLS_ZIP}
|
||||
mv cmdline-tools latest
|
||||
|
|
|
@ -8,8 +8,7 @@ if [[ -z "${ANDROID_HOME}" ]]; then
|
|||
export ANDROID_SDK_ROOT=${SDKDIR}
|
||||
fi
|
||||
|
||||
echo "Killing previous emulators"
|
||||
${ANDROID_HOME}/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do ${ANDROID_HOME}/platform-tools/adb -s $line emu kill; done
|
||||
bash $PWD/utils/avd_stop.sh
|
||||
|
||||
EMULATOR_GPU="host"
|
||||
if [[ -n "${GITHUB_ACTIONS}" ]]; then
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ -z "${ANDROID_HOME}" ]]; then
|
||||
SDKDIR=$PWD/.android-sdk
|
||||
export ANDROID_HOME=${SDKDIR}
|
||||
export ANDROID_SDK_ROOT=${SDKDIR}
|
||||
fi
|
||||
|
||||
echo "Killing previous emulators"
|
||||
${ANDROID_HOME}/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do ${ANDROID_HOME}/platform-tools/adb -s $line emu kill; done
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const { _clank } = require('..');
|
||||
const assert = require('assert');
|
||||
const childProcess = require('child_process');
|
||||
const path = require('path');
|
||||
const readline = require('readline');
|
||||
|
||||
(async () => {
|
||||
setTimeout(() => {
|
||||
console.error('Timed out starting emulator');
|
||||
process.exit(1);
|
||||
}, 60000);
|
||||
const proc = childProcess.spawn(path.join(process.cwd(), '.android-sdk/emulator/emulator'), ['-no-window', '-avd', 'android30', '-verbose'], {
|
||||
env: {
|
||||
...process.env,
|
||||
ANDROID_SDK_ROOT: path.join(process.cwd(), '.android-sdk'),
|
||||
ANDROID_HOME: path.join(process.cwd(), '.android-sdk'),
|
||||
}
|
||||
});
|
||||
proc.stdout.on('data', data => console.log(data.toString()));
|
||||
proc.stderr.on('data', data => console.log(data.toString()));
|
||||
await waitForLine(proc, /boot completed/);
|
||||
|
||||
const context = await _clank.launchPersistentContext('');
|
||||
const [page] = context.pages();
|
||||
await page.goto('data:text/html,<title>Hello world</title>');
|
||||
assert(await page.title() === 'Hello world');
|
||||
await context.close();
|
||||
process.exit(0);
|
||||
})();
|
||||
|
||||
async function waitForLine(proc, regex) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({ input: proc.stdout });
|
||||
const failError = new Error('Process failed to launch!');
|
||||
rl.on('line', onLine);
|
||||
rl.on('close', reject.bind(null, failError));
|
||||
proc.on('exit', reject.bind(null, failError));
|
||||
proc.on('error', reject.bind(null, failError));
|
||||
|
||||
function onLine(line) {
|
||||
const match = line.match(regex);
|
||||
if (!match)
|
||||
return;
|
||||
resolve(match);
|
||||
}
|
||||
});
|
||||
}
|
Загрузка…
Ссылка в новой задаче