-
Notifications
You must be signed in to change notification settings - Fork 661
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: inject resources with CDP (#7186)
* proxyless: inject resources using cdp * fix tests * small refactoring * small refactoring * update hammerhead * stub proxyless tests * fix task script creation * fix proxyless run * revert refactoring
- Loading branch information
1 parent
bc8bac1
commit 9b348de
Showing
17 changed files
with
219 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import BrowserConnection from './index'; | ||
|
||
class BrowserConnectionTracker { | ||
public activeBrowserConnections: { [id: string]: BrowserConnection }; | ||
|
||
public constructor () { | ||
this.activeBrowserConnections = {}; | ||
} | ||
|
||
public add (connection: BrowserConnection): void { | ||
this.activeBrowserConnections[connection.id] = connection; | ||
} | ||
|
||
public remove (connection: BrowserConnection): void { | ||
delete this.activeBrowserConnections[connection.id]; | ||
} | ||
} | ||
|
||
export default new BrowserConnectionTracker(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
src/browser/provider/built-in/dedicated/chrome/requests-interceptor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { ProtocolApi } from 'chrome-remote-interface'; | ||
import Protocol from 'devtools-protocol'; | ||
import RequestPausedEvent = Protocol.Fetch.RequestPausedEvent; | ||
import RequestPattern = Protocol.Fetch.RequestPattern; | ||
import GetResponseBodyResponse = Protocol.Fetch.GetResponseBodyResponse; | ||
import { | ||
injectResources, | ||
PageInjectableResources, | ||
INJECTABLE_SCRIPTS as HAMMERHEAD_INJECTABLE_SCRIPTS, | ||
} from 'testcafe-hammerhead'; | ||
import BrowserConnection from '../../../../connection'; | ||
import { SCRIPTS, TESTCAFE_UI_STYLES } from '../../../../../assets/injectables'; | ||
|
||
const HTTP_STATUS_OK = 200; | ||
|
||
export default class RequestsInterceptor { | ||
private readonly _browserId: string; | ||
|
||
public constructor (browserId: string) { | ||
this._browserId = browserId; | ||
} | ||
|
||
private _getResponseAsString (response: GetResponseBodyResponse): string { | ||
return response.base64Encoded | ||
? Buffer.from(response.body, 'base64').toString() | ||
: response.body; | ||
} | ||
|
||
private async _prepareInjectableResources (): Promise<PageInjectableResources> { | ||
const browserConnection = BrowserConnection.getById(this._browserId) as BrowserConnection; | ||
const proxy = browserConnection.browserConnectionGateway.proxy; | ||
const windowId = browserConnection.activeWindowId; | ||
|
||
const taskScript = await browserConnection.currentJob.currentTestRun.session.getTaskScript({ | ||
referer: '', | ||
cookieUrl: '', | ||
isIframe: false, | ||
withPayload: true, | ||
serverInfo: proxy.server1Info, | ||
windowId, | ||
}); | ||
|
||
const injectableResources = { | ||
stylesheets: [ | ||
TESTCAFE_UI_STYLES, | ||
], | ||
scripts: [ | ||
...HAMMERHEAD_INJECTABLE_SCRIPTS, | ||
...SCRIPTS, | ||
], | ||
embeddedScripts: [taskScript], | ||
}; | ||
|
||
injectableResources.scripts = injectableResources.scripts.map(script => proxy.resolveRelativeServiceUrl(script)); | ||
injectableResources.stylesheets = injectableResources.stylesheets.map(style => proxy.resolveRelativeServiceUrl(style)); | ||
|
||
return injectableResources; | ||
} | ||
|
||
public async setup (client: ProtocolApi): Promise<void> { | ||
const fetchAllDocumentsPattern = { | ||
urlPattern: '*', | ||
resourceType: 'Document', | ||
requestStage: 'Response', | ||
} as RequestPattern; | ||
|
||
await client.Fetch.enable({ patterns: [fetchAllDocumentsPattern] }); | ||
|
||
client.Fetch.on('requestPaused', async (params: RequestPausedEvent) => { | ||
const { | ||
requestId, | ||
responseHeaders, | ||
responseStatusCode, | ||
} = params; | ||
|
||
const responseObj = await client.Fetch.getResponseBody({ requestId }); | ||
const responseStr = this._getResponseAsString(responseObj); | ||
const injectableResources = await this._prepareInjectableResources(); | ||
const updatedResponseStr = injectResources(responseStr, injectableResources); | ||
|
||
await client.Fetch.fulfillRequest({ | ||
requestId, | ||
responseCode: responseStatusCode || HTTP_STATUS_OK, | ||
responseHeaders: responseHeaders || [], | ||
body: Buffer.from(updatedResponseStr).toString('base64'), | ||
}); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.