Skip to content
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

fix: cy.intercept delay works correctly with 204 No Content #17126

Merged
merged 1 commit into from
Jul 13, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions packages/driver/cypress/integration/commands/net_stubbing_spec.ts
Original file line number Diff line number Diff line change
@@ -1682,6 +1682,30 @@ describe('network stubbing', { retries: 2 }, function () {
.then(() => testDelay()).wait('@get')
})

// https://github.com/cypress-io/cypress/issues/15188
it('delay works correctly with 204 No Content', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.include('No response ever occurred')

done()
})

cy.intercept('POST', '/post-only', {
statusCode: 204, // delay is not respected
delay: 5000,
}).as('create')

cy.window().then((win) => {
win.eval(
`fetch("/post-only", {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
});`,
)
})

cy.wait('@create', { timeout: 500 })
})

// @see https://github.com/cypress-io/cypress/issues/15901
it('can intercept utf-8 request bodies without crashing', function () {
cy.intercept('POST', 'http://localhost:5000/api/sample')
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/driver-events.ts
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ async function sendStaticResponse (state: NetStubbingState, getFixture: GetFixtu

await setResponseFromFixture(getFixture, options.staticResponse)

_sendStaticResponse(request, options.staticResponse)
await _sendStaticResponse(request, options.staticResponse)
}

export function _restoreMatcherOptionsTypes (options: AnnotatedRouteMatcherOptions) {
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/intercepted-request.ts
Original file line number Diff line number Diff line change
@@ -194,7 +194,7 @@ export class InterceptedRequest {
}

if (immediateStaticResponse) {
sendStaticResponse(this, immediateStaticResponse)
await sendStaticResponse(this, immediateStaticResponse)

return data
}
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/middleware/response.ts
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ export const InterceptResponse: ResponseMiddleware = async function () {

mergeChanges(request.res as any, modifiedRes)

const bodyStream = getBodyStream(modifiedRes.body, _.pick(modifiedRes, ['throttleKbps', 'delay']) as any)
const bodyStream = await getBodyStream(modifiedRes.body, _.pick(modifiedRes, ['throttleKbps', 'delay']) as any)

return request.continueResponse!(bodyStream)
}
16 changes: 12 additions & 4 deletions packages/net-stubbing/lib/server/util.ts
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ export async function setResponseFromFixture (getFixtureFn: GetFixtureFn, static
* @param backendRequest BackendRequest object.
* @param staticResponse BackendStaticResponse object.
*/
export function sendStaticResponse (backendRequest: Pick<InterceptedRequest, 'res' | 'onError' | 'onResponse'>, staticResponse: BackendStaticResponse) {
export async function sendStaticResponse (backendRequest: Pick<InterceptedRequest, 'res' | 'onError' | 'onResponse'>, staticResponse: BackendStaticResponse) {
const { onError, onResponse } = backendRequest

if (staticResponse.forceNetworkError) {
@@ -173,12 +173,12 @@ export function sendStaticResponse (backendRequest: Pick<InterceptedRequest, 're
body,
})

const bodyStream = getBodyStream(body, _.pick(staticResponse, 'throttleKbps', 'delay'))
const bodyStream = await getBodyStream(body, _.pick(staticResponse, 'throttleKbps', 'delay'))

onResponse!(incomingRes, bodyStream)
}

export function getBodyStream (body: Buffer | string | Readable | undefined, options: { delay?: number, throttleKbps?: number }): Readable {
export async function getBodyStream (body: Buffer | string | Readable | undefined, options: { delay?: number, throttleKbps?: number }): Promise<Readable> {
const { delay, throttleKbps } = options
const pt = new PassThrough()

@@ -203,11 +203,19 @@ export function getBodyStream (body: Buffer | string | Readable | undefined, opt
return writable.end()
}

delay ? setTimeout(sendBody, delay) : sendBody()
delay ? await wait(sendBody, delay) : sendBody()

return pt
}

function wait (fn, ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(fn())
}, ms)
})
}

export function mergeDeletedHeaders (before: CyHttpMessages.BaseMessage, after: CyHttpMessages.BaseMessage) {
for (const k in before.headers) {
// a header was deleted from `after` but was present in `before`, delete it in `before` too