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

str.replace is not a function during cy.request() #2923

Closed
dudeNumber4 opened this issue Dec 10, 2018 · 4 comments

Comments

3 participants
@dudeNumber4
Copy link

commented Dec 10, 2018

Current behavior:

Upon cy.request with a seemingly valid header, following is the stack trace of the error. Note that changing the header key "content-type" to "ContentType" makes the error go away.

TypeError: str.replace is not a function
    at Querystring.rfc3986 (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\lib\querystring.js:43:14)
    at Request.json (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\request.js:1293:30)
    at Request.init (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\request.js:406:10)
    at Request.RP$initInterceptor [as init] (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request-promise-core\configure\request2.js:45:29)
    at new Request (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\request.js:127:8)
    at request (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\index.js:53:10)
    at C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\request\index.js:100:12
    at Object.create (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\lib\request.js:170:18)
    at C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\lib\request.js:364:26
    at tryCatcher (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\promise.js:510:31)
    at Promise._settlePromise (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\promise.js:567:18)
    at Promise._settlePromise0 (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\promise.js:612:10)
    at Promise._settlePromises (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\promise.js:691:18)
    at Async._drainQueue (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\async.js:133:16)
    at Async._drainQueues (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\async.js:143:10)
    at Immediate.Async.drainQueues (C:\Users\Brad Wood\AppData\Local\Cypress\Cache\3.1.3\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\async.js:17:14)
    at runCallback (timers.js:781:20)
    at tryOnImmediate (timers.js:743:5)
    at processImmediate [as _immediateCallback] (timers.js:714:5)

Desired behavior:

Network call made. I realize now that "form":true is the accepted method of setting that content type; still minor bug.

Create this options object:

const options = {
  "method": "POST",
  "url": "some valid url",
  "headers": {
    "Accept": "application/json",
    "content-type": "application/x-www-form-urlencoded"
  },
  "body": {
    "scope": "my_scope"
  }
};

cy.request(options).then // ...

Versions

3.1.3

@jennifer-shehane

This comment has been minimized.

Copy link
Member

commented Jan 28, 2019

I am able to verify this seems like a bug.

Reproducible example

it('throws an error', function () {
  cy.request({
    'method': 'POST',
    'url': 'https://jsonplaceholder.cypress.io/comments',
    'headers': {
      'Accept': 'application/json',
      'content-type': 'application/x-www-form-urlencoded',
    },
    'body': {
      'scope': 'my_scope',
    },
  })
})
@flotwig

This comment has been minimized.

Copy link
Member

commented Feb 8, 2019

This options object also causes an exception when passed to the request library directly: https://runkit.com/embed/hewk0u53ebr6

The root of the issue seems to be that the body is not a string. application/x-www-form-urlencoded expects a urlencoded string to be passed as the body. If you wrap your body in qs.stringify, the request will work fine: https://runkit.com/flotwig/issue-2923-qs This will also fix the exception that arises within Cypress.

If you look at the docs for request options, you'll see the following definition for body, which lines up with what we're seeing here:

body - entity body for PATCH, POST and PUT requests. Must be a Buffer, String or ReadStream. If json is true, then body must be a JSON-serializable object.

request.coffee probably needs to be updated to account for the edge case described in this issue and warn the user that something unexpected is going to happen.

@cypress-bot

This comment has been minimized.

Copy link

commented Apr 1, 2019

The code for this is done in cypress-io/cypress#3440, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot

This comment has been minimized.

Copy link

commented May 17, 2019

Released in 3.3.0.

@jennifer-shehane jennifer-shehane changed the title Error upon request str.replace is not a function during cy.request() Jun 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.