chore: move chromium to src/server/chromium, enfore installer deps (#3582)

This commit is contained in:
Dmitry Gozman 2020-08-22 15:46:42 -07:00 committed by GitHub
parent 9fca63f8ec
commit f4e8f34c96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 147 additions and 131 deletions

View File

@ -6,7 +6,7 @@ utils/testrunner/examples/
lib/
*.js
src/generated/*
src/chromium/protocol.ts
src/server/chromium/protocol.ts
src/firefox/protocol.ts
src/webkit/protocol.ts
/types/*

View File

@ -16,7 +16,7 @@
import { CDPSessionChannel, CDPSessionInitializer } from '../protocol/channels';
import { ChannelOwner } from './channelOwner';
import { Protocol } from '../chromium/protocol';
import { Protocol } from '../server/chromium/protocol';
export class CDPSession extends ChannelOwner<CDPSessionChannel, CDPSessionInitializer> {
static from(cdpSession: CDPSessionChannel): CDPSession {

View File

@ -17,15 +17,12 @@
import * as crypto from 'crypto';
import { EventEmitter } from 'events';
import * as fs from 'fs';
import * as os from 'os';
import * as removeFolder from 'rimraf';
import * as util from 'util';
import * as types from './types';
import { Progress } from './progress';
const removeFolderAsync = util.promisify(removeFolder);
const readFileAsync = util.promisify(fs.readFile.bind(fs));
export type RegisteredListener = {
emitter: EventEmitter;
@ -112,43 +109,4 @@ class Helper {
}
}
export async function getUbuntuVersion(): Promise<string> {
if (os.platform() !== 'linux')
return '';
const osReleaseText = await readFileAsync('/etc/os-release', 'utf8').catch(e => '');
if (!osReleaseText)
return '';
return getUbuntuVersionInternal(osReleaseText);
}
export function getUbuntuVersionSync(): string {
if (os.platform() !== 'linux')
return '';
try {
const osReleaseText = fs.readFileSync('/etc/os-release', 'utf8');
if (!osReleaseText)
return '';
return getUbuntuVersionInternal(osReleaseText);
} catch (e) {
return '';
}
}
function getUbuntuVersionInternal(osReleaseText: string): string {
const fields = new Map();
for (const line of osReleaseText.split('\n')) {
const tokens = line.split('=');
const name = tokens.shift();
let value = tokens.join('=').trim();
if (value.startsWith('"') && value.endsWith('"'))
value = value.substring(1, value.length - 1);
if (!name)
continue;
fields.set(name.toLowerCase(), value);
}
if (!fields.get('name') || fields.get('name').toLowerCase() !== 'ubuntu')
return '';
return fields.get('version_id') || '';
}
export const helper = Helper;

View File

@ -18,7 +18,7 @@
import { execSync } from 'child_process';
import * as os from 'os';
import * as path from 'path';
import { getUbuntuVersionSync } from '../helper';
import { getUbuntuVersionSync } from '../utils/ubuntuVersion';
import { getFromENV } from '../utils/utils';
export type BrowserName = 'chromium'|'webkit'|'firefox';

View File

@ -19,7 +19,7 @@ import { Dispatcher, DispatcherScope, lookupDispatcher } from './dispatcher';
import { PageDispatcher, BindingCallDispatcher, WorkerDispatcher } from './pageDispatcher';
import * as channels from '../../protocol/channels';
import { RouteDispatcher, RequestDispatcher } from './networkDispatchers';
import { CRBrowserContext } from '../../chromium/crBrowser';
import { CRBrowserContext } from '../../server/chromium/crBrowser';
import { CDPSessionDispatcher } from './cdpSessionDispatcher';
export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channels.BrowserContextInitializer> implements channels.BrowserContextChannel {

View File

@ -19,7 +19,7 @@ import * as channels from '../../protocol/channels';
import { BrowserContextDispatcher } from './browserContextDispatcher';
import { CDPSessionDispatcher } from './cdpSessionDispatcher';
import { Dispatcher, DispatcherScope } from './dispatcher';
import { CRBrowser } from '../../chromium/crBrowser';
import { CRBrowser } from '../../server/chromium/crBrowser';
import { PageDispatcher } from './pageDispatcher';
export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserInitializer> implements channels.BrowserChannel {

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { CRSession, CRSessionEvents } from '../../chromium/crConnection';
import { CRSession, CRSessionEvents } from '../../server/chromium/crConnection';
import * as channels from '../../protocol/channels';
import { Dispatcher, DispatcherScope } from './dispatcher';

View File

@ -15,7 +15,6 @@
*/
import { Frame, NavigationEvent } from '../../frames';
import * as types from '../../types';
import * as channels from '../../protocol/channels';
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, existingDispatcher } from './dispatcher';
import { ElementHandleDispatcher, createHandle } from './elementHandlerDispatcher';
@ -38,11 +37,11 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameInitializer
loadStates: Array.from(frame._subtreeLifecycleEvents),
});
this._frame = frame;
frame.on(Frame.Events.AddLifecycle, (event: types.LifecycleEvent) => {
this._dispatchEvent('loadstate', { add: event });
frame.on(Frame.Events.AddLifecycle, lifecycleEvent => {
this._dispatchEvent('loadstate', { add: lifecycleEvent });
});
frame.on(Frame.Events.RemoveLifecycle, (event: types.LifecycleEvent) => {
this._dispatchEvent('loadstate', { remove: event });
frame.on(Frame.Events.RemoveLifecycle, lifecycleEvent => {
this._dispatchEvent('loadstate', { remove: lifecycleEvent });
});
frame.on(Frame.Events.Navigation, (event: NavigationEvent) => {
const params = { url: event.url, name: event.name, error: event.error ? event.error.message : undefined };

View File

@ -29,7 +29,7 @@ import { RequestDispatcher, ResponseDispatcher, RouteDispatcher } from './networ
import { serializeResult, parseArgument } from './jsHandleDispatcher';
import { ElementHandleDispatcher, createHandle } from './elementHandlerDispatcher';
import { FileChooser } from '../../fileChooser';
import { CRCoverage } from '../../chromium/crCoverage';
import { CRCoverage } from '../../server/chromium/crCoverage';
export class PageDispatcher extends Dispatcher<Page, channels.PageInitializer> implements channels.PageChannel {
private _page: Page;

View File

@ -17,17 +17,17 @@
import * as path from 'path';
import * as os from 'os';
import { CRBrowser } from '../chromium/crBrowser';
import { Env } from './processLauncher';
import { kBrowserCloseMessageId } from '../chromium/crConnection';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { BrowserTypeBase } from './browserType';
import { ConnectionTransport, ProtocolRequest } from '../transport';
import { BrowserDescriptor } from '../install/browserPaths';
import { CRDevTools } from '../chromium/crDevTools';
import { BrowserOptions } from '../browser';
import * as types from '../types';
import { isDebugMode, getFromENV } from '../utils/utils';
import { CRBrowser } from './crBrowser';
import { Env } from '../processLauncher';
import { kBrowserCloseMessageId } from './crConnection';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { BrowserTypeBase } from '../browserType';
import { ConnectionTransport, ProtocolRequest } from '../../transport';
import type { BrowserDescriptor } from '../../install/browserPaths';
import { CRDevTools } from './crDevTools';
import { BrowserOptions } from '../../browser';
import * as types from '../../types';
import { isDebugMode, getFromENV } from '../../utils/utils';
export class Chromium extends BrowserTypeBase {
private _devtools: CRDevTools | undefined;

View File

@ -17,9 +17,9 @@
import { CRSession } from './crConnection';
import { Protocol } from './protocol';
import * as dom from '../dom';
import * as accessibility from '../accessibility';
import * as types from '../types';
import * as dom from '../../dom';
import * as accessibility from '../../accessibility';
import * as types from '../../types';
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
const {nodes} = await client.send('Accessibility.getFullAXTree');

View File

@ -15,13 +15,13 @@
* limitations under the License.
*/
import { Browser, BrowserOptions } from '../browser';
import { assertBrowserContextIsNotOwned, BrowserContext, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
import { assert } from '../utils/utils';
import * as network from '../network';
import { Page, PageBinding, Worker } from '../page';
import { ConnectionTransport } from '../transport';
import * as types from '../types';
import { Browser, BrowserOptions } from '../../browser';
import { assertBrowserContextIsNotOwned, BrowserContext, validateBrowserContextOptions, verifyGeolocation } from '../../browserContext';
import { assert } from '../../utils/utils';
import * as network from '../../network';
import { Page, PageBinding, Worker } from '../../page';
import { ConnectionTransport } from '../../transport';
import * as types from '../../types';
import { ConnectionEvents, CRConnection, CRSession } from './crConnection';
import { CRPage } from './crPage';
import { readProtocolStream } from './crProtocolHelper';

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
import { assert } from '../utils/utils';
import { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport';
import { assert } from '../../utils/utils';
import { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../../transport';
import { Protocol } from './protocol';
import { EventEmitter } from 'events';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { debugLogger } from '../utils/debugLogger';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { debugLogger } from '../../utils/debugLogger';
export const ConnectionEvents = {
Disconnected: Symbol('ConnectionEvents.Disconnected')

View File

@ -16,11 +16,11 @@
*/
import { CRSession } from './crConnection';
import { helper, RegisteredListener } from '../helper';
import { helper, RegisteredListener } from '../../helper';
import { Protocol } from './protocol';
import * as types from '../types';
import * as sourceMap from '../utils/sourceMap';
import { assert } from '../utils/utils';
import * as types from '../../types';
import * as sourceMap from '../../utils/sourceMap';
import { assert } from '../../utils/utils';
export class CRCoverage {
private _jsCoverage: JSCoverage;

View File

@ -18,10 +18,10 @@
import { CRSession } from './crConnection';
import { getExceptionMessage, releaseObject } from './crProtocolHelper';
import { Protocol } from './protocol';
import * as js from '../javascript';
import * as sourceMap from '../utils/sourceMap';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { parseEvaluationResultValue } from '../common/utilityScriptSerializers';
import * as js from '../../javascript';
import * as sourceMap from '../../utils/sourceMap';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { parseEvaluationResultValue } from '../../common/utilityScriptSerializers';
export class CRExecutionContext implements js.ExecutionContextDelegate {
_client: CRSession;

View File

@ -15,11 +15,11 @@
* limitations under the License.
*/
import * as input from '../input';
import * as types from '../types';
import * as input from '../../input';
import * as types from '../../types';
import { CRSession } from './crConnection';
import { macEditingCommands } from '../macEditingCommands';
import { isString } from '../utils/utils';
import { macEditingCommands } from '../../macEditingCommands';
import { isString } from '../../utils/utils';
function toModifiersMask(modifiers: Set<types.KeyboardModifier>): number {
let mask = 0;

View File

@ -16,14 +16,14 @@
*/
import { CRSession } from './crConnection';
import { Page } from '../page';
import { helper, RegisteredListener } from '../helper';
import { Page } from '../../page';
import { helper, RegisteredListener } from '../../helper';
import { Protocol } from './protocol';
import * as network from '../network';
import * as frames from '../frames';
import * as types from '../types';
import * as network from '../../network';
import * as frames from '../../frames';
import * as types from '../../types';
import { CRPage } from './crPage';
import { assert, headersObjectToArray } from '../utils/utils';
import { assert, headersObjectToArray } from '../../utils/utils';
export class CRNetworkManager {
private _client: CRSession;

View File

@ -15,28 +15,28 @@
* limitations under the License.
*/
import * as dom from '../dom';
import * as frames from '../frames';
import { helper, RegisteredListener } from '../helper';
import * as network from '../network';
import * as dom from '../../dom';
import * as frames from '../../frames';
import { helper, RegisteredListener } from '../../helper';
import * as network from '../../network';
import { CRSession, CRConnection, CRSessionEvents } from './crConnection';
import { CRExecutionContext } from './crExecutionContext';
import { CRNetworkManager } from './crNetworkManager';
import { Page, Worker, PageBinding } from '../page';
import { Page, Worker, PageBinding } from '../../page';
import { Protocol } from './protocol';
import { toConsoleMessageLocation, exceptionToError, releaseObject } from './crProtocolHelper';
import * as dialog from '../dialog';
import { PageDelegate } from '../page';
import * as dialog from '../../dialog';
import { PageDelegate } from '../../page';
import { RawMouseImpl, RawKeyboardImpl } from './crInput';
import { getAccessibilityTree } from './crAccessibility';
import { CRCoverage } from './crCoverage';
import { CRPDF } from './crPdf';
import { CRBrowserContext } from './crBrowser';
import * as types from '../types';
import { ConsoleMessage } from '../console';
import * as sourceMap from '../utils/sourceMap';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { assert, headersArrayToObject } from '../utils/utils';
import * as types from '../../types';
import { ConsoleMessage } from '../../console';
import * as sourceMap from '../../utils/sourceMap';
import { rewriteErrorMessage } from '../../utils/stackTrace';
import { assert, headersArrayToObject } from '../../utils/utils';
const UTILITY_WORLD_NAME = '__playwright_utility_world__';

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import { assert } from '../utils/utils';
import * as types from '../types';
import { assert } from '../../utils/utils';
import * as types from '../../types';
import { CRSession } from './crConnection';
import { readProtocolStream } from './crProtocolHelper';

View File

@ -19,8 +19,8 @@ import { CRSession } from './crConnection';
import { Protocol } from './protocol';
import * as fs from 'fs';
import * as util from 'util';
import * as types from '../types';
import { mkdirIfNeeded } from '../utils/utils';
import * as types from '../../types';
import { mkdirIfNeeded } from '../../utils/utils';
export function getExceptionMessage(exceptionDetails: Protocol.Runtime.ExceptionDetails): string {
if (exceptionDetails.exception)

View File

@ -15,9 +15,9 @@
*/
import * as path from 'path';
import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
import { CRConnection, CRSession } from '../chromium/crConnection';
import { CRExecutionContext } from '../chromium/crExecutionContext';
import { CRBrowser, CRBrowserContext } from './chromium/crBrowser';
import { CRConnection, CRSession } from './chromium/crConnection';
import { CRExecutionContext } from './chromium/crExecutionContext';
import * as js from '../javascript';
import { Page } from '../page';
import { TimeoutSettings } from '../utils/timeoutSettings';

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Chromium } from './chromium';
import { Chromium } from './chromium/chromium';
import { WebKit } from './webkit';
import { Firefox } from './firefox';
import { selectors } from '../selectors';

View File

@ -18,7 +18,7 @@ import * as util from 'util';
import * as path from 'path';
import * as os from 'os';
import { spawn } from 'child_process';
import { getUbuntuVersion } from '../helper';
import { getUbuntuVersion } from '../utils/ubuntuVersion';
import { linuxLddDirectories, windowsExeAndDllDirectories, BrowserDescriptor } from '../install/browserPaths.js';
const accessAsync = util.promisify(fs.access.bind(fs));

View File

@ -0,0 +1,61 @@
/**
* Copyright 2017 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 * as fs from 'fs';
import * as os from 'os';
import * as util from 'util';
const readFileAsync = util.promisify(fs.readFile.bind(fs));
export async function getUbuntuVersion(): Promise<string> {
if (os.platform() !== 'linux')
return '';
const osReleaseText = await readFileAsync('/etc/os-release', 'utf8').catch(e => '');
if (!osReleaseText)
return '';
return getUbuntuVersionInternal(osReleaseText);
}
export function getUbuntuVersionSync(): string {
if (os.platform() !== 'linux')
return '';
try {
const osReleaseText = fs.readFileSync('/etc/os-release', 'utf8');
if (!osReleaseText)
return '';
return getUbuntuVersionInternal(osReleaseText);
} catch (e) {
return '';
}
}
function getUbuntuVersionInternal(osReleaseText: string): string {
const fields = new Map();
for (const line of osReleaseText.split('\n')) {
const tokens = line.split('=');
const name = tokens.shift();
let value = tokens.join('=').trim();
if (value.startsWith('"') && value.endsWith('"'))
value = value.substring(1, value.length - 1);
if (!name)
continue;
fields.set(name.toLowerCase(), value);
}
if (!fields.get('name') || fields.get('name').toLowerCase() !== 'ubuntu')
return '';
return fields.get('version_id') || '';
}

View File

@ -52,18 +52,20 @@ async function checkDeps() {
function allowImport(from, to) {
from = from.substring(from.indexOf('src' + path.sep)).replace(/\\/g, '/');
to = to.substring(to.indexOf('src' + path.sep)).replace(/\\/g, '/') + '.ts';
const toDirectory = to.substring(0, to.lastIndexOf('/') + 1);
while (from.lastIndexOf('/') !== -1) {
from = from.substring(0, from.lastIndexOf('/'));
const allowed = DEPS.get(from + '/');
if (!allowed)
continue;
for (const prefix of allowed) {
if (to.startsWith(prefix))
for (const dep of allowed) {
if (to === dep || toDirectory === dep )
return true;
}
return false;
}
return false;
// Allow everything else for now.
return true;
}
}
@ -71,8 +73,8 @@ const DEPS = new Map([
['src/utils/', ['src/utils/']],
['src/common/', ['src/common/']],
['src/protocol/', ['src/protocol/', 'src/utils/']],
['src/client/', ['src/client/', 'src/utils/', 'src/protocol/', 'src/chromium/protocol.ts']],
['src/', ['src/']], // Allow everything else for now.
['src/install/', ['src/install/', 'src/utils/']],
['src/client/', ['src/client/', 'src/utils/', 'src/protocol/', 'src/server/chromium/protocol.ts']],
]);
checkDeps();

View File

@ -31,7 +31,7 @@ let documentation;
const typesDir = path.join(PROJECT_DIR, 'types');
if (!fs.existsSync(typesDir))
fs.mkdirSync(typesDir)
fs.writeFileSync(path.join(typesDir, 'protocol.d.ts'), fs.readFileSync(path.join(PROJECT_DIR, 'src', 'chromium', 'protocol.ts')), 'utf8');
fs.writeFileSync(path.join(typesDir, 'protocol.d.ts'), fs.readFileSync(path.join(PROJECT_DIR, 'src', 'server', 'chromium', 'protocol.ts')), 'utf8');
const browser = await chromium.launch();
const page = await browser.newPage();
const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));

View File

@ -15,15 +15,11 @@ async function generateProtocol(name, executablePath) {
}
async function generateChromiumProtocol(executablePath) {
const outputPath = path.join(__dirname, '..', '..', 'src', 'chromium', 'protocol.ts');
const outputPath = path.join(__dirname, '..', '..', 'src', 'server', 'chromium', 'protocol.ts');
process.env.PLAYWRIGHT_CHROMIUM_DEBUG_PORT = '9339';
const playwright = require('../../index').chromium;
const defaultArgs = playwright._defaultArgs.bind(playwright);
playwright._defaultArgs = (...args) => {
const result = defaultArgs(...args);
result.push('--remote-debugging-port=9339');
return result;
};
const browser = await playwright.launch({ executablePath });
delete process.env.PLAYWRIGHT_CHROMIUM_DEBUG_PORT;
const page = await browser.newPage();
await page.goto(`http://localhost:9339/json/protocol`);
const json = JSON.parse(await page.evaluate(() => document.documentElement.innerText));