diff --git a/packages/server/lib/browsers/cdp_automation.ts b/packages/server/lib/browsers/cdp_automation.ts index 2342f882d2df..7d96704741db 100644 --- a/packages/server/lib/browsers/cdp_automation.ts +++ b/packages/server/lib/browsers/cdp_automation.ts @@ -202,6 +202,15 @@ export class CdpAutomation { // in Firefox, the hash is incorrectly included in the URL: https://bugzilla.mozilla.org/show_bug.cgi?id=1715366 if (url.includes('#')) url = url.slice(0, url.indexOf('#')) + // Filter out "data:" urls from being cached - fixes: https://github.com/cypress-io/cypress/issues/17853 + // Chrome sends `Network.requestWillBeSent` events with data urls which won't actually be fetched + // Example data url: "data:font/woff;base64," + if (url.startsWith('data:')) { + debugVerbose('skipping `data:` url %s', url) + + return + } + // Firefox: https://searchfox.org/mozilla-central/rev/98a9257ca2847fad9a19631ac76199474516b31e/remote/cdp/domains/parent/Network.jsm#397 // Firefox lacks support for urlFragment and initiator, two nice-to-haves const browserPreRequest: BrowserPreRequest = { diff --git a/packages/server/test/unit/browsers/cdp_automation_spec.ts b/packages/server/test/unit/browsers/cdp_automation_spec.ts index b5bbf18511ee..608726185f68 100644 --- a/packages/server/test/unit/browsers/cdp_automation_spec.ts +++ b/packages/server/test/unit/browsers/cdp_automation_spec.ts @@ -71,15 +71,103 @@ context('lib/browsers/cdp_automation', () => { this.sendDebuggerCommand = sinon.stub() this.onFn = sinon.stub() this.sendCloseTargetCommand = sinon.stub() + this.automation = { + onBrowserPreRequest: sinon.stub(), + onRequestEvent: sinon.stub(), + } - this.automation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, null, false) + this.cdpAutomation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, this.automation, false) this.sendDebuggerCommand .throws(new Error('not stubbed')) .withArgs('Browser.getVersion') .resolves() - this.onRequest = this.automation.onRequest + this.onRequest = this.cdpAutomation.onRequest + }) + + describe('.onNetworkRequestWillBeSent', function () { + it('triggers onBrowserPreRequest', function () { + const browserPreRequest = { + requestId: '0', + type: 'other', + request: { + method: 'GET', + url: 'https://www.google.com', + headers: {}, + }, + } + + this.onFn + .withArgs('Network.requestWillBeSent') + .yield(browserPreRequest) + + expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({ + requestId: browserPreRequest.requestId, + method: browserPreRequest.request.method, + url: browserPreRequest.request.url, + headers: browserPreRequest.request.headers, + resourceType: browserPreRequest.type, + originalResourceType: browserPreRequest.type, + }) + }) + + it('removes # from a url', function () { + const browserPreRequest = { + requestId: '0', + type: 'other', + request: { + method: 'GET', + url: 'https://www.google.com/foo#', + headers: {}, + }, + } + + this.onFn + .withArgs('Network.requestWillBeSent') + .yield(browserPreRequest) + + expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({ + requestId: browserPreRequest.requestId, + method: browserPreRequest.request.method, + url: 'https://www.google.com/foo', // we only care about the url + headers: browserPreRequest.request.headers, + resourceType: browserPreRequest.type, + originalResourceType: browserPreRequest.type, + }) + }) + + it('ignore events with data urls', function () { + this.onFn + .withArgs('Network.requestWillBeSent') + .yield({ request: { url: 'data:font;base64' } }) + + expect(this.automation.onBrowserPreRequest).to.not.be.called + }) + }) + + describe('.onResponseReceived', function () { + it('triggers onRequestEvent', function () { + const browserResponseReceived = { + requestId: '0', + response: { + status: 200, + headers: {}, + }, + } + + this.onFn + .withArgs('Network.responseReceived') + .yield(browserResponseReceived) + + expect(this.automation.onRequestEvent).to.have.been.calledWith( + 'response:received', { + requestId: browserResponseReceived.requestId, + status: browserResponseReceived.response.status, + headers: browserResponseReceived.response.headers, + }, + ) + }) }) describe('get:cookies', () => {