mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore(chromium): resize browser frame when emulating viewport (#1924)
This commit is contained in:
parent
fa59372248
commit
2fcc2b5552
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "playwright-core",
|
"name": "playwright-core",
|
||||||
"version": "0.13.0-post",
|
"version": "0.14.0-post",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -46,10 +46,11 @@ export class CRBrowser extends BrowserBase {
|
|||||||
private _tracingRecording = false;
|
private _tracingRecording = false;
|
||||||
private _tracingPath: string | null = '';
|
private _tracingPath: string | null = '';
|
||||||
private _tracingClient: CRSession | undefined;
|
private _tracingClient: CRSession | undefined;
|
||||||
|
readonly _isHeadful: boolean;
|
||||||
|
|
||||||
static async connect(transport: ConnectionTransport, isPersistent: boolean, logger: InnerLogger, slowMo?: number): Promise<CRBrowser> {
|
static async connect(transport: ConnectionTransport, isPersistent: boolean, logger: InnerLogger, options: { slowMo?: number, headless?: boolean } = {}): Promise<CRBrowser> {
|
||||||
const connection = new CRConnection(SlowMoTransport.wrap(transport, slowMo), logger);
|
const connection = new CRConnection(SlowMoTransport.wrap(transport, options.slowMo), logger);
|
||||||
const browser = new CRBrowser(connection, logger, isPersistent);
|
const browser = new CRBrowser(connection, logger, isPersistent, !options.headless);
|
||||||
const session = connection.rootSession;
|
const session = connection.rootSession;
|
||||||
if (!isPersistent) {
|
if (!isPersistent) {
|
||||||
await session.send('Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: true, flatten: true });
|
await session.send('Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: true, flatten: true });
|
||||||
@ -84,13 +85,14 @@ export class CRBrowser extends BrowserBase {
|
|||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(connection: CRConnection, logger: InnerLogger, isPersistent: boolean) {
|
constructor(connection: CRConnection, logger: InnerLogger, isPersistent: boolean, isHeadful: boolean) {
|
||||||
super(logger);
|
super(logger);
|
||||||
this._connection = connection;
|
this._connection = connection;
|
||||||
this._session = this._connection.rootSession;
|
this._session = this._connection.rootSession;
|
||||||
|
|
||||||
if (isPersistent)
|
if (isPersistent)
|
||||||
this._defaultContext = new CRBrowserContext(this, null, validateBrowserContextOptions({}));
|
this._defaultContext = new CRBrowserContext(this, null, validateBrowserContextOptions({}));
|
||||||
|
this._isHeadful = isHeadful;
|
||||||
this._connection.on(ConnectionEvents.Disconnected, () => {
|
this._connection.on(ConnectionEvents.Disconnected, () => {
|
||||||
for (const context of this._contexts.values())
|
for (const context of this._contexts.values())
|
||||||
context._browserClosed();
|
context._browserClosed();
|
||||||
@ -141,7 +143,7 @@ export class CRBrowser extends BrowserBase {
|
|||||||
assert(!this._serviceWorkers.has(targetInfo.targetId), 'Duplicate target ' + targetInfo.targetId);
|
assert(!this._serviceWorkers.has(targetInfo.targetId), 'Duplicate target ' + targetInfo.targetId);
|
||||||
|
|
||||||
if (targetInfo.type === 'background_page') {
|
if (targetInfo.type === 'background_page') {
|
||||||
const backgroundPage = new CRPage(session, targetInfo.targetId, context, null);
|
const backgroundPage = new CRPage(session, targetInfo.targetId, context, null, false);
|
||||||
this._backgroundPages.set(targetInfo.targetId, backgroundPage);
|
this._backgroundPages.set(targetInfo.targetId, backgroundPage);
|
||||||
backgroundPage.pageOrError().then(() => {
|
backgroundPage.pageOrError().then(() => {
|
||||||
context!.emit(Events.CRBrowserContext.BackgroundPage, backgroundPage._page);
|
context!.emit(Events.CRBrowserContext.BackgroundPage, backgroundPage._page);
|
||||||
@ -151,7 +153,7 @@ export class CRBrowser extends BrowserBase {
|
|||||||
|
|
||||||
if (targetInfo.type === 'page') {
|
if (targetInfo.type === 'page') {
|
||||||
const opener = targetInfo.openerId ? this._crPages.get(targetInfo.openerId) || null : null;
|
const opener = targetInfo.openerId ? this._crPages.get(targetInfo.openerId) || null : null;
|
||||||
const crPage = new CRPage(session, targetInfo.targetId, context, opener);
|
const crPage = new CRPage(session, targetInfo.targetId, context, opener, this._isHeadful);
|
||||||
this._crPages.set(targetInfo.targetId, crPage);
|
this._crPages.set(targetInfo.targetId, crPage);
|
||||||
if (opener && opener._initializedPage) {
|
if (opener && opener._initializedPage) {
|
||||||
for (const signalBarrier of opener._initializedPage._frameManager._signalBarriers)
|
for (const signalBarrier of opener._initializedPage._frameManager._signalBarriers)
|
||||||
|
@ -39,6 +39,7 @@ import { ConsoleMessage } from '../console';
|
|||||||
import { NotConnectedError } from '../errors';
|
import { NotConnectedError } from '../errors';
|
||||||
import { logError } from '../logger';
|
import { logError } from '../logger';
|
||||||
|
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
|
|
||||||
export class CRPage implements PageDelegate {
|
export class CRPage implements PageDelegate {
|
||||||
@ -55,7 +56,7 @@ export class CRPage implements PageDelegate {
|
|||||||
private readonly _pagePromise: Promise<Page | Error>;
|
private readonly _pagePromise: Promise<Page | Error>;
|
||||||
_initializedPage: Page | null = null;
|
_initializedPage: Page | null = null;
|
||||||
|
|
||||||
constructor(client: CRSession, targetId: string, browserContext: CRBrowserContext, opener: CRPage | null) {
|
constructor(client: CRSession, targetId: string, browserContext: CRBrowserContext, opener: CRPage | null, hasUIWindow: boolean) {
|
||||||
this._targetId = targetId;
|
this._targetId = targetId;
|
||||||
this._opener = opener;
|
this._opener = opener;
|
||||||
this.rawKeyboard = new RawKeyboardImpl(client);
|
this.rawKeyboard = new RawKeyboardImpl(client);
|
||||||
@ -67,7 +68,7 @@ export class CRPage implements PageDelegate {
|
|||||||
this._mainFrameSession = new FrameSession(this, client, targetId);
|
this._mainFrameSession = new FrameSession(this, client, targetId);
|
||||||
this._sessions.set(targetId, this._mainFrameSession);
|
this._sessions.set(targetId, this._mainFrameSession);
|
||||||
client.once(CRSessionEvents.Disconnected, () => this._page._didDisconnect());
|
client.once(CRSessionEvents.Disconnected, () => this._page._didDisconnect());
|
||||||
this._pagePromise = this._mainFrameSession._initialize().then(() => this._initializedPage = this._page).catch(e => e);
|
this._pagePromise = this._mainFrameSession._initialize(hasUIWindow).then(() => this._initializedPage = this._page).catch(e => e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _forAllFrameSessions(cb: (frame: FrameSession) => Promise<any>) {
|
private async _forAllFrameSessions(cb: (frame: FrameSession) => Promise<any>) {
|
||||||
@ -97,7 +98,7 @@ export class CRPage implements PageDelegate {
|
|||||||
this._page._frameManager.removeChildFramesRecursively(frame);
|
this._page._frameManager.removeChildFramesRecursively(frame);
|
||||||
const frameSession = new FrameSession(this, session, targetId);
|
const frameSession = new FrameSession(this, session, targetId);
|
||||||
this._sessions.set(targetId, frameSession);
|
this._sessions.set(targetId, frameSession);
|
||||||
frameSession._initialize().catch(e => e);
|
frameSession._initialize(false).catch(e => e);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFrameSession(targetId: Protocol.Target.TargetID) {
|
removeFrameSession(targetId: Protocol.Target.TargetID) {
|
||||||
@ -319,6 +320,7 @@ class FrameSession {
|
|||||||
private _firstNonInitialNavigationCommittedPromise: Promise<void>;
|
private _firstNonInitialNavigationCommittedPromise: Promise<void>;
|
||||||
private _firstNonInitialNavigationCommittedFulfill = () => {};
|
private _firstNonInitialNavigationCommittedFulfill = () => {};
|
||||||
private _firstNonInitialNavigationCommittedReject = (e: Error) => {};
|
private _firstNonInitialNavigationCommittedReject = (e: Error) => {};
|
||||||
|
private _windowId: number | undefined;
|
||||||
|
|
||||||
constructor(crPage: CRPage, client: CRSession, targetId: string) {
|
constructor(crPage: CRPage, client: CRSession, targetId: string) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
@ -364,7 +366,11 @@ class FrameSession {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
async _initialize(hasUIWindow: boolean) {
|
||||||
|
if (hasUIWindow) {
|
||||||
|
const { windowId } = await this._client.send('Browser.getWindowForTarget');
|
||||||
|
this._windowId = windowId;
|
||||||
|
}
|
||||||
let lifecycleEventsEnabled: Promise<any>;
|
let lifecycleEventsEnabled: Promise<any>;
|
||||||
if (!this._isMainFrame())
|
if (!this._isMainFrame())
|
||||||
this._addSessionListeners();
|
this._addSessionListeners();
|
||||||
@ -696,6 +702,20 @@ class FrameSession {
|
|||||||
screenOrientation: isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' },
|
screenOrientation: isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' },
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
if (this._windowId) {
|
||||||
|
let insets = { width: 24, height: 88 };
|
||||||
|
if (process.platform === 'win32')
|
||||||
|
insets = { width: 16, height: 88 };
|
||||||
|
else if (process.platform === 'linux')
|
||||||
|
insets = { width: 8, height: 85 };
|
||||||
|
else if (process.platform === 'darwin')
|
||||||
|
insets = { width: 2, height: 80 };
|
||||||
|
|
||||||
|
promises.push(this._client.send('Browser.setWindowBounds', {
|
||||||
|
windowId: this._windowId,
|
||||||
|
bounds: { width: viewport.width + insets.width, height: viewport.height + insets.height }
|
||||||
|
}));
|
||||||
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ export class Chromium implements BrowserType<CRBrowser> {
|
|||||||
async launch(options: LaunchOptions = {}): Promise<CRBrowser> {
|
async launch(options: LaunchOptions = {}): Promise<CRBrowser> {
|
||||||
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
||||||
const { browserServer, transport, downloadsPath, logger } = await this._launchServer(options, 'local');
|
const { browserServer, transport, downloadsPath, logger } = await this._launchServer(options, 'local');
|
||||||
const browser = await CRBrowser.connect(transport!, false, logger, options.slowMo);
|
const browser = await CRBrowser.connect(transport!, false, logger, options);
|
||||||
browser._ownedServer = browserServer;
|
browser._ownedServer = browserServer;
|
||||||
browser._downloadsPath = downloadsPath;
|
browser._downloadsPath = downloadsPath;
|
||||||
return browser;
|
return browser;
|
||||||
@ -60,14 +60,10 @@ export class Chromium implements BrowserType<CRBrowser> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async launchPersistentContext(userDataDir: string, options: LaunchOptions = {}): Promise<BrowserContext> {
|
async launchPersistentContext(userDataDir: string, options: LaunchOptions = {}): Promise<BrowserContext> {
|
||||||
const {
|
|
||||||
timeout = 30000,
|
|
||||||
slowMo = 0,
|
|
||||||
} = options;
|
|
||||||
const { transport, browserServer, logger } = await this._launchServer(options, 'persistent', userDataDir);
|
const { transport, browserServer, logger } = await this._launchServer(options, 'persistent', userDataDir);
|
||||||
const browser = await CRBrowser.connect(transport!, true, logger, slowMo);
|
const browser = await CRBrowser.connect(transport!, true, logger, options);
|
||||||
browser._ownedServer = browserServer;
|
browser._ownedServer = browserServer;
|
||||||
await helper.waitWithTimeout(browser._firstPagePromise, 'first page', timeout);
|
await helper.waitWithTimeout(browser._firstPagePromise, 'first page', options.timeout || 30000);
|
||||||
return browser._defaultContext!;
|
return browser._defaultContext!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +133,7 @@ export class Chromium implements BrowserType<CRBrowser> {
|
|||||||
|
|
||||||
async connect(options: ConnectOptions): Promise<CRBrowser> {
|
async connect(options: ConnectOptions): Promise<CRBrowser> {
|
||||||
return await WebSocketTransport.connect(options.wsEndpoint, transport => {
|
return await WebSocketTransport.connect(options.wsEndpoint, transport => {
|
||||||
return CRBrowser.connect(transport, false, new RootLogger(options.logger), options.slowMo);
|
return CRBrowser.connect(transport, false, new RootLogger(options.logger), options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user