From d62e2b663404a9ec549374d86448aa5ea6419277 Mon Sep 17 00:00:00 2001 From: Eelke Boezeman Date: Wed, 17 Apr 2019 07:54:11 +0200 Subject: [PATCH 1/5] add `matcher` option to cy.route --- packages/driver/src/cypress/server.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/driver/src/cypress/server.coffee b/packages/driver/src/cypress/server.coffee index 22dcf0761b56..96af763f96d8 100644 --- a/packages/driver/src/cypress/server.coffee +++ b/packages/driver/src/cypress/server.coffee @@ -272,6 +272,7 @@ create = (options = {}) -> testStr(fullyQualifiedUrl, options.stripOrigin(fullyQualifiedUrl)) xhrMatchesRoute: (xhr, route) -> + return route.matcher(xhr, route) if _.isFunction(route.matcher) server.methodsMatch(route.method, xhr.method) and server.urlsMatch(route.url, xhr.url) add: (xhr, attrs = {}) -> From 432ae9826c341fecdd304c2a2a6b064c290d41c4 Mon Sep 17 00:00:00 2001 From: Eelke Boezeman Date: Fri, 3 May 2019 08:05:08 +0200 Subject: [PATCH 2/5] fix options validation - matcher trumps url - non-func matcher throws error --- packages/driver/src/cy/commands/xhr.coffee | 13 ++++++++----- packages/driver/src/cypress/error_messages.coffee | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/driver/src/cy/commands/xhr.coffee b/packages/driver/src/cy/commands/xhr.coffee index 1a9ff4b74062..1b2b7fe228fb 100644 --- a/packages/driver/src/cy/commands/xhr.coffee +++ b/packages/driver/src/cy/commands/xhr.coffee @@ -358,11 +358,14 @@ module.exports = (Commands, Cypress, cy, state, config) -> _.defaults(options, defaults) - if not options.url - $utils.throwErrByPath "route.url_missing" - - if not (_.isString(options.url) or _.isRegExp(options.url)) - $utils.throwErrByPath "route.url_invalid" + if options.matcher + if not _.isFunction(options.matcher) + $utils.throwErrByPath "route.matcher_invalid" + else + if not options.url + $utils.throwErrByPath "route.url_missing" + if not (_.isString(options.url) or _.isRegExp(options.url)) + $utils.throwErrByPath "route.url_invalid" if not $utils.isValidHttpMethod(options.method) $utils.throwErrByPath "route.method_invalid", { diff --git a/packages/driver/src/cypress/error_messages.coffee b/packages/driver/src/cypress/error_messages.coffee index d7594354817c..eaa15a9b2013 100644 --- a/packages/driver/src/cypress/error_messages.coffee +++ b/packages/driver/src/cypress/error_messages.coffee @@ -689,6 +689,7 @@ module.exports = { route: failed_prerequisites: "#{cmd('route')} cannot be invoked before starting the #{cmd('server')}" invalid_arguments: "#{cmd('route')} was not provided any arguments. You must provide valid arguments." + matcher_invalid: "#{cmd('route')} was called with an invalid matcher option: matcher must be a Function that returns a Boolean." method_invalid: "#{cmd('route')} was called with an invalid method: '{{method}}'. Method can be: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, or any other method supported by Node's HTTP parser." response_invalid: "#{cmd('route')} cannot accept an undefined or null response. It must be set to something, even an empty string will work." url_invalid: "#{cmd('route')} was called with an invalid url. Url must be either a string or regular expression." From 1bffa7a84f13f64116da2573925e917f23fe150e Mon Sep 17 00:00:00 2001 From: Eelke Boezeman Date: Fri, 3 May 2019 08:10:18 +0200 Subject: [PATCH 3/5] add cy.route tests to xhr spec --- .../integration/commands/xhr_spec.coffee | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee index 87501f75bdc1..e33ac3b0e32e 100644 --- a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee +++ b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee @@ -1204,6 +1204,58 @@ describe "src/cy/commands/xhr", -> response: {} }) + it "accepts matcher option", -> + matcher = () => true + response = { foo: true } + + cy.route({ + matcher, + response, + }).then -> + @expectOptionsToBe({ + matcher, + status: 200, + response + }) + + it "throws an error when matcher option is not a function", -> + cy.route({ + matcher: 'foo', + }); + cy.on "fail", (err) -> expect(err.message).to.eq( + "cy.route() was called with an invalid matcher option: matcher must be a Function that returns a Boolean." + ) + + it "passes both xhr and options arguments to matcher option function", -> + cy + .window() + .then (win) -> + options = { + matcher: (xhr, _options) => + expect(xhr instanceof win.XMLHttpRequest).to.be.true + expect(_options.matcher).to.eq(options.matcher) + expect(_options.response).to.eq(options.response) + response: 'foo', + } + cy + .route(options) + .window().then (win) -> + win.$.get("/foo") + + it "ignores url when matcher option is present", -> + cy + .route({ + url: "/bar" + matcher: (xhr, options) => /foo/.test(xhr.url) + response: 'foo', + }).as("getFoo") + .window().then (win) -> + win.$.get("/bar").catch((response) -> expect(response.status == 404)) + .window().then (win) -> + win.$.get("/foo") + .wait("@getFoo").then (xhr) -> + expect(xhr.responseBody).to.eq 'foo' + ## FIXME it.skip "can explicitly done() in onRequest function from options", (done) -> cy From 5e6e23afbc94b25219f703a54977f31a672f68bb Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Tue, 7 May 2019 10:49:54 -0400 Subject: [PATCH 4/5] add test for matcher receiving request body --- .../integration/commands/xhr_spec.coffee | 131 +++++++++++------- 1 file changed, 79 insertions(+), 52 deletions(-) diff --git a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee index e33ac3b0e32e..bf79dfbb34f9 100644 --- a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee +++ b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee @@ -1204,58 +1204,6 @@ describe "src/cy/commands/xhr", -> response: {} }) - it "accepts matcher option", -> - matcher = () => true - response = { foo: true } - - cy.route({ - matcher, - response, - }).then -> - @expectOptionsToBe({ - matcher, - status: 200, - response - }) - - it "throws an error when matcher option is not a function", -> - cy.route({ - matcher: 'foo', - }); - cy.on "fail", (err) -> expect(err.message).to.eq( - "cy.route() was called with an invalid matcher option: matcher must be a Function that returns a Boolean." - ) - - it "passes both xhr and options arguments to matcher option function", -> - cy - .window() - .then (win) -> - options = { - matcher: (xhr, _options) => - expect(xhr instanceof win.XMLHttpRequest).to.be.true - expect(_options.matcher).to.eq(options.matcher) - expect(_options.response).to.eq(options.response) - response: 'foo', - } - cy - .route(options) - .window().then (win) -> - win.$.get("/foo") - - it "ignores url when matcher option is present", -> - cy - .route({ - url: "/bar" - matcher: (xhr, options) => /foo/.test(xhr.url) - response: 'foo', - }).as("getFoo") - .window().then (win) -> - win.$.get("/bar").catch((response) -> expect(response.status == 404)) - .window().then (win) -> - win.$.get("/foo") - .wait("@getFoo").then (xhr) -> - expect(xhr.responseBody).to.eq 'foo' - ## FIXME it.skip "can explicitly done() in onRequest function from options", (done) -> cy @@ -1384,6 +1332,77 @@ describe "src/cy/commands/xhr", -> url: /foo/ respond: false + describe "matcher option", -> + it "accepts matcher option", -> + matcher = () => true + response = { foo: true } + + cy.route({ + matcher, + response, + }).then -> + @expectOptionsToBe({ + matcher, + status: 200, + response + }) + + it "passes both xhr and options arguments to matcher option function", -> + cy + .window() + .then (win) -> + options = { + matcher: (xhr, _options) => + expect(xhr instanceof win.XMLHttpRequest).to.be.true + expect(_options.matcher).to.eq(options.matcher) + expect(_options.response).to.eq(options.response) + response: 'foo', + } + cy + .route(options) + .window().then (win) -> + win.$.get("/foo") + + it "receives request body in matcher", -> + options = { + matcher: (xhr) => + debugger + expect(xhr.body).to.eq('baz') + } + + cy + .route(options) + .window().then (win) -> + win.$.post("/foo", "baz") + + it "ignores url when matcher option is present", -> + cy + .route({ + url: "/bar" + matcher: (xhr, options) => /foo/.test(xhr.url) + response: 'foo', + }).as("getFoo") + .window().then (win) -> + win.$.get("/bar").catch((response) -> expect(response.status == 404)) + .window().then (win) -> + win.$.get("/foo") + .wait("@getFoo").then (xhr) -> + expect(xhr.responseBody).to.eq 'foo' + + it "ignores url when matcher option is present", -> + cy + .route({ + url: "/bar" + matcher: (xhr, options) => /foo/.test(xhr.url) + response: 'foo', + }).as("getFoo") + .window().then (win) -> + win.$.get("/bar").catch((response) -> expect(response.status == 404)) + .window().then (win) -> + win.$.get("/foo") + .wait("@getFoo").then (xhr) -> + expect(xhr.responseBody).to.eq 'foo' + describe "deprecations", -> beforeEach -> @warn = cy.spy(window.top.console, "warn") @@ -1494,6 +1513,14 @@ describe "src/cy/commands/xhr", -> cy.route(getUrl) + it "fails when matcher option is not a function", -> + cy.route({ + matcher: 'foo', + }) + + cy.on "fail", (err) -> + expect(err.message).to.eq "cy.route() was called with an invalid matcher option: matcher must be a Function that returns a Boolean." + it "fails when functions reject", (done) -> error = new Error From 09ef88d780b924c174e12573a9369b62cb586a69 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Tue, 7 May 2019 10:53:58 -0400 Subject: [PATCH 5/5] -debugger --- .../driver/test/cypress/integration/commands/xhr_spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee index bf79dfbb34f9..4ea7c1461a1d 100644 --- a/packages/driver/test/cypress/integration/commands/xhr_spec.coffee +++ b/packages/driver/test/cypress/integration/commands/xhr_spec.coffee @@ -1366,7 +1366,6 @@ describe "src/cy/commands/xhr", -> it "receives request body in matcher", -> options = { matcher: (xhr) => - debugger expect(xhr.body).to.eq('baz') }