-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(server): convert remaining browsers code to typescript #23556
Changes from 7 commits
297e41b
173de9f
e493600
beb3f2d
4957a83
c255548
b01e8c0
ce15192
8bd49f3
8e8f62a
501895a
5e74399
ab66d07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -20,9 +20,7 @@ import { BrowserCriClient } from './browser-cri-client' | |||
import type { LaunchedBrowser } from '@packages/launcher/lib/browsers' | ||||
import type { CRIWrapper } from './cri-client' | ||||
import type { Automation } from '../automation' | ||||
|
||||
// TODO: this is defined in `cypress-npm-api` but there is currently no way to get there | ||||
type CypressConfiguration = any | ||||
import type { BrowserLaunchOpts, BrowserNewTabOpts } from '@packages/types' | ||||
|
||||
const debug = debugModule('cypress:server:browsers:chrome') | ||||
|
||||
|
@@ -123,7 +121,7 @@ const DEFAULT_ARGS = [ | |||
'--disable-dev-shm-usage', | ||||
] | ||||
|
||||
let browserCriClient | ||||
let browserCriClient: BrowserCriClient | undefined | ||||
|
||||
/** | ||||
* Reads all known preference files (CHROME_PREFERENCE_PATHS) from disk and retur | ||||
|
@@ -433,8 +431,8 @@ const _handlePausedRequests = async (client) => { | |||
}) | ||||
} | ||||
|
||||
const _setAutomation = async (client: CRIWrapper.Client, automation: Automation, resetBrowserTargets: (shouldKeepTabOpen: boolean) => Promise<void>, options: CypressConfiguration = {}) => { | ||||
const cdpAutomation = await CdpAutomation.create(client.send, client.on, resetBrowserTargets, automation, options.experimentalSessionAndOrigin) | ||||
const _setAutomation = async (client: CRIWrapper.Client, automation: Automation, resetBrowserTargets: (shouldKeepTabOpen: boolean) => Promise<void>, options: BrowserLaunchOpts) => { | ||||
const cdpAutomation = await CdpAutomation.create(client.send, client.on, resetBrowserTargets, automation, !!options.experimentalSessionAndOrigin) | ||||
|
||||
return automation.use(cdpAutomation) | ||||
} | ||||
|
@@ -490,7 +488,7 @@ export = { | |||
return extensionDest | ||||
}, | ||||
|
||||
_getArgs (browser: Browser, options: CypressConfiguration, port: string) { | ||||
_getArgs (browser: Browser, options: BrowserLaunchOpts, port: string) { | ||||
const args = ([] as string[]).concat(DEFAULT_ARGS) | ||||
|
||||
if (os.platform() === 'linux') { | ||||
|
@@ -551,43 +549,60 @@ export = { | |||
return args | ||||
}, | ||||
|
||||
async connectToNewSpec (browser: Browser, options: CypressConfiguration = {}, automation: Automation) { | ||||
async connectToNewSpec (browser: Browser, options: BrowserNewTabOpts, automation: Automation) { | ||||
debug('connecting to new chrome tab in existing instance with url and debugging port', { url: options.url }) | ||||
|
||||
const browserCriClient = this._getBrowserCriClient() | ||||
|
||||
if (!browserCriClient) throw new Error('Missing browserCriClient in connectToNewSpec') | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think
assert(browserCriClient, 'Missing browserCriClient in connectToNewSpec') There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should actually close #22451 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, at least it will give a clearer error message. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well...it doesn't fix it but it just give a better warning. I remember talking with @ryanthemanuel about this
|
||||
|
||||
const pageCriClient = browserCriClient.currentlyAttachedTarget | ||||
|
||||
if (!pageCriClient) throw new Error('Missing pageCriClient in connectToNewSpec') | ||||
|
||||
if (!options.url) throw new Error('Missing url in connectToNewSpec') | ||||
|
||||
await this.attachListeners(browser, options.url, pageCriClient, automation, options) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of marking this as async There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Readability-wise, I prefer |
||||
}, | ||||
|
||||
async connectToExisting (browser: Browser, options: BrowserLaunchOpts, automation) { | ||||
const port = await protocol.getRemoteDebuggingPort() | ||||
|
||||
debug('connecting to existing chrome instance with url and debugging port', { url: options.url, port }) | ||||
if (!options.onError) throw new Error('Missing onError in connectToExisting') | ||||
|
||||
const browserCriClient = await BrowserCriClient.create(port, browser.displayName, options.onError, onReconnect) | ||||
|
||||
if (!options.url) throw new Error('Missing url in connectToExisting') | ||||
|
||||
const pageCriClient = await browserCriClient.attachToTargetUrl(options.url) | ||||
|
||||
await this._setAutomation(pageCriClient, automation, browserCriClient.resetBrowserTargets, options) | ||||
}, | ||||
|
||||
async attachListeners (browser: Browser, url: string, pageCriClient, automation: Automation, options: BrowserLaunchOpts & { onInitializeNewBrowserTab?: () => void }) { | ||||
if (!browserCriClient) throw new Error('Missing browserCriClient in attachListeners') | ||||
|
||||
await this._setAutomation(pageCriClient, automation, browserCriClient.resetBrowserTargets, options) | ||||
|
||||
// make sure page events are re enabled or else frame tree updates will NOT work as well as other items listening for page events | ||||
await pageCriClient.send('Page.enable') | ||||
|
||||
await options.onInitializeNewBrowserTab() | ||||
await options.onInitializeNewBrowserTab?.() | ||||
|
||||
await Promise.all([ | ||||
this._maybeRecordVideo(pageCriClient, options, browser.majorVersion), | ||||
this._handleDownloads(pageCriClient, options.downloadsFolder, automation), | ||||
]) | ||||
|
||||
await this._navigateUsingCRI(pageCriClient, options.url) | ||||
await this._navigateUsingCRI(pageCriClient, url) | ||||
|
||||
if (options.experimentalSessionAndOrigin) { | ||||
await this._handlePausedRequests(pageCriClient) | ||||
_listenForFrameTreeChanges(pageCriClient) | ||||
} | ||||
}, | ||||
|
||||
async connectToExisting (browser: Browser, options: CypressConfiguration = {}, automation) { | ||||
const port = await protocol.getRemoteDebuggingPort() | ||||
|
||||
debug('connecting to existing chrome instance with url and debugging port', { url: options.url, port }) | ||||
const browserCriClient = await BrowserCriClient.create(port, browser.displayName, options.onError, onReconnect) | ||||
const pageCriClient = await browserCriClient.attachToTargetUrl(options.url) | ||||
|
||||
await this._setAutomation(pageCriClient, automation, browserCriClient.resetBrowserTargets, options) | ||||
}, | ||||
|
||||
async open (browser: Browser, url, options: CypressConfiguration = {}, automation: Automation): Promise<LaunchedBrowser> { | ||||
async open (browser: Browser, url, options: BrowserLaunchOpts, automation: Automation): Promise<LaunchedBrowser> { | ||||
const { isTextTerminal } = options | ||||
|
||||
const userDir = utils.getProfileDir(browser, isTextTerminal) | ||||
|
@@ -646,6 +661,8 @@ export = { | |||
// SECOND connect to the Chrome remote interface | ||||
// and when the connection is ready | ||||
// navigate to the actual url | ||||
if (!options.onError) throw new Error('Missing onError in chrome#open') | ||||
|
||||
browserCriClient = await BrowserCriClient.create(port, browser.displayName, options.onError, onReconnect) | ||||
|
||||
la(browserCriClient, 'expected Chrome remote interface reference', browserCriClient) | ||||
|
@@ -669,7 +686,7 @@ export = { | |||
debug('closing remote interface client') | ||||
|
||||
// Do nothing on failure here since we're shutting down anyway | ||||
browserCriClient.close().catch() | ||||
browserCriClient?.close().catch() | ||||
browserCriClient = undefined | ||||
|
||||
debug('closing chrome') | ||||
|
@@ -679,21 +696,7 @@ export = { | |||
|
||||
const pageCriClient = await browserCriClient.attachToTargetUrl('about:blank') | ||||
|
||||
await this._setAutomation(pageCriClient, automation, browserCriClient.resetBrowserTargets, options) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice deduping of this code here. Good clean up |
||||
|
||||
await pageCriClient.send('Page.enable') | ||||
|
||||
await Promise.all([ | ||||
this._maybeRecordVideo(pageCriClient, options, browser.majorVersion), | ||||
this._handleDownloads(pageCriClient, options.downloadsFolder, automation), | ||||
]) | ||||
|
||||
await this._navigateUsingCRI(pageCriClient, url) | ||||
|
||||
if (options.experimentalSessionAndOrigin) { | ||||
await this._handlePausedRequests(pageCriClient) | ||||
_listenForFrameTreeChanges(pageCriClient) | ||||
} | ||||
await this.attachListeners(browser, url, pageCriClient, automation, options) | ||||
|
||||
// return the launched browser process | ||||
// with additional method to close the remote connection | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the interface is
I wonder why we need the
ts-expect-error
? What is the error?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only
OpenProjectLaunchOpts
at this point, which doesn't haveurl
. This is an area that should be refactored, we're putting a lot of functionality intoproject.launchProject
that makes it difficult to reason with (and difficult to sanely type)