diff --git a/packages/driver/cypress/integration/commands/net_stubbing_spec.ts b/packages/driver/cypress/integration/commands/net_stubbing_spec.ts index 544eec4efd77..27bc07da5802 100644 --- a/packages/driver/cypress/integration/commands/net_stubbing_spec.ts +++ b/packages/driver/cypress/integration/commands/net_stubbing_spec.ts @@ -11,6 +11,13 @@ const testFail = (cb, expectedDocsUrl = 'https://on.cypress.io/intercept') => { }) } +let routeCount = 0 +const uniqueRoute = (route) => { + routeCount += 1 + + return `${route}-${routeCount}` +} + describe('network stubbing', function () { const { $, _, sinon, state, Promise } = Cypress @@ -45,7 +52,7 @@ describe('network stubbing', function () { it('url, body and stores Route', function () { const handler = 'bar' - const url = 'http://foo.invalid' + const url = uniqueRoute('http://foo.invalid') const expectedEvent = { routeMatcher: { url: { @@ -72,7 +79,7 @@ describe('network stubbing', function () { return {} } - const url = 'http://foo.invalid' + const url = uniqueRoute('http://foo.invalid') const expectedEvent = { routeMatcher: { url: { @@ -115,7 +122,7 @@ describe('network stubbing', function () { bar: 'baz', quuz: /(.*)quux/gi, }, - url: 'http://foo.invalid', + url: uniqueRoute('http://foo.invalid'), } const expectedEvent = { @@ -185,7 +192,7 @@ describe('network stubbing', function () { }) it('mergeRouteMatcher + string url works', function () { - const url = '/foo*' + const url = uniqueRoute('/foo') const handler = (req) => { // @ts-ignore @@ -203,7 +210,7 @@ describe('network stubbing', function () { } const expectedRoute = { - options: { url, middleware: true }, + options: { url: `${url}*`, middleware: true }, handler, } @@ -211,23 +218,24 @@ describe('network stubbing', function () { routeMatcher: { url: { type: 'glob', - value: url, + value: `${url}*`, }, middleware: true, }, hasInterceptor: true, } - cy.intercept(url, { middleware: true }, handler).as('get') + cy.intercept(`${url}*`, { middleware: true }, handler).as('get') .then(() => { - return $.get('/foo') + return $.get(url) }) .wait('@get') }) // @see https://github.com/cypress-io/cypress/pull/16390 it('mergeRouteMatcher + regex url works', function () { - const url = /^\/foo.*/ + const url = uniqueRoute('/foo') + const regexUrl = new RegExp(`^${url}.*`) const handler = (req) => { // @ts-ignore @@ -245,7 +253,7 @@ describe('network stubbing', function () { } const expectedRoute = { - options: { url, middleware: true }, + options: { url: regexUrl, middleware: true }, handler, } @@ -253,16 +261,16 @@ describe('network stubbing', function () { routeMatcher: { url: { type: 'regex', - value: String(url), + value: String(regexUrl), }, middleware: true, }, hasInterceptor: true, } - cy.intercept(url, { middleware: true }, handler).as('get') + cy.intercept(regexUrl, { middleware: true }, handler).as('get') .then(() => { - return $.get('/foo') + return $.get(url) }) .wait('@get') }) @@ -378,10 +386,12 @@ describe('network stubbing', function () { * https://github.com/cypress-io/cypress/issues/4460 */ it('can override a StaticResponse with another StaticResponse', function () { - cy.intercept('GET', '/items*', []) - .intercept('GET', '/items*', ['foo', 'bar']) + const url = uniqueRoute('/items') + + cy.intercept('GET', `${url}*`, []) + .intercept('GET', `${url}*`, ['foo', 'bar']) .then(() => { - return $.getJSON('/items') + return $.getJSON(url) }) .should('deep.eq', ['foo', 'bar']) }) @@ -404,13 +414,15 @@ describe('network stubbing', function () { }) it('sends a StaticResponse if the newest stub is a StaticResponse', function () { - cy.intercept('/foo*', () => { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, () => { throw new Error('this should not be called') }).as('interceptor') - .intercept('/foo*', { body: 'something' }).as('staticresponse') - .intercept('/foo*').as('spy') + .intercept(`${url}*`, { body: 'something' }).as('staticresponse') + .intercept(`${url}*`).as('spy') .then(() => { - return $.get('/foo') + return $.get(url) }) .should('deep.eq', 'something') .wait('@spy') @@ -419,10 +431,12 @@ describe('network stubbing', function () { }) it('sends a StaticResponse if a request handler does not supply a response', function () { - cy.intercept('/foo*', { body: 'something' }).as('staticresponse') - .intercept('/foo*', () => { }).as('interceptor') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, { body: 'something' }).as('staticresponse') + .intercept(`${url}*`, () => { }).as('interceptor') .then(() => { - return $.get('/foo') + return $.get(url) }) .should('deep.eq', 'something') .wait('@interceptor') @@ -543,7 +557,9 @@ describe('network stubbing', function () { }) it('has name of route', function () { - cy.intercept('/foo', {}).then(function () { + const url = uniqueRoute('/foo') + + cy.intercept(url, {}).then(function () { expect(this.lastLog.get('name')).to.eq('route') }) }) @@ -575,14 +591,20 @@ describe('network stubbing', function () { }) it('is incremented to 2', function () { - cy.intercept(/foo/, {}).then(function () { - $.get('/foo') + const url = uniqueRoute('/foo') + const regexUrl = new RegExp(url) + + cy.intercept(regexUrl, {}).then(function () { + $.get(url) }).wrap(this).invoke('lastLog.get', 'numResponses').should('eq', 1) }) it('is incremented for each matching request', function () { - cy.intercept(/foo/, {}).then(function () { - return Promise.all([$.get('/foo'), $.get('/foo'), $.get('/foo')]) + const url = uniqueRoute('/foo') + const regexUrl = new RegExp(url) + + cy.intercept(regexUrl, {}).then(function () { + return Promise.all([$.get(url), $.get(url), $.get(url)]) }).wrap(this).invoke('lastLog.get', 'numResponses').should('eq', 3) }) }) @@ -619,13 +641,15 @@ describe('network stubbing', function () { // TODO: not currently implemented it.skip('fails when method is invalid', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.include('cy.intercept() was called with an invalid method: \'POSTS\'.') done() }) - cy.intercept('post', '/foo', {}) + cy.intercept('post', url, {}) }) it('requires a url when given a response', function (done) { @@ -650,6 +674,8 @@ describe('network stubbing', function () { }) it('cannot merge url with url', function (done) { + const url = uniqueRoute('/bar') + testFail((err) => { expect(err.message).to.include('When invoking \`cy.intercept()\` with a \`RouteMatcher\` as the second parameter, \`url\` can only be specified as the first parameter') @@ -657,10 +683,12 @@ describe('network stubbing', function () { }) // @ts-ignore - should fail - cy.intercept('/foo', { url: '/bar' }, () => {}) + cy.intercept(url, { url }, () => {}) }) it('cannot pass RouteMatcherOptions in 2nd arg with no handler', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.include('When invoking \`cy.intercept()\` with a \`RouteMatcher\` as the second parameter, a handler (function or \`StaticResponse\`) must be specified as the third parameter.') @@ -668,10 +696,12 @@ describe('network stubbing', function () { }) // sadly this passes typecheck, but the runtime error will prevent this - cy.intercept('/foo', { middleware: true }) + cy.intercept(url, { middleware: true }) }) context('with an unexpected number of arguments', function () { + const url = uniqueRoute('/url') + it('cy.intercept(url, handler?)', function (done) { testFail((err) => { expect(err.message).to.include('The `cy.intercept(url, handler?)` signature accepts a maximum of 2 arguments, but 3 arguments were passed.') @@ -679,27 +709,31 @@ describe('network stubbing', function () { }) // @ts-ignore - cy.intercept('/url', { forceNetworkError: true }, () => {}) + cy.intercept(url, { forceNetworkError: true }, () => {}) }) it('cy.intercept(url, mergeRouteMatcher, handler)', function (done) { + const url = uniqueRoute('/url') + testFail((err) => { expect(err.message).to.include('The `cy.intercept(url, mergeRouteMatcher, handler)` signature accepts a maximum of 3 arguments, but 4 arguments were passed.') done() }) // @ts-ignore - cy.intercept('/url', { middleware: true }, { forceNetworkError: true }, () => {}) + cy.intercept(url, { middleware: true }, { forceNetworkError: true }, () => {}) }) it('cy.intercept(method, url, handler?)', function (done) { + const url = uniqueRoute('/url') + testFail((err) => { expect(err.message).to.include('The `cy.intercept(method, url, handler?)` signature accepts a maximum of 3 arguments, but 4 arguments were passed.') done() }) // @ts-ignore - cy.intercept('POST', '/url', { forceNetworkError: true }, () => {}) + cy.intercept('POST', url, { forceNetworkError: true }, () => {}) }) }) @@ -915,9 +949,11 @@ describe('network stubbing', function () { }) it('different origin (HTTP)', function () { - cy.intercept('/foo*').as('foo') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`).as('foo') .then(() => { - $.get('http://baz.foobar.com:3501/foo') + $.get(`http://baz.foobar.com:3501${url}`) }) .wait('@foo') }) @@ -940,9 +976,11 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/8487 it('different origin (HTTPS)', function () { - cy.intercept('/foo*', 'somethin').as('foo') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, 'somethin').as('foo') .then(() => { - $.get('https://bar.foobar.com.invalid:3502/foo') + $.get(`https://bar.foobar.com.invalid:3502${url}`) }) .wait('@foo') }) @@ -1136,7 +1174,9 @@ describe('network stubbing', function () { }) it('can stub a cy.visit with static body', function () { - cy.intercept('/foo', 'hello cruel world').visit('/foo').document().should('contain.text', 'hello cruel world') + const url = uniqueRoute('/foo') + + cy.intercept(url, 'hello cruel world').visit(url).document().should('contain.text', 'hello cruel world') }) it('can stub a response with an empty StaticResponse', function (done) { @@ -1164,17 +1204,21 @@ describe('network stubbing', function () { }) it('can use regular strings as response', function () { - cy.intercept('/foo*', 'foo bar baz').as('getFoo').then(function (win) { - $.get('/foo') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, 'foo bar baz').as('getFoo').then(function (win) { + $.get(url) }).wait('@getFoo').then(function (res) { expect(res.response!.body).to.eq('foo bar baz') }) }) it('can stub requests with uncommon HTTP methods', function () { - cy.intercept('PROPFIND', '/foo', 'foo bar baz').as('getFoo').then(function (win) { + const url = uniqueRoute('/foo') + + cy.intercept('PROPFIND', url, 'foo bar baz').as('getFoo').then(function (win) { $.ajax({ - url: '/foo', + url, method: 'PROPFIND', }) }).wait('@getFoo').then(function (res) { @@ -1211,20 +1255,23 @@ describe('network stubbing', function () { }) it('still works after a cy.visit', function () { - cy.intercept(/foo/, { + const url = uniqueRoute('/foo') + const regexUrl = new RegExp(url) + + cy.intercept(regexUrl, { body: JSON.stringify({ foo: 'bar' }), headers: { 'content-type': 'application/json', }, }).as('getFoo').visit('http://localhost:3500/fixtures/jquery.html').window().then(function (win) { return new Promise(function (resolve) { - $.get('/foo').done(_.ary(resolve, 0)) + $.get(url).done(_.ary(resolve, 0)) }) - }).wait('@getFoo').its('request.url').should('include', '/foo').visit('http://localhost:3500/fixtures/generic.html').window().then(function (win) { + }).wait('@getFoo').its('request.url').should('include', url).visit('http://localhost:3500/fixtures/generic.html').window().then(function (win) { return new Promise(function (resolve) { - $.get('/foo').done(_.ary(resolve, 0)) + $.get(url).done(_.ary(resolve, 0)) }) - }).wait('@getFoo').its('request.url').should('include', '/foo') + }).wait('@getFoo').its('request.url').should('include', url) }) // @see https://github.com/cypress-io/cypress/issues/15841 @@ -1922,10 +1969,11 @@ describe('network stubbing', function () { context('can end response', () => { for (const eventName of ['before:response', 'response']) { it(`in \`${eventName}\``, () => { + const url = uniqueRoute('/foo') const expectBeforeResponse = eventName === 'response' let beforeResponseCalled = false - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.on('response', (res) => { throw new Error('response should not be reached') }) @@ -1938,7 +1986,7 @@ describe('network stubbing', function () { } }) }).as('first') - .intercept('/foo*', (req) => { + .intercept(`${url}*`, (req) => { // @ts-ignore req.on(eventName, (res) => { res.send({ @@ -1948,7 +1996,7 @@ describe('network stubbing', function () { }) }).as('second') .then(() => { - return $.getJSON('/foo') + return $.getJSON(url) }) .should('include', { 'foo': 1 }) .wait('@first').wait('@second') @@ -1961,27 +2009,31 @@ describe('network stubbing', function () { context('errors', function () { it('when unknown eventName is passed', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.contain('An invalid event name was passed as the first parameter to \`req.on()\`.') done() }) - cy.intercept('/foo', function (req) { + cy.intercept(url, function (req) { // @ts-ignore req.on('totally-bad', _.noop) - }).visit('/foo') + }).visit(url) }) it('when no function is passed', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.contain('\`req.on()\` requires the second parameter to be a function.') done() }) - cy.intercept('/foo', function (req) { + cy.intercept(url, function (req) { // @ts-ignore req.on('before:response', false) - }).visit('/foo') + }).visit(url) }) }) }) @@ -2082,6 +2134,8 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/8921 it('with case-insensitive header matching', function () { + const url = uniqueRoute('/foo') + cy.intercept({ headers: { 'X-some-Thing': 'foo', @@ -2090,7 +2144,7 @@ describe('network stubbing', function () { .as('foo') .then(() => { $.get({ - url: '/foo', + url, headers: { 'X-SOME-THING': 'foo', }, @@ -2124,15 +2178,16 @@ describe('network stubbing', function () { context('with `times`', function () { it('only uses each handler N times', function () { + const url = uniqueRoute('/foo') const third = sinon.stub() cy - .intercept({ url: '/foo*', times: 3 }, 'fourth').as('4') - .intercept({ url: '/foo*', times: 2 }, third).as('3') - .intercept({ url: '/foo*', times: 2 }, 'second').as('2') - .intercept({ url: '/foo*', times: 1 }, 'first').as('1') + .intercept({ url: `${url}*`, times: 3 }, 'fourth').as('4') + .intercept({ url: `${url}*`, times: 2 }, third).as('3') + .intercept({ url: `${url}*`, times: 2 }, 'second').as('2') + .intercept({ url: `${url}*`, times: 1 }, 'first').as('1') .then(async () => { - const expectGet = (expected) => $.get('/foo').then((res) => expect(res).to.eq(expected)) + const expectGet = (expected) => $.get(url).then((res) => expect(res).to.eq(expected)) await Promise.mapSeries([ 'first', @@ -2146,7 +2201,7 @@ describe('network stubbing', function () { expect(third).to.be.calledTwice // now that matches are exhausted, it should fall through - await $.get('/foo').catch((xhr) => { + await $.get(url).catch((xhr) => { expect(xhr).to.include({ status: 404, }) @@ -2240,40 +2295,48 @@ describe('network stubbing', function () { context('with StaticResponse shorthand', function () { it('req.reply(body)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply('baz') }) - .then(() => $.get('/foo')) + .then(() => $.get(url)) .should('eq', 'baz') }) it('req.reply(json)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply({ baz: 'quux' }) }) - .then(() => $.getJSON('/foo')) + .then(() => $.getJSON(url)) .should('deep.eq', { baz: 'quux' }) }) it('req.reply(status)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply(777) }) .then(() => { return new Promise((resolve) => { - $.get('/foo').fail((x) => resolve(x.status)) + $.get(url).fail((x) => resolve(x.status)) }) }) .should('eq', 777) }) it('req.reply(status, body)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply(777, 'bar') }) .then(() => { return new Promise((resolve) => { - $.get('/foo').fail((xhr) => resolve(_.pick(xhr, 'status', 'responseText'))) + $.get(url).fail((xhr) => resolve(_.pick(xhr, 'status', 'responseText'))) }) }).should('include', { status: 777, @@ -2282,12 +2345,14 @@ describe('network stubbing', function () { }) it('req.reply(status, json)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply(777, { bar: 'baz' }) }) .then(() => { return new Promise((resolve) => { - $.get('/foo').fail((xhr) => resolve(_.pick(xhr, 'status', 'responseJSON'))) + $.get(url).fail((xhr) => resolve(_.pick(xhr, 'status', 'responseJSON'))) }) }).should('deep.include', { status: 777, @@ -2296,12 +2361,14 @@ describe('network stubbing', function () { }) it('req.reply(status, json, headers)', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply(777, { bar: 'baz' }, { 'x-quux': 'quuz' }) }) .then(() => { return new Promise((resolve) => { - $.get('/foo').fail((xhr) => resolve(_.pick(xhr, 'status', 'responseJSON', 'getAllResponseHeaders'))) + $.get(url).fail((xhr) => resolve(_.pick(xhr, 'status', 'responseJSON', 'getAllResponseHeaders'))) }) }).should('deep.include', { status: 777, @@ -2312,11 +2379,13 @@ describe('network stubbing', function () { }) it('can forceNetworkError', function (done) { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply({ forceNetworkError: true }) }) .then(() => { - $.get('/foo').fail((xhr) => { + $.get(url).fail((xhr) => { expect(xhr).to.include({ status: 0, statusText: 'error', @@ -2392,6 +2461,8 @@ describe('network stubbing', function () { }) it('fails test if an exception is thrown in req handler', function (done) { + const url = uniqueRoute('/foo') + cy.on('fail', (err2) => { expect(err2).to.eq(err) @@ -2400,24 +2471,28 @@ describe('network stubbing', function () { const err = new Error('bar') - cy.intercept('/foo', () => { + cy.intercept(url, () => { throw err - }).visit('/foo') + }).visit(url) }) it('fails test if req.reply is called with an invalid StaticResponse', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.contain('must be a number between 100 and 999 (inclusive).') done() }) - cy.intercept('/foo', (req) => { + cy.intercept(url, (req) => { req.reply({ statusCode: 1 }) - }).visit('/foo') + }).visit(url) }) it('can timeout in request handler', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { Cypress.config('defaultCommandTimeout', 5000) expect(err.message).to.match(/^A request callback passed to `cy.intercept\(\)` timed out after returning a Promise that took more than the `defaultCommandTimeout` of `50ms` to resolve\./) @@ -2427,9 +2502,9 @@ describe('network stubbing', function () { Cypress.config('defaultCommandTimeout', 50) - cy.intercept('/foo', () => { + cy.intercept(url, () => { return Promise.delay(200) - }).visit('/foo') + }).visit(url) }) }) @@ -2966,7 +3041,9 @@ describe('network stubbing', function () { }) it('res.send({ fixture })', function () { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply((res) => { res.send({ statusCode: 200, @@ -2975,19 +3052,21 @@ describe('network stubbing', function () { }) }) .then(() => { - return $.getJSON('/foo') + return $.getJSON(url) }) .should('include', { foo: 1 }) }) it('can forceNetworkError', function (done) { - cy.intercept('/foo*', function (req) { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, function (req) { req.reply((res) => { res.send({ forceNetworkError: true }) }) }) .then(() => { - $.get('/foo').fail((xhr) => { + $.get(url).fail((xhr) => { expect(xhr).to.include({ status: 0, statusText: 'error', @@ -3073,6 +3152,8 @@ describe('network stubbing', function () { }) it('fails test if an exception is thrown in res handler', function (done) { + const url = uniqueRoute('/foo') + cy.on('fail', (err2) => { expect(err2).to.eq(err) done() @@ -3080,31 +3161,33 @@ describe('network stubbing', function () { const err = new Error('bar') - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.reply(() => { throw err }) }) .then(() => { - $.get('/foo') + $.get(url) }) .wait(1000) }) it('fails test if res.send is called with an invalid StaticResponse', function (done) { + const url = uniqueRoute('/foo') + testFail((err) => { expect(err.message).to.include('must be a number between 100 and 999 (inclusive).') done() }) - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.reply((res) => { res.send({ statusCode: 1 }) }) }) .then(() => { - $.get('/foo') + $.get(url) }) }) @@ -3189,127 +3272,147 @@ describe('network stubbing', function () { const testFailWaiting = (cb) => testFail(cb, 'https://on.cypress.io/wait') it('can wait on a single response using "alias"', function () { - cy.intercept('/foo*', 'bar') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, 'bar') .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar') }) it('can timeout waiting on a single response using "alias"', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('No response ever occurred.') done() }) - cy.intercept('/foo*', () => new Promise(_.noop)) + cy.intercept(`${url}*`, () => new Promise(_.noop)) .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar', { timeout: 100 }) }) it('can wait on a single response using "alias.response"', function () { - cy.intercept('/foo*', 'bar') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, 'bar') .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.response') }) it('can timeout waiting on a single response using "alias.response"', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('No response ever occurred.') done() }) - cy.intercept('/foo*', () => new Promise(_.noop)) + cy.intercept(`${url}*`, () => new Promise(_.noop)) .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.response', { timeout: 100 }) }) it('can wait on a single request using "alias.request"', function () { - cy.intercept('/foo*') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`) .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.request') }) it('can timeout waiting on a single request using "alias.request"', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('No request ever occurred.') done() }) - cy.intercept('/foo*') + cy.intercept(`${url}*`) .as('foo.bar') .wait('@foo.bar.request', { timeout: 100 }) }) it('can incrementally wait on responses', function () { - cy.intercept('/foo*', 'bar') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, 'bar') .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar') }) it('can timeout incrementally waiting on responses', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('for the 1st response to the route') done() }) - cy.intercept('/foo*', () => new Promise(_.noop)) + cy.intercept(`${url}*`, () => new Promise(_.noop)) .as('foo.bar') .then(() => { - $.get('/foo') - $.get('/foo') + $.get(url) + $.get(url) }) .wait('@foo.bar', { timeout: 500 }) .wait('@foo.bar', { timeout: 500 }) }) it('can incrementally wait on requests', function () { - cy.intercept('/foo*', (req) => { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, (req) => { req.reply(_.noop) // only request will be received, no response }) .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.request') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.request') }) it('can timeout incrementally waiting on requests', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('for the 2nd request to the route') done() }) - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.reply(_.noop) // only request will be received, no response }) .as('foo.bar') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@foo.bar.request') .wait('@foo.bar.request', { timeout: 100 }) @@ -3391,10 +3494,12 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/9062 it('can spy on a request using forceNetworkError', function () { - cy.intercept('/foo*', { forceNetworkError: true }) + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, { forceNetworkError: true }) .as('err') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@err').should('have.property', 'error') .and('include', { @@ -3416,11 +3521,13 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/16451 it('yields the expected interception when two requests are raced', function () { - cy.intercept('/foo*', { times: 1 }, { delay: 100, body: 'bar' }).as('a') - cy.intercept('/foo*', { times: 1 }, 'foo').as('a') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, { times: 1 }, { delay: 100, body: 'bar' }).as('a') + cy.intercept(`${url}*`, { times: 1 }, 'foo').as('a') cy.then(() => { - $.get('/foo') - $.get('/foo') + $.get(url) + $.get(url) }) .wait('@a').its('response.body').should('eq', 'foo') .wait('@a').its('response.body').should('eq', 'bar') @@ -3429,10 +3536,12 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/9306 context('cy.get(alias)', function () { it('gets the latest Interception by alias', function () { - cy.intercept('/foo*', { bar: 'baz' }).as('alias') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, { bar: 'baz' }).as('alias') .then(() => { - $.get('/foo') - $.get('/foo') + $.get(url) + $.get(url) }) .wait('@alias').wait('@alias').then((interception) => { cy.get('@alias').then((interception2) => { @@ -3443,10 +3552,12 @@ describe('network stubbing', function () { }) it('gets all aliased Interceptions by alias.all', function () { - cy.intercept('/foo*', { bar: 'baz' }).as('alias') + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, { bar: 'baz' }).as('alias') .then(() => { - $.get('/foo') - $.get('/foo') + $.get(url) + $.get(url) }) .wait('@alias').wait('@alias') @@ -3457,11 +3568,12 @@ describe('network stubbing', function () { it('gets indexed Interception by alias.number', function () { let interception + const url = uniqueRoute('/foo') - cy.intercept('/foo*', { bar: 'baz' }).as('alias') + cy.intercept(`${url}*`, { bar: 'baz' }).as('alias') .then(() => { - $.get('/foo') - $.get('/foo') + $.get(url) + $.get(url) }) .wait('@alias').then((_interception) => { interception = _interception @@ -3474,12 +3586,14 @@ describe('network stubbing', function () { }) it('gets per-request aliased Interceptions', function () { - cy.intercept('/foo*', (req) => { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, (req) => { req.alias = 'alias' req.reply({ bar: 'baz' }) }) .then(() => { - $.get('/foo') + $.get(url) }) .wait('@alias').then((interception) => { cy.get('@alias').then((interception2) => { @@ -3490,46 +3604,54 @@ describe('network stubbing', function () { }) it('yields null when no requests have been made', function () { - cy.intercept('/foo').as('foo') + const url = uniqueRoute('/foo') + + cy.intercept(url).as('foo') cy.get('@foo').should('be.null') }) }) context('with an intercepted request', function () { it('can dynamically alias the request', function () { - cy.intercept('/foo*', (req) => { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, (req) => { req.alias = 'fromInterceptor' }) .then(() => { - $.get('/foo') + $.get(url) }) .wait('@fromInterceptor') }) it('can time out on a dynamic alias', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('for the 1st request to the route') done() }) - cy.intercept('/foo', (req) => { + cy.intercept(url, (req) => { req.alias = 'fromInterceptor' }) .wait('@fromInterceptor', { timeout: 100 }) }) it('dynamic aliases are fulfilled before route aliases', function (done) { + const url = uniqueRoute('/foo') + testFailWaiting((err) => { expect(err.message).to.contain('for the 1st request to the route: `fromAs`') done() }) - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.alias = 'fromInterceptor' }) .as('fromAs') .then(() => { - $.get('/foo') + $.get(url) }) .wait('@fromInterceptor') // this will fail - dynamic aliasing maintains the existing wait semantics, including that each request can only be waited once @@ -3537,15 +3659,17 @@ describe('network stubbing', function () { }) it('fulfills both dynamic aliases when two are defined', function () { - cy.intercept('/foo*', (req) => { + const url = uniqueRoute('/foo') + + cy.intercept(`${url}*`, (req) => { req.alias = 'fromInterceptor' }) - .intercept('/foo*', (req) => { + .intercept(`${url}*`, (req) => { expect(req.alias).to.be.undefined req.alias = 'fromInterceptor2' }) .then(() => { - $.get('/foo') + $.get(url) }) .wait('@fromInterceptor') .wait('@fromInterceptor2') @@ -3650,10 +3774,12 @@ describe('network stubbing', function () { // @see https://github.com/cypress-io/cypress/issues/9580 context('overwrite cy.intercept', () => { it('works with an alias by default', () => { + const url = uniqueRoute('/foo') + // sanity test before testing it with the cy.intercept overwrite - cy.intercept('/foo*', 'my value').as('netAlias') + cy.intercept(`${url}*`, 'my value').as('netAlias') .then(() => { - return $.get('/foo') + return $.get(url) }) cy.wait('@netAlias').its('response.body').should('equal', 'my value') @@ -3661,6 +3787,7 @@ describe('network stubbing', function () { it('works with an alias and function', () => { let myInterceptCalled + const url = uniqueRoute('/foo') cy.spy(cy, 'log') @@ -3672,9 +3799,9 @@ describe('network stubbing', function () { }) }) - cy.intercept('/foo*', 'my value').as('netAlias') + cy.intercept(`${url}*`, 'my value').as('netAlias') .then(() => { - return $.get('/foo') + return $.get(url) }) .then(() => { expect(myInterceptCalled, 'my intercept was called').to.be.true @@ -3686,6 +3813,7 @@ describe('network stubbing', function () { it('works with an alias and arrow function', () => { let myInterceptCalled + const url = uniqueRoute('/foo') cy.spy(cy, 'log') @@ -3697,9 +3825,9 @@ describe('network stubbing', function () { }) }) - cy.intercept('/foo*', 'my value').as('netAlias') + cy.intercept(`${url}*`, 'my value').as('netAlias') .then(() => { - return $.get('/foo') + return $.get(url) }) .then(() => { expect(myInterceptCalled, 'my intercept was called').to.be.true @@ -3711,6 +3839,7 @@ describe('network stubbing', function () { it('works with dynamic alias', () => { let myInterceptCalled + const url = uniqueRoute('/foo') cy.spy(cy, 'log') @@ -3722,12 +3851,12 @@ describe('network stubbing', function () { }) }) - cy.intercept('/foo*', (req) => { + cy.intercept(`${url}*`, (req) => { req.alias = 'netAlias' req.reply('my value') }) .then(() => { - return $.get('/foo') + return $.get(url) }) .then(() => { expect(myInterceptCalled, 'my intercept was called').to.be.true @@ -3758,6 +3887,8 @@ describe('network stubbing', function () { context('unit tests', function () { context('#getDisplayUrlMatcher', function () { + const url = uniqueRoute('/foo') + function testDisplayUrl (title: string, expectedDisplayUrl: string, matcher: Partial) { return it(title, function () { expect(getDisplayUrlMatcher(matcher)).to.eq(expectedDisplayUrl) @@ -3767,8 +3898,8 @@ describe('network stubbing', function () { testDisplayUrl('with only url', 'http://google.net', { url: 'http://google.net' }) testDisplayUrl('with url + method', 'http://google.net', { method: 'GET', url: 'http://google.net' }) testDisplayUrl('with regex url', '/foo/', { url: /foo/ }) - testDisplayUrl('with only path', '/foo', { path: '/foo' }) - testDisplayUrl('with only pathname', '/foo', { pathname: '/foo' }) + testDisplayUrl('with only path', url, { path: url }) + testDisplayUrl('with only pathname', url, { pathname: url }) testDisplayUrl('with host + port', '{hostname: foo.net, port: 1234}', { hostname: 'foo.net', port: 1234 }) testDisplayUrl('with url and query', '{url: http://something, query: {a: b}}', { url: 'http://something', query: { a: 'b' } }) })