Skip to content

Commit 8695e34

Browse files
committed
chore(dashboard): remove devtools capability
1 parent 1ae6dd9 commit 8695e34

File tree

9 files changed

+42
-195
lines changed

9 files changed

+42
-195
lines changed

packages/dashboard/src/dashboard.tsx

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ import './dashboard.css';
1919
import { navigate } from './index';
2020
import { DashboardClient } from './dashboardClient';
2121
import { asLocator } from '@isomorphic/locatorGenerators';
22-
import { SplitView } from '@web/components/splitView';
23-
import { ChevronLeftIcon, ChevronRightIcon, CloseIcon, PlusIcon, ReloadIcon, PickLocatorIcon, InspectorPanelIcon } from './icons';
22+
import { ChevronLeftIcon, ChevronRightIcon, CloseIcon, PlusIcon, ReloadIcon, PickLocatorIcon } from './icons';
2423
import { SettingsButton } from './settingsView';
2524

2625
import type { DashboardClientChannel } from './dashboardClient';
@@ -43,7 +42,6 @@ export const Dashboard: React.FC<{ wsUrl?: string }> = ({ wsUrl }) => {
4342
const [tabs, setTabs] = React.useState<Tab[] | null>(null);
4443
const [url, setUrl] = React.useState('');
4544
const [frame, setFrame] = React.useState<DashboardChannelEvents['frame']>();
46-
const [showInspector, setShowInspector] = React.useState(false);
4745
const [pickingTabId, setPickingTabId] = React.useState<string | null>(null);
4846
const [locatorToast, setLocatorToast] = React.useState<{ text: string; timer: ReturnType<typeof setTimeout> }>();
4947

@@ -103,7 +101,6 @@ export const Dashboard: React.FC<{ wsUrl?: string }> = ({ wsUrl }) => {
103101
setChannel(undefined);
104102
setInteractive(false);
105103
setPickingTabId(null);
106-
setShowInspector(false);
107104
};
108105

109106
return () => {
@@ -272,7 +269,6 @@ export const Dashboard: React.FC<{ wsUrl?: string }> = ({ wsUrl }) => {
272269
onClick={() => {
273270
channel?.cancelPickLocator();
274271
setPickingTabId(null);
275-
setShowInspector(false);
276272
setInteractive(false);
277273
}}
278274
>
@@ -334,66 +330,40 @@ export const Dashboard: React.FC<{ wsUrl?: string }> = ({ wsUrl }) => {
334330
>
335331
<PickLocatorIcon />
336332
</button>
337-
{selectedTab?.inspectorUrl && (
338-
<button
339-
className={'nav-btn' + (showInspector ? ' active-toggle' : '')}
340-
title='Chrome DevTools'
341-
aria-pressed={showInspector}
342-
disabled={!channel}
343-
onClick={() => {
344-
setInteractive(true);
345-
setShowInspector(!showInspector);
346-
}}
347-
>
348-
<InspectorPanelIcon />
349-
</button>
350-
)}
351333
</div>
352334

353335
{/* Viewport */}
354336
<div className='viewport-wrapper'>
355-
<SplitView
356-
orientation='horizontal'
357-
sidebarSize={500}
358-
minSidebarSize={300}
359-
settingName='devtoolsInspector'
360-
sidebarHidden={!showInspector || !selectedTab?.inspectorUrl}
361-
main={<div className='viewport-main'>
362-
<div
363-
ref={screenRef}
364-
className='screen'
365-
tabIndex={0}
366-
style={{ display: frame ? '' : 'none' }}
367-
onMouseDown={onScreenMouseDown}
368-
onMouseUp={onScreenMouseUp}
369-
onMouseMove={onScreenMouseMove}
370-
onWheel={onScreenWheel}
371-
onKeyDown={onScreenKeyDown}
372-
onKeyUp={onScreenKeyUp}
373-
onContextMenu={e => e.preventDefault()}
374-
>
375-
<img
376-
ref={displayRef}
377-
id='display'
378-
className='display'
379-
alt='screencast'
380-
src={frame ? 'data:image/jpeg;base64,' + frame.data : undefined}
381-
/>
382-
{locatorToast
383-
? <div className='screen-toast visible'>Copied: <code>{locatorToast.text}</code></div>
384-
: picking
385-
? <div className='screen-toast visible'>Click an element to pick its locator</div>
386-
: null
387-
}
388-
</div>
389-
{overlayText && <div className={'screen-overlay' + (frame ? ' has-frame' : '')}><span>{overlayText}</span></div>}
390-
</div>}
391-
sidebar={<iframe
392-
className='inspector-frame'
393-
src={selectedTab?.inspectorUrl || ''}
394-
title='Chrome DevTools'
395-
/>}
396-
/>
337+
<div className='viewport-main'>
338+
<div
339+
ref={screenRef}
340+
className='screen'
341+
tabIndex={0}
342+
style={{ display: frame ? '' : 'none' }}
343+
onMouseDown={onScreenMouseDown}
344+
onMouseUp={onScreenMouseUp}
345+
onMouseMove={onScreenMouseMove}
346+
onWheel={onScreenWheel}
347+
onKeyDown={onScreenKeyDown}
348+
onKeyUp={onScreenKeyUp}
349+
onContextMenu={e => e.preventDefault()}
350+
>
351+
<img
352+
ref={displayRef}
353+
id='display'
354+
className='display'
355+
alt='screencast'
356+
src={frame ? 'data:image/jpeg;base64,' + frame.data : undefined}
357+
/>
358+
{locatorToast
359+
? <div className='screen-toast visible'>Copied: <code>{locatorToast.text}</code></div>
360+
: picking
361+
? <div className='screen-toast visible'>Click an element to pick its locator</div>
362+
: null
363+
}
364+
</div>
365+
{overlayText && <div className={'screen-overlay' + (frame ? ' has-frame' : '')}><span>{overlayText}</span></div>}
366+
</div>
397367
</div>
398368
</div>);
399369
};

packages/dashboard/src/dashboardChannel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
export type Tab = { pageId: string; title: string; url: string; selected: boolean; inspectorUrl?: string };
17+
export type Tab = { pageId: string; title: string; url: string; selected: boolean };
1818

1919
export type DashboardChannelEvents = {
2020
frame: { data: string; viewportWidth: number; viewportHeight: number };

packages/playwright-core/src/server/android/android.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ export class AndroidDevice extends SdkObject {
299299
'--disable-fre',
300300
'--no-default-browser-check',
301301
`--remote-debugging-socket-name=${socketName}`,
302-
...chromiumSwitches(undefined, undefined, true),
302+
...chromiumSwitches({ android: true }),
303303
...this._innerDefaultArgs(options)
304304
];
305305
return chromeArguments;

packages/playwright-core/src/server/bidi/bidiChromium.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export class BidiChromium extends BrowserType {
114114
throw new Error('Playwright manages remote debugging connection itself.');
115115
if (args.find(arg => !arg.startsWith('-')))
116116
throw new Error('Arguments can not specify page to be opened');
117-
const chromeArguments = [...chromiumSwitches(options.assistantMode)];
117+
const chromeArguments = [...chromiumSwitches()];
118118

119119
if (os.platform() === 'darwin') {
120120
// See https://issues.chromium.org/issues/40277080

packages/playwright-core/src/server/chromium/chromium.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ export class Chromium extends BrowserType {
330330
throw new Error('Playwright manages remote debugging connection itself.');
331331
if (args.find(arg => !arg.startsWith('-')))
332332
throw new Error('Arguments can not specify page to be opened');
333-
const chromeArguments = [...chromiumSwitches(options.assistantMode, options.channel)];
333+
const chromeArguments = [...chromiumSwitches()];
334334

335335
// See https://issues.chromium.org/issues/40277080
336336
chromeArguments.push('--enable-unsafe-swiftshader');

packages/playwright-core/src/server/chromium/chromiumSwitches.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
// No dependencies as it is used from the Electron loader.
1919

20-
const disabledFeatures = (assistantMode?: boolean) => [
20+
const disabledFeatures = [
2121
// See https://github.com/microsoft/playwright/issues/14047
2222
'AvoidUnnecessaryBeforeUnloadCheckSync',
2323
// See https://github.com/microsoft/playwright/issues/38568
@@ -44,14 +44,13 @@ const disabledFeatures = (assistantMode?: boolean) => [
4444
'RenderDocument',
4545
// Prevents downloading optimization hints on startup.
4646
'OptimizationHints',
47-
assistantMode ? 'AutomationControlled' : '',
4847
// Disables forced sign-in in Edge.
4948
'msForceBrowserSignIn',
5049
// Disables updating the preferred version in LaunchServices preferences on mac.
5150
'msEdgeUpdateLaunchServicesPreferredVersion',
5251
].filter(Boolean);
5352

54-
export const chromiumSwitches = (assistantMode?: boolean, channel?: string, android?: boolean) => [
53+
export const chromiumSwitches = (options?: { android?: boolean }) => [
5554
'--disable-field-trial-config', // https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
5655
'--disable-background-networking',
5756
'--disable-background-timer-throttling',
@@ -66,7 +65,7 @@ export const chromiumSwitches = (assistantMode?: boolean, channel?: string, andr
6665
'--disable-dev-shm-usage',
6766
'--disable-edgeupdater', // Disables Edge-specific updater on mac.
6867
'--disable-extensions',
69-
'--disable-features=' + disabledFeatures(assistantMode).join(','),
68+
'--disable-features=' + disabledFeatures.join(','),
7069
process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? '' : '--enable-features=CDPScreenshotNewSurface',
7170
'--allow-pre-commit-input',
7271
'--disable-hang-monitor',
@@ -88,12 +87,11 @@ export const chromiumSwitches = (assistantMode?: boolean, channel?: string, andr
8887
'--unsafely-disable-devtools-self-xss-warnings',
8988
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
9089
'--edge-skip-compat-layer-relaunch',
91-
assistantMode ? '' : '--enable-automation',
9290
// This disables Chrome for Testing infobar that is visible in the persistent context.
9391
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
9492
'--disable-infobars',
9593
// Less annoying popups.
9694
'--disable-search-engine-choice-screen',
9795
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
98-
android ? '' : '--disable-sync',
96+
options?.android ? '' : '--disable-sync',
9997
].filter(Boolean);

packages/playwright-core/src/tools/dashboard/dashboardApp.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { gracefullyProcessExitDoNotHang } from '@utils/processLauncher';
2525
import { libPath } from '../../package';
2626
import { playwright } from '../../inprocess';
2727
import { findChromiumChannelBestEffort, registryDirectory } from '../../server/registry/index';
28-
import { CDPConnection, DashboardConnection } from './dashboardController';
28+
import { DashboardConnection } from './dashboardController';
2929
import { serverRegistry } from '../../serverRegistry';
3030
import { connectToBrowserAcrossVersions } from '../utils/connect';
3131
import { createClientInfo } from '../cli-client/registry';
@@ -147,21 +147,7 @@ async function innerOpenDashboardApp(): Promise<api.Page> {
147147
throw new Error('Unsupported WebSocket URL: ' + url.toString());
148148
const browserDescriptor = serverRegistry.readDescriptor(guid);
149149

150-
const cdpPageId = url.searchParams.get('cdpPageId');
151-
if (cdpPageId) {
152-
const connection = browserGuidToDashboardConnection.get(guid);
153-
if (!connection)
154-
throw new Error('CDP connection not found for session: ' + guid);
155-
const page = connection.pageForId(cdpPageId);
156-
if (!page)
157-
throw new Error('Page not found for page ID: ' + cdpPageId);
158-
return new CDPConnection(page);
159-
}
160-
161-
const cdpUrl = new URL(httpServer.urlPrefix('human-readable'));
162-
cdpUrl.pathname = httpServer.wsGuid()!;
163-
cdpUrl.searchParams.set('guid', guid);
164-
const connection = new DashboardConnection(browserDescriptor, cdpUrl, () => browserGuidToDashboardConnection.delete(guid));
150+
const connection = new DashboardConnection(browserDescriptor, () => browserGuidToDashboardConnection.delete(guid));
165151
browserGuidToDashboardConnection.set(guid, connection);
166152
return connection;
167153
});

packages/playwright-core/src/tools/dashboard/dashboardController.ts

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,14 @@ export class DashboardConnection implements Transport, DashboardChannel {
3636
private _eventListeners = new Map<string, Set<Function>>();
3737

3838
private _browserDescriptor: BrowserDescriptor;
39-
private _cdpUrl: URL;
4039
private _onclose: () => void;
4140

4241
private _initPromise?: Promise<void>;
4342
private _context!: api.BrowserContext;
4443
private _browser?: api.Browser;
4544

46-
constructor(browserDescriptor: BrowserDescriptor, cdpUrl: URL, onclose: () => void) {
45+
constructor(browserDescriptor: BrowserDescriptor, onclose: () => void) {
4746
this._browserDescriptor = browserDescriptor;
48-
this._cdpUrl = cdpUrl;
4947
this._onclose = onclose;
5048
}
5149

@@ -242,51 +240,22 @@ export class DashboardConnection implements Transport, DashboardChannel {
242240

243241
private async _tabList(): Promise<Tab[]> {
244242
const pages = this._context.pages();
245-
if (pages.length === 0)
246-
return [];
247-
const devtoolsUrl = await this._devtoolsUrl(pages[0]);
248243
return await Promise.all(pages.map(async page => {
249244
const title = await page.title();
250245
return {
251246
pageId: this._pageId(page),
252247
title,
253248
url: page.url(),
254249
selected: page === this.selectedPage,
255-
inspectorUrl: devtoolsUrl ? await this._pageInspectorUrl(page, devtoolsUrl) : 'data:text/plain,Dashboard only supported in Chromium based browsers',
256250
};
257251
}));
258252
}
259253

260-
pageForId(pageId: string) {
261-
return this._context?.pages().find(p => this._pageId(p) === pageId);
262-
}
263-
264254
private _pageId(p: api.Page): string {
265255
// eslint-disable-next-line no-restricted-syntax -- _guid is very conservative.
266256
return (p as any)._guid;
267257
}
268258

269-
private async _devtoolsUrl(page: api.Page) {
270-
// eslint-disable-next-line no-restricted-syntax -- cdpPort is not in the public LaunchOptions type, fine if regresses.
271-
const cdpPort = (this._browserDescriptor.browser.launchOptions as any).cdpPort;
272-
if (cdpPort)
273-
return new URL(`http://localhost:${cdpPort}/devtools/`);
274-
275-
const browserRevision = await getBrowserRevision(page);
276-
if (!browserRevision)
277-
return null;
278-
return new URL(`https://chrome-devtools-frontend.appspot.com/serve_rev/${browserRevision}/`);
279-
}
280-
281-
private async _pageInspectorUrl(page: api.Page, devtoolsUrl: URL): Promise<string | undefined> {
282-
const inspector = new URL('./devtools_app.html', devtoolsUrl);
283-
const cdp = new URL(this._cdpUrl);
284-
cdp.searchParams.set('cdpPageId', this._pageId(page));
285-
inspector.searchParams.set('ws', `${cdp.host}${cdp.pathname}${cdp.search}`);
286-
const url = inspector.toString();
287-
return url;
288-
}
289-
290259
private _sendTabList() {
291260
this._tabList().then(tabs => this._emit('tabs', { tabs }));
292261
}
@@ -298,59 +267,3 @@ export class DashboardConnection implements Transport, DashboardChannel {
298267
this._emit('frame', { data, viewportWidth, viewportHeight });
299268
}
300269
}
301-
302-
async function getBrowserRevision(page: api.Page): Promise<string | null> {
303-
try {
304-
const session = await page.context().newCDPSession(page);
305-
const version = await session.send('Browser.getVersion');
306-
await session.detach();
307-
return version.revision;
308-
} catch (error) {
309-
return null;
310-
}
311-
}
312-
313-
export class CDPConnection implements Transport {
314-
sendEvent?: (method: string, params: any) => void;
315-
close?: () => void;
316-
317-
private _page: api.Page;
318-
private _rawSession: api.CDPSession | null = null;
319-
private _rawSessionListeners: { dispose: () => Promise<void> }[] = [];
320-
private _initializePromise: Promise<void> | undefined;
321-
322-
constructor(page: api.Page) {
323-
this._page = page;
324-
}
325-
326-
onconnect() {
327-
this._initializePromise = this._initializeRawSession();
328-
}
329-
330-
async dispatch(method: string, params: any): Promise<any> {
331-
await this._initializePromise;
332-
if (!this._rawSession)
333-
throw new Error('CDP session is not initialized');
334-
return await this._rawSession.send(method as Parameters<api.CDPSession['send']>[0], params);
335-
}
336-
337-
onclose() {
338-
this._rawSessionListeners.forEach(listener => listener.dispose());
339-
this._rawSession?.detach().catch(() => {});
340-
this._rawSession = null;
341-
this._initializePromise = undefined;
342-
}
343-
344-
private async _initializeRawSession() {
345-
const session = await this._page.context().newCDPSession(this._page);
346-
this._rawSession = session;
347-
this._rawSessionListeners = [
348-
eventsHelper.addEventListener(session, 'event', ({ method, params }) => {
349-
this.sendEvent?.(method, params);
350-
}),
351-
eventsHelper.addEventListener(session, 'close', () => {
352-
this.close?.();
353-
}),
354-
];
355-
}
356-
}

0 commit comments

Comments
 (0)