Skip to content

Commit

Permalink
Changes from review
Browse files Browse the repository at this point in the history
  • Loading branch information
flotwig committed Mar 25, 2021
1 parent 7344235 commit 762d6eb
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 61 deletions.
31 changes: 11 additions & 20 deletions packages/driver/cypress/integration/commands/net_stubbing_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,17 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
cy
.intercept('/dump-headers', { middleware: true }, (req) => {
e.push('mware req handler')
req.on('before:response', (res) => e.push('mware before:response'))
req.on('response', (res) => e.push('mware response'))
req.on('after:response', (res) => e.push('mware after:response'))
req.on('before:response', (res) => {
e.push('mware before:response')
})

req.on('response', (res) => {
e.push('mware response')
})

req.on('after:response', (res) => {
e.push('mware after:response')
})
})
.intercept('/dump-headers', (req) => {
e.push('normal req handler')
Expand Down Expand Up @@ -1275,23 +1283,6 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
})

context('request events', function () {
it('receives response error in `error`', function () {
let err

cy.intercept({ hostname: 'foo.invalid' }, (req) => {
req.on('error', (_err) => {
err = _err
})
}).as('err')
.then(() => {
$.get('http://foo.invalid')
})
.wait('@err')
.then(() => {
expect(err.message).to.contain('ENOTFOUND')
})
})

context('can end response', () => {
for (const eventName of ['before:response', 'response']) {
it(`in \`${eventName}\``, () => {
Expand Down
38 changes: 21 additions & 17 deletions packages/driver/src/cy/net-stubbing/events/before-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const debug = Debug('cypress:driver:net-stubbing:events:before-request')

type Result = HandlerResult<CyHttpMessages.IncomingRequest>

const validEvents = ['before:response', 'response', 'after:response', 'error']
const validEvents = ['before:response', 'response', 'after:response']

export const onBeforeRequest: HandlerFn<CyHttpMessages.IncomingRequest> = (Cypress, frame, userHandler, { getRoute, getRequest, emitNetEvent, sendStaticResponse }) => {
function getRequestLog (route: Route, request: Omit<Interception, 'log'>) {
Expand Down Expand Up @@ -59,6 +59,24 @@ export const onBeforeRequest: HandlerFn<CyHttpMessages.IncomingRequest> = (Cypre

parseJsonBody(req)

const subscribe = (eventName, handler) => {
const subscription: Subscription = {
id: _.uniqueId('Subscription'),
routeId,
eventName,
await: true,
}

request.subscriptions.push({
subscription,
handler,
})

debug('created request subscription %o', { eventName, request, subscription, handler })

emitNetEvent('subscribe', { requestId, subscription } as NetEvent.ToServer.Subscribe)
}

const getCanonicalRequest = (): Interception => {
const existingRequest = getRequest(routeId, requestId)

Expand Down Expand Up @@ -90,21 +108,7 @@ export const onBeforeRequest: HandlerFn<CyHttpMessages.IncomingRequest> = (Cypre
return $errUtils.throwErrByPath('net_stubbing.request_handling.event_needs_handler')
}

const subscription: Subscription = {
id: _.uniqueId('Subscription'),
routeId,
eventName,
await: true,
}

request.subscriptions.push({
subscription,
handler,
})

debug('created request subscription %o', { eventName, request, subscription, handler })

emitNetEvent('subscribe', { requestId, subscription } as NetEvent.ToServer.Subscribe)
subscribe(eventName, handler)

return request
},
Expand Down Expand Up @@ -139,7 +143,7 @@ export const onBeforeRequest: HandlerFn<CyHttpMessages.IncomingRequest> = (Cypre
}

// allow `req` to be sent outgoing, then pass the response body to `responseHandler`
request.on('before:response', responseHandler)
subscribe('response:callback', responseHandler)

userReq.responseTimeout = userReq.responseTimeout || Cypress.config('responseTimeout')

Expand Down
5 changes: 3 additions & 2 deletions packages/driver/src/cy/net-stubbing/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Route, Interception, StaticResponse, NetEvent } from '../types'
import { onBeforeRequest } from './before-request'
import { onResponse } from './response'
import { onAfterResponse } from './after-response'
import { onError } from './error'
import { onNetworkError } from './network-error'
import Bluebird from 'bluebird'
import { getBackendStaticResponse } from '../static-response-utils'

Expand All @@ -21,9 +21,10 @@ export type HandlerFn<D> = (Cypress: Cypress.Cypress, frame: NetEvent.ToDriver.E
const netEventHandlers: { [eventName: string]: HandlerFn<any> } = {
'before:request': onBeforeRequest,
'before:response': onResponse,
'response:callback': onResponse,
'response': onResponse,
'after:response': onAfterResponse,
'error': onError,
'network:error': onNetworkError,
}

export function registerEvents (Cypress: Cypress.Cypress, cy: Cypress.cy) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CyHttpMessages } from '@packages/net-stubbing/lib/types'
import { errByPath, makeErrFromObj } from '../../../cypress/error_utils'
import { HandlerFn } from '.'

export const onError: HandlerFn<CyHttpMessages.Error> = async (Cypress, frame, userHandler, { getRequest, getRoute }) => {
export const onNetworkError: HandlerFn<CyHttpMessages.NetworkError> = async (Cypress, frame, userHandler, { getRequest, getRoute }) => {
const request = getRequest(frame.subscription.routeId, frame.requestId)

const { data } = frame
Expand All @@ -13,9 +13,9 @@ export const onError: HandlerFn<CyHttpMessages.Error> = async (Cypress, frame, u
}

let err = makeErrFromObj(data.error)
// does this request have a `before:response` handler?
// does this request have a user response callback handler?
const hasResponseHandler = !!request.subscriptions.find(({ subscription }) => {
return subscription.eventName === 'before:response'
return subscription.eventName === 'response:callback'
})
const isAwaitingResponse = hasResponseHandler && ['Received', 'Intercepted'].includes(request.state)
const isTimeoutError = data.error.code && ['ESOCKETTIMEDOUT', 'ETIMEDOUT'].includes(data.error.code)
Expand Down
19 changes: 7 additions & 12 deletions packages/net-stubbing/lib/external-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export namespace CyHttpMessages {
finalResBody?: BaseMessage['body']
}

export interface Error {
export interface NetworkError {
error: any
}
}
Expand Down Expand Up @@ -206,28 +206,23 @@ export interface Subscription {

interface InterceptionEvents {
/**
* Emitted before `response` and at the same time as `req.continue` and `req.reply` handlers.
* Emitted before `response` and before any `req.continue` handlers.
* Modifications to `res` will be applied to the incoming response.
* If a promise is returned from `cb`, it will be awaited before processing other event handlers.
*/
on(eventName: 'before:response', cb: (res: CyHttpMessages.IncomingHttpResponse) => void): Interception
on(eventName: 'before:response', cb: HttpResponseInterceptor): Interception
/**
* Emitted after `before:response` and after any `req.continue` or `req.reply` handlers - before the response is sent to the browser.
* Emitted after `before:response` and after any `req.continue` handlers - before the response is sent to the browser.
* Modifications to `res` will be applied to the incoming response.
* If a promise is returned from `cb`, it will be awaited before processing other event handlers.
*/
on(eventName: 'response', cb: (res: CyHttpMessages.IncomingHttpResponse) => void): Interception
on(eventName: 'response', cb: HttpResponseInterceptor): Interception
/**
* Emitted once the response to a request has finished sending to the browser.
* Modifications to `res` have no impact.
* If a promise is returned from `cb`, it will be awaited before processing other event handlers.
*/
on(eventName: 'after:response', cb: (res: CyHttpMessages.IncomingResponse) => void): Interception
/**
* Emitted when a network error is encountered during an upstream request.
* If a promise is returned from `cb`, it will be awaited before processing other event handlers.
*/
on(eventName: 'error', cb: (err: Error) => void): Interception
on(eventName: 'after:response', cb: (res: CyHttpMessages.IncomingResponse) => void | Promise<void>): Interception
}

/**
Expand Down Expand Up @@ -445,7 +440,7 @@ declare global {
* })
* @example
* cy.intercept('https://localhost:7777/some-response', (req) => {
* req.reply(res => {
* req.continue(res => {
* res.body = 'some new body'
* })
* })
Expand Down
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/driver-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async function sendStaticResponse (state: NetStubbingState, getFixture: GetFixtu
return
}

if (options.staticResponse.fixture && ['before:response', 'response'].includes(request.lastEvent!)) {
if (options.staticResponse.fixture && ['before:response', 'response:callback', 'response'].includes(request.lastEvent!)) {
// if we're already in a response phase, it's possible that the fixture body will never be sent to the browser
// so include the fixture body in `after:response`
request.includeBodyInAfterResponse = true
Expand Down
3 changes: 1 addition & 2 deletions packages/net-stubbing/lib/server/intercepted-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,10 @@ export class InterceptedRequest {
immediateStaticResponse: route.staticResponse,
subscriptions: [{
eventName: 'before:request',
// req.reply callback?
await: !!route.hasInterceptor,
routeId: route.id,
},
...(['before:response', 'after:response', 'error'].map((eventName) => {
...(['response:callback', 'after:response', 'network:error'].map((eventName) => {
// notification-only default event
return { eventName, await: false, routeId: route.id }
}))],
Expand Down
4 changes: 2 additions & 2 deletions packages/net-stubbing/lib/server/middleware/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export const InterceptError: ErrorMiddleware = async function () {

request.continueResponse = this.next

await request.handleSubscriptions<CyHttpMessages.Error>({
eventName: 'error',
await request.handleSubscriptions<CyHttpMessages.NetworkError>({
eventName: 'network:error',
data: {
error: errors.clone(this.error),
},
Expand Down
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/middleware/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const InterceptResponse: ResponseMiddleware = async function () {
}

const modifiedRes = await request.handleSubscriptions<CyHttpMessages.IncomingResponse>({
eventName: ['before:response', 'response'],
eventName: ['before:response', 'response:callback', 'response'],
data: res,
mergeChanges,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/runner/cypress/fixtures/errors/intercept_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('cy.intercept', () => {
data: {},
})

Cypress.emit('net:event', 'error', {
Cypress.emit('net:event', 'network:error', {
eventId: '1',
requestId: '1',
subscription: {
Expand Down

0 comments on commit 762d6eb

Please sign in to comment.