test(android): run selected page tests on android (#5879)

This commit is contained in:
Pavel Feldman 2021-03-19 10:31:54 +08:00 committed by GitHub
parent cbebf64f07
commit ad5c028f37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 188 additions and 178 deletions

View file

@ -235,6 +235,9 @@ jobs:
test_android:
name: Android Emulator
runs-on: macos-10.15
env:
FOLIO_JSON_OUTPUT_NAME: "test-results/report.json"
PW_ANDROID_TESTS: 1
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
@ -247,10 +250,10 @@ 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=120000 --global-timeout=5400000 --retries=3 --reporter=dot,json
env:
FOLIO_JSON_OUTPUT_NAME: "test-results/report.json"
PW_ANDROID_TESTS: 1
- name: Run device tests
run: npx folio test/android -p browserName=chromium --workers=1 --forbid-only --timeout=120000 --global-timeout=5400000 --retries=3 --reporter=dot,json
- name: Run page tests
run: npx folio test/page -p browserName=chromium --workers=1 --forbid-only --timeout=120000 --global-timeout=5400000 --retries=3 --reporter=dot,json
- run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json
if: always() && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-'))
- uses: actions/upload-artifact@v1

View file

@ -1,35 +0,0 @@
/**
* Copyright 2020 Microsoft Corporation. All rights reserved.
*
* 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.
*/
import type { Android, AndroidDevice } from '../..';
import { folio as baseFolio } from '../fixtures';
const fixtures = baseFolio.extend<{
device: AndroidDevice
}, {
android: Android,
}>();
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);
await device.close();
});
export const folio = fixtures.build();

View file

@ -14,24 +14,24 @@
* limitations under the License.
*/
import { folio } from './android.fixtures';
import { folio } from '../fixtures';
const { it, expect } = folio;
if (process.env.PW_ANDROID_TESTS) {
it('androidDevice.model', async function({ device }) {
expect(device.model()).toBe('sdk_gphone_x86_arm');
it('androidDevice.model', async function({ androidDevice }) {
expect(androidDevice.model()).toBe('sdk_gphone_x86_arm');
});
it('androidDevice.launchBrowser', async function({ device }) {
const context = await device.launchBrowser();
it('androidDevice.launchBrowser', async function({ androidDevice }) {
const context = await androidDevice.launchBrowser();
const [page] = context.pages();
await page.goto('data:text/html,<title>Hello world!</title>');
expect(await page.title()).toBe('Hello world!');
await context.close();
});
it('should create new page', async function({ device }) {
const context = await device.launchBrowser();
it('should create new page', async function({ androidDevice }) {
const context = await androidDevice.launchBrowser();
const page = await context.newPage();
await page.goto('data:text/html,<title>Hello world!</title>');
expect(await page.title()).toBe('Hello world!');
@ -39,8 +39,8 @@ if (process.env.PW_ANDROID_TESTS) {
await context.close();
});
it('should check', async function({ device }) {
const context = await device.launchBrowser();
it('should check', async function({ androidDevice }) {
const context = await androidDevice.launchBrowser();
const [page] = context.pages();
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
await page.check('input');
@ -48,8 +48,8 @@ if (process.env.PW_ANDROID_TESTS) {
await page.close();
await context.close();
});
it('should be able to send CDP messages', async ({ device }) => {
const context = await device.launchBrowser();
it('should be able to send CDP messages', async ({ androidDevice }) => {
const context = await androidDevice.launchBrowser();
const [page] = context.pages();
const client = await context.newCDPSession(page);
await client.send('Runtime.enable');

View file

@ -17,17 +17,17 @@
import fs from 'fs';
import { PNG } from 'pngjs';
import { folio } from './android.fixtures';
import { folio } from '../fixtures';
const { it, expect } = folio;
if (process.env.PW_ANDROID_TESTS) {
it('androidDevice.shell', async function({ device }) {
const output = await device.shell('echo 123');
it('androidDevice.shell', async function({ androidDevice }) {
const output = await androidDevice.shell('echo 123');
expect(output.toString()).toBe('123\n');
});
it('androidDevice.open', async function({ device }) {
const socket = await device.open('shell:/bin/cat');
it('androidDevice.open', async function({ androidDevice }) {
const socket = await androidDevice.open('shell:/bin/cat');
await socket.write(Buffer.from('321\n'));
const output = await new Promise(resolve => socket.on('data', resolve));
expect(output.toString()).toBe('321\n');
@ -36,9 +36,9 @@ if (process.env.PW_ANDROID_TESTS) {
await closedPromise;
});
it('androidDevice.screenshot', async function({ device, testInfo }) {
it('androidDevice.screenshot', async function({ androidDevice, testInfo }) {
const path = testInfo.outputPath('screenshot.png');
const result = await device.screenshot({ path });
const result = await androidDevice.screenshot({ path });
const buffer = fs.readFileSync(path);
expect(result.length).toBe(buffer.length);
const { width, height} = PNG.sync.read(result);
@ -46,18 +46,18 @@ if (process.env.PW_ANDROID_TESTS) {
expect(height).toBe(1920);
});
it('androidDevice.push', async function({ device, testInfo }) {
await device.shell('rm /data/local/tmp/hello-world');
await device.push(Buffer.from('hello world'), '/data/local/tmp/hello-world');
const data = await device.shell('cat /data/local/tmp/hello-world');
it('androidDevice.push', async function({ androidDevice }) {
await androidDevice.shell('rm /data/local/tmp/hello-world');
await androidDevice.push(Buffer.from('hello world'), '/data/local/tmp/hello-world');
const data = await androidDevice.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');
}, async function({ androidDevice }) {
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
await androidDevice.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'Hello');
expect((await androidDevice.info({ res: 'org.chromium.webview_shell:id/url_field' })).text).toBe('Hello');
});
}

View file

@ -14,30 +14,30 @@
* limitations under the License.
*/
import { folio } from './android.fixtures';
import { folio } from '../fixtures';
const { it, expect } = folio;
if (process.env.PW_ANDROID_TESTS) {
it('androidDevice.webView', 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' });
it('androidDevice.webView', async function({ androidDevice }) {
expect(androidDevice.webViews().length).toBe(0);
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
const webview = await androidDevice.webView({ pkg: 'org.chromium.webview_shell' });
expect(webview.pkg()).toBe('org.chromium.webview_shell');
expect(device.webViews().length).toBe(1);
expect(androidDevice.webViews().length).toBe(1);
});
it('webView.page', 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' });
it('webView.page', async function({ androidDevice }) {
expect(androidDevice.webViews().length).toBe(0);
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
const webview = await androidDevice.webView({ pkg: 'org.chromium.webview_shell' });
const page = await webview.page();
expect(page.url()).toBe('about:blank');
});
it('should navigate page internally', async function({ device, server }) {
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' });
it('should navigate page internally', async function({ androidDevice }) {
expect(androidDevice.webViews().length).toBe(0);
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
const webview = await androidDevice.webView({ pkg: 'org.chromium.webview_shell' });
const page = await webview.page();
await page.goto('data:text/html,<title>Hello world!</title>');
expect(await page.title()).toBe('Hello world!');
@ -45,16 +45,16 @@ if (process.env.PW_ANDROID_TESTS) {
it('should navigate page externally', test => {
test.fixme(!!process.env.CI, 'Hangs on the bots');
}, 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' });
}, async function({ androidDevice }) {
expect(androidDevice.webViews().length).toBe(0);
await androidDevice.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
const webview = await androidDevice.webView({ pkg: 'org.chromium.webview_shell' });
const page = await webview.page();
await device.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'data:text/html,<title>Hello world!</title>');
await androidDevice.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'data:text/html,<title>Hello world!</title>');
await Promise.all([
page.waitForNavigation(),
device.press({ res: 'org.chromium.webview_shell:id/url_field' }, 'Enter')
androidDevice.press({ res: 'org.chromium.webview_shell:id/url_field' }, 'Enter')
]);
expect(await page.title()).toBe('Hello world!');
});

View file

@ -0,0 +1,69 @@
/**
* Copyright 2018 Google Inc. All rights reserved.
* Modifications 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.
*/
import { it, expect } from './fixtures';
import path from 'path';
it('should work with browser context scripts', async ({ context, server }) => {
await context.addInitScript(() => window['temp'] = 123);
const page = await context.newPage();
await page.addInitScript(() => window['injected'] = window['temp']);
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
});
it('should work without navigation, after all bindings', async ({ context }) => {
let callback;
const promise = new Promise(f => callback = f);
await context.exposeFunction('woof', function(arg) {
callback(arg);
});
await context.addInitScript(() => {
window['woof']('hey');
window['temp'] = 123;
});
const page = await context.newPage();
expect(await page.evaluate(() => window['temp'])).toBe(123);
expect(await promise).toBe('hey');
});
it('should work without navigation in popup', async ({ context }) => {
await context.addInitScript(() => window['temp'] = 123);
const page = await context.newPage();
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.evaluate(() => window['win'] = window.open()),
]);
expect(await popup.evaluate(() => window['temp'])).toBe(123);
});
it('should work with browser context scripts with a path', async ({ context, server }) => {
await context.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') });
const page = await context.newPage();
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
});
it('should work with browser context scripts for already created pages', async ({ context, server }) => {
const page = await context.newPage();
await context.addInitScript(() => window['temp'] = 123);
await page.addInitScript(() => window['injected'] = window['temp']);
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
});

View file

@ -20,7 +20,7 @@ import fs from 'fs';
import path from 'path';
import util from 'util';
import os from 'os';
import type { Browser, BrowserContext, BrowserType, Page } from '../index';
import type { AndroidDevice, Browser, BrowserContext, BrowserType, Page } from '../index';
import { installCoverageHooks } from './coverage';
import { folio as httpFolio } from './http.fixtures';
import { folio as playwrightFolio } from './playwright.fixtures';
@ -45,6 +45,8 @@ type ModeParameters = {
};
type WorkerFixtures = {
toImpl: (rpcObject: any) => any;
androidDevice: AndroidDevice;
androidDeviceBrowser: BrowserContext;
};
type TestFixtures = {
createUserDataDir: () => Promise<string>;
@ -157,6 +159,27 @@ fixtures.testParametersPathSegment.override(async ({ browserName }, run) => {
await run(browserName);
});
fixtures.androidDevice.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);
await device.close();
}, { scope: 'worker' });
fixtures.androidDeviceBrowser.init(async ({ androidDevice }, runTest) => {
await runTest(await androidDevice.launchBrowser());
}, { scope: 'worker' });
if (process.env.PW_ANDROID_TESTS) {
fixtures.page.override(async ({ androidDeviceBrowser }, run) => {
for (const page of androidDeviceBrowser.pages())
await page.close();
run(await androidDeviceBrowser.newPage());
});
}
export const folio = fixtures.build();
folio.generateParametrizedTests(

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
import path from 'path';
it('should evaluate before anything else on the page', async ({ page, server }) => {
@ -27,7 +27,7 @@ it('should evaluate before anything else on the page', async ({ page, server })
});
it('should work with a path', async ({ page, server }) => {
await page.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') });
await page.addInitScript({ path: path.join(__dirname, '../assets/injectedfile.js') });
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
});
@ -38,74 +38,12 @@ it('should work with content', async ({ page, server }) => {
expect(await page.evaluate(() => window['result'])).toBe(123);
});
it('should throw without path and content', async ({ page, server }) => {
it('should throw without path and content', async ({ page }) => {
// @ts-expect-error foo is not a real option of addInitScript
const error = await page.addInitScript({ foo: 'bar' }).catch(e => e);
expect(error.message).toContain('Either path or content property must be present');
});
it('should work with browser context scripts', async ({ browser, server }) => {
const context = await browser.newContext();
await context.addInitScript(() => window['temp'] = 123);
const page = await context.newPage();
await page.addInitScript(() => window['injected'] = window['temp']);
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
await context.close();
});
it('should work without navigation, after all bindings', async ({ browser }) => {
const context = await browser.newContext();
let callback;
const promise = new Promise(f => callback = f);
await context.exposeFunction('woof', function(arg) {
callback(arg);
});
await context.addInitScript(() => {
window['woof']('hey');
window['temp'] = 123;
});
const page = await context.newPage();
expect(await page.evaluate(() => window['temp'])).toBe(123);
expect(await promise).toBe('hey');
await context.close();
});
it('should work without navigation in popup', async ({ browser }) => {
const context = await browser.newContext();
await context.addInitScript(() => window['temp'] = 123);
const page = await context.newPage();
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.evaluate(() => window['win'] = window.open()),
]);
expect(await popup.evaluate(() => window['temp'])).toBe(123);
await context.close();
});
it('should work with browser context scripts with a path', async ({ browser, server }) => {
const context = await browser.newContext();
await context.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') });
const page = await context.newPage();
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
await context.close();
});
it('should work with browser context scripts for already created pages', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await context.addInitScript(() => window['temp'] = 123);
await page.addInitScript(() => window['injected'] = window['temp']);
await page.goto(server.PREFIX + '/tamperable.html');
expect(await page.evaluate(() => window['result'])).toBe(123);
await context.close();
});
it('should support multiple scripts', async ({ page, server }) => {
await page.addInitScript(function() {
window['script1'] = 1;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
import path from 'path';
it('should throw an error if no options are provided', async ({page, server}) => {
@ -44,7 +44,7 @@ it('should work with a url and type=module', async ({page, server}) => {
it('should work with a path and type=module', async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
await page.addScriptTag({ path: path.join(__dirname, 'assets/es6/es6pathimport.js'), type: 'module' });
await page.addScriptTag({ path: path.join(__dirname, '../assets/es6/es6pathimport.js'), type: 'module' });
await page.waitForFunction('window.__es6injected');
expect(await page.evaluate(() => window['__es6injected'])).toBe(42);
});
@ -69,7 +69,7 @@ it('should throw an error if loading from url fail', async ({page, server}) => {
it('should work with a path', async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
const scriptHandle = await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
const scriptHandle = await page.addScriptTag({ path: path.join(__dirname, '../assets/injectedfile.js') });
expect(scriptHandle.asElement()).not.toBeNull();
expect(await page.evaluate(() => window['__injected'])).toBe(42);
});
@ -78,7 +78,7 @@ it('should include sourceURL when path is provided', (test, { browserName }) =>
test.skip(browserName === 'webkit');
}, async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
await page.addScriptTag({ path: path.join(__dirname, '../assets/injectedfile.js') });
const result = await page.evaluate(() => window['__injectedError'].stack);
expect(result).toContain(path.join('assets', 'injectedfile.js'));
});
@ -98,7 +98,9 @@ it('should throw when added with content to the CSP page', async ({page, server}
expect(error).toBeTruthy();
});
it('should throw when added with URL to the CSP page', async ({page, server}) => {
it('should throw when added with URL to the CSP page', test => {
test.skip(process.env.PW_ANDROID_TESTS);
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/csp.html');
let error = null;
await page.addScriptTag({ url: server.CROSS_PROCESS_PREFIX + '/injectedfile.js' }).catch(e => error = e);

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
import path from 'path';
it('should throw an error if no options are provided', async ({page, server}) => {
@ -49,14 +49,14 @@ it('should throw an error if loading from url fail', async ({page, server}) => {
it('should work with a path', async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
const styleHandle = await page.addStyleTag({ path: path.join(__dirname, 'assets/injectedstyle.css') });
const styleHandle = await page.addStyleTag({ path: path.join(__dirname, '../assets/injectedstyle.css') });
expect(styleHandle.asElement()).not.toBeNull();
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(255, 0, 0)');
});
it('should include sourceURL when path is provided', async ({page, server}) => {
await page.goto(server.EMPTY_PAGE);
await page.addStyleTag({ path: path.join(__dirname, 'assets/injectedstyle.css') });
await page.addStyleTag({ path: path.join(__dirname, '../assets/injectedstyle.css') });
const styleHandle = await page.$('style');
const styleContent = await page.evaluate(style => style.innerHTML, styleHandle);
expect(styleContent).toContain(path.join('assets', 'injectedstyle.css'));
@ -76,7 +76,9 @@ it('should throw when added with content to the CSP page', async ({page, server}
expect(error).toBeTruthy();
});
it('should throw when added with URL to the CSP page', async ({page, server}) => {
it('should throw when added with URL to the CSP page', test => {
test.skip(process.env.PW_ANDROID_TESTS);
}, async ({page, server}) => {
await page.goto(server.PREFIX + '/csp.html');
let error = null;
await page.addStyleTag({ url: server.CROSS_PROCESS_PREFIX + '/injectedstyle.css' }).catch(e => error = e);

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should check the box', async ({page}) => {
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
declare const renderComponent;
declare const e;

View file

@ -14,10 +14,11 @@
* limitations under the License.
*/
import { it } from './fixtures';
import { it } from '../fixtures';
it('should not hit scroll bar', (test, { browserName, platform }) => {
test.fixme(browserName === 'webkit' && platform === 'darwin');
test.skip(process.env.PW_ANDROID_TESTS);
}, async ({page, server}) => {
await page.setContent(`
<style>

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should avoid side effects after timeout', (test, { mode }) => {
test.skip(mode !== 'default');

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should timeout waiting for display:none to be gone', async ({page, server}) => {
await page.goto(server.PREFIX + '/input/button.html');

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should fail when element jumps during hit testing', (test, { mode }) => {
test.skip(mode !== 'default');

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should timeout waiting for stable position', async ({page, server}) => {
await page.goto(server.PREFIX + '/input/button.html');

View file

@ -15,8 +15,8 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { attachFrame } from './utils';
import { it, expect } from '../fixtures';
import { attachFrame } from '../utils';
async function giveItAChanceToClick(page) {
for (let i = 0; i < 5; i++)
@ -29,7 +29,7 @@ it('should click the button', async ({page, server}) => {
expect(await page.evaluate('result')).toBe('Clicked');
});
it('should click svg', async ({page, server}) => {
it('should click svg', async ({page}) => {
await page.setContent(`
<svg height="100" width="100">
<circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
@ -370,7 +370,9 @@ it('should click the button with em border with offset', async ({page, server, i
expect(await page.evaluate('offsetY')).toBe(isWebKit ? 12 * 2 + 10 : 10);
});
it('should click a very large button with offset', async ({page, server, isWebKit}) => {
it('should click a very large button with offset', test => {
test.skip(process.env.PWTESTREPORT);
}, async ({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => button.style.borderWidth = '8px');
await page.$eval('button', button => button.style.height = button.style.width = '2000px');
@ -381,7 +383,9 @@ it('should click a very large button with offset', async ({page, server, isWebKi
expect(await page.evaluate('offsetY')).toBe(isWebKit ? 1910 + 8 : 1910);
});
it('should click a button in scrolling container with offset', async ({page, server, isWebKit}) => {
it('should click a button in scrolling container with offset', test => {
test.skip(process.env.PWTESTREPORT);
}, async ({page, server, isWebKit}) => {
await page.goto(server.PREFIX + '/input/button.html');
await page.$eval('button', button => {
const container = document.createElement('div');

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should fire', async ({page, server}) => {
page.on('dialog', dialog => {

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should work', async ({page}) => {
const windowHandle = await page.evaluateHandle(() => window);

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { it, expect } from './fixtures';
import { it, expect } from '../fixtures';
it('should work', async ({ page }) => {
const result = await page.evaluate(() => 7 * 3);

View file

@ -29,6 +29,9 @@ const rejectSymbol = Symbol('reject callback');
const readFileAsync = util.promisify(fs.readFile.bind(fs));
const gzipAsync = util.promisify(zlib.gzip.bind(zlib));
const loopback = process.env.PW_ANDROID_TESTS ? '10.0.2.2' : 'localhost';
const cross_origin_loopback = process.env.PW_ANDROID_TESTS ? '10.0.2.2' : '127.0.0.1';
class TestServer {
/**
* @param {string} dirPath
@ -91,9 +94,9 @@ class TestServer {
const protocol = sslOptions ? 'https' : 'http';
this.PORT = port;
this.PREFIX = `${protocol}://localhost:${port}`;
this.CROSS_PROCESS_PREFIX = `${protocol}://127.0.0.1:${port}`;
this.EMPTY_PAGE = `${protocol}://localhost:${port}/empty.html`;
this.PREFIX = `${protocol}://${loopback}:${port}`;
this.CROSS_PROCESS_PREFIX = `${protocol}://${cross_origin_loopback}:${port}`;
this.EMPTY_PAGE = `${protocol}://${loopback}:${port}/empty.html`;
}
_onSocket(socket) {