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

In Cypress 3.3.0, Cypress.Blob.base64StringToBlob doesn't work with pdf #4253

Closed
Skylsmoi opened this issue May 20, 2019 · 16 comments

Comments

4 participants
@Skylsmoi
Copy link

commented May 20, 2019

Current behavior:

My test simulate a drop event to test React DropZone (https://github.com/react-dropzone/react-dropzone).

The test drop a base 64 encoded with Cypress.Blob.base64StringToBlob pdf into the drop zone.

Since Cypress 3.3.0, the test fails.

The event is triggered but the endpoint that receive the pdf never answers. The process works if done by hand without Cypress so the endpoint works.

I have tested with other file type (png, jpeg ...) and the test works.
It only fails with pdf.

Desired behavior:

The pdf gets encoded properly to be sent in a formData.

Steps to reproduce: (app code and test code)

The Cypress command that encode the file and trigger a drop event:

Cypress.Commands.add('dropFixtureInDropZone', (fixturePath, fixtureMime, dropZoneSelector) => {
  const dropEvent = { dataTransfer: { files: [] } }
  cy.fixture(fixturePath, 'base64').then(fixture => {
    return Cypress.Blob.base64StringToBlob(fixture, fixtureMime).then(blob => {
      dropEvent.dataTransfer.files.push(blob)
    })
  })

  cy.get(dropZoneSelector).trigger('drop', dropEvent)
})

The function that calls it:

export const create_file = (cy, fileTitle = 'newFile') => {
  cy.get('[data-cy=dropdownCreateBtn]').should('be.visible').click()
  cy.get('.show .subdropdown__link__file__icon').should('be.visible').click()

  cy.dropFixtureInDropZone('the_pdf.pdf', 'application/pdf', '.filecontent__form')

  cy.get('[data-cy=popup__createcontent__form__button]')
    .click()

  cy.get('[data-cy="popinFixed"].file')
    .should('be.visible')

  cy.get(`.workspace__content__fileandfolder > .content[title="blob"] .fa.fa-paperclip`)
    .should('be.visible')
}

The test fails at cy.get('[data-cy="popinFixed"].file')).should('be.visible') because since the endpoint doesn't answer, that dom element isn't displayed

Versions

tested in cypress open and cypress run, with electron and chrome in Cypress 3.3.0

@skjnldsv

This comment has been minimized.

Copy link

commented May 20, 2019

Related to #4252
I may have mis-identified my issue :)

@Skylsmoi could it be related to file size?
I get some small gif/svg/png to bass, but no mp4/mkv/big jpg or big png :)

@Skylsmoi

This comment has been minimized.

Copy link
Author

commented May 20, 2019

@skjnldsv Mmh, the pdf I was testing with is 269ko so I don't think so.

@Skylsmoi

This comment has been minimized.

Copy link
Author

commented May 20, 2019

I have checked #4252 and I get the same display in the browser's dev tools Network tab

@jennifer-shehane

This comment has been minimized.

Copy link
Member

commented May 20, 2019

Do either of you have any proxy configuration setup? https://on.cypress.io/proxy-configuration

Can you run cypress run or cypress open with DEBUG logs on and print the output where this failure is occurring? https://on.cypress.io/debugging#Print-DEBUG-logs

@skjnldsv

This comment has been minimized.

Copy link

commented May 20, 2019

Good enough @jennifer-shehane ?
No proxy setup either

  cypress:server:socket backend:request { 
    eventName: 'get:fixture', 
    args: [ 
      'video1.mp4', 
      { 
        encoding: 'base64' 
      } 
    ] 
  } +2s
  cypress:server:timers child received timer id 163 +94ms
  cypress:server:fixture fixture exact name exists /home/admin/Docker/apps2/viewer/cypress/fixtures/video1.mp4 +2m
  cypress:server:server Getting remote state: { 
    auth: null, 
    props: { 
      port: '8000', tld: 'localhost', domain: '' 
    }, 
    origin: 'http://localhost:8000', 
    strategy: 'http', 
    visiting: false, 
    domainName: 'localhost', 
    fileServer: null 
  } +641ms
  cypress:server:proxy handling proxied request { 
    url: '/remote.php/webdav/video1.mp4', 
    proxiedUrl: 'http://localhost:8000/remote.php/webdav/video1.mp4', 
    headers: { 
      host: 'localhost:8000', 
      'proxy-connection': 'keep-alive', 
      'content-length': '1412863', 
      accept: 'application/json, text/plain, */*', 
      requesttoken: 'mG7sSMa2wwH+YSkamIm5HYdYWxdSqcOLTt7EjhfypMk=:8QemC/OFkEe3SnBp7c7cUOgTDUQx3bH9NOr9+1OCw4A=', 
      origin: 'http://localhost:8000', 
      'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.3.0 Chrome/61.0.3163.100 Electron/2.0.18 Safari/537.36', 
      'content-type': 'video/mp4', 
      referer: 'http://localhost:8000/__cypress/iframes/integration/video.mp4.spec.js', 
      'accept-encoding': 'gzip, deflate', 
      'accept-language': 'fr', 
      cookie: 'oc_sessionPassphrase=U4PDuNLIz9KIjxUlCN6c6QrPpD9Gl%2F1K39rpQvb%2BG4XD4xFexTaAOHfffyuiUKym1RXMnHr6w91DHsO9azyh4RCOp%2FoKHf72x5IzM4BQ8J5zdJLRgNC3KrcXp2DF5q3B; nc_sameSiteCookielax=true; nc_sameSiteCookiestrict=true; ocyy42x2ap3d=1rnhh14omat69l1sc77c4tqd9k; nc_username=yxeqxwg; nc_token=PkUxxx0PwKKmY6PLXyO8kbeA%2BDgU78rs; nc_session_id=1rnhh14omat69l1sc77c4tqd9k' 
    }, 
    remoteState: { 
      auth: null, 
      props: { port: '8000', tld: 'localhost', domain: '' }, 
      origin: 'http://localhost:8000', 
      strategy: 'http', 
      visiting: false, 
      domainName: 'localhost', 
      fileServer: null 
    } 
  } +282ms
  cypress:server:stream_buffer extending buffer to accomodate new chunk { 
    bufferLength: 2048, 
    newBufferLength: 65536 
  } +803ms
  cypress:server:stream_buffer appending chunk to buffer { 
    bytesWritten: 0, 
    chunkLength: 64535 
  } +0ms
  cypress:network:agent addRequest called for http://localhost:8000/remote.php/webdav/video1.mp4 +247ms
  cypress:server:timers child sending timer id 162 +2s
  cypress:server:timers clearing timer id 163 from queue { '163': { args: [], ms: 85000, cb: [Function] } } +4s
  cypress:server:timers queuing timer id 164 after 85000 ms +0ms
@Skylsmoi

This comment has been minimized.

Copy link
Author

commented May 20, 2019

No proxy setup

Here is the debug trace that starts right before the command dropFixtureInDropZone in my code above

  cypress:server:timers clearing timer id 88 from queue { '88': { args: [], ms: 85000, cb: [Function] }, '103': { args: [], ms: 85000, cb: [Function] } } +5s
  cypress:server:timers queuing timer id 104 after 85000 ms +0ms
  cypress:server:socket backend:request { eventName: 'get:fixture', args: [ 'the_pdf.pdf', { encoding: 'base64' } ] } +8s
  cypress:server:timers child received timer id 104 +5s
  cypress:server:fixture fixture exact name exists /home/come/repo/tracim/functionnal_tests/cypress/fixtures/the_pdf.pdf +8s
  cypress:server:server Getting remote state: { auth: null, props: { port: '1337', tld: 'localhost', domain: '' }, origin: 'http://localhost:1337', strategy: 'http', visiting: false, domainName: 'localhost', fileServer: null } +6s
  cypress:server:proxy handling proxied request { 
    url: '/api/v2/workspaces/1/files', 
    proxiedUrl: 'http://localhost:1337/api/v2/workspaces/1/files', 
    headers: { host: 'localhost:1337', 'proxy-connection': 'keep-alive', 'content-length': '269672', accept: 'application/json', origin: 'http://localhost:1337', 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36', 
    'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryr83lSz5ZCq2tVABt', 
    referer: 'http://localhost:1337/ui/workspaces/1/contents/file/new?folder_open=&parent_id=null', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7', cookie: 'lastConnection=1; defaultLanguage=en; session_key=6865f51955b26674a97d5d3439bf13f8cc2b20031a50f3ac46004831a07db4422c67fc48' }, remoteState: { auth: null, props: { port: '1337', tld: 'localhost', domain: '' }, origin: 'http://localhost:1337', strategy: 'http', visiting: false, domainName: 'localhost', fileServer: null } } +6s
  cypress:server:stream_buffer extending buffer to accomodate new chunk { bufferLength: 2048, newBufferLength: 65536 } +0ms
  cypress:server:stream_buffer appending chunk to buffer { bytesWritten: 0, chunkLength: 64820 } +1ms
  cypress:network:agent addRequest called for http://localhost:1337/api/v2/workspaces/1/files +6s
@jennifer-shehane

This comment has been minimized.

Copy link
Member

commented May 20, 2019

@Skylsmoi I see the file upload is on a 'content-type': 'multipart/form-data;, I think this may be related to this existing issue. #4240 But...also, @flotwig's issue indicated that this only happens on localhost using https, which I see doesn't seem to be the case for you.

@skjnldsv Not sure if these issues are related still tbh. We'll likely need @flotwig's eyes on it, but the best information you can provide for us is a completely reproducible example of the problem so we can run it locally.

@skjnldsv

This comment has been minimized.

Copy link

commented May 20, 2019

@jennifer-shehane is my repo tests acceptable enough for you to test?
Or do you need something more dedicated and created for this issue only?

@jennifer-shehane

This comment has been minimized.

Copy link
Member

commented May 20, 2019

@skjnldsv Something more simplified would be best, since we don't have NextCloud setup - may take a while to get is all running.

Ideally just providing an index.html with simplified html + javascript and a test visiting index.html that fails (or a publicly available url). You can clone https://github.com/cypress-io/cypress-test-tiny as a starter repo for this.

@skjnldsv

This comment has been minimized.

Copy link

commented May 20, 2019

@jennifer-shehane local test is built on a all-in one docker with nextcloud in it, so it's just two commands to run :)

@jennifer-shehane

This comment has been minimized.

Copy link
Member

commented May 20, 2019

@skjnldsv k, document the commands to get it running and we'll take a look.

@flotwig

This comment has been minimized.

Copy link
Member

commented May 20, 2019

I've gotten this to reproduce in 3.3.0. This is starting to look like a duplicate of #4240, so I'll close this issue and we can continue discussion there.

@flotwig flotwig closed this May 20, 2019

@flotwig flotwig self-assigned this May 20, 2019

flotwig added a commit that referenced this issue May 20, 2019

@skjnldsv

This comment has been minimized.

Copy link

commented May 20, 2019

@jennifer-shehane shall we reopen #4252 then?
I added the steps to reproduce there :)

@flotwig

This comment has been minimized.

Copy link
Member

commented May 20, 2019

@skjnldsv That also looks like a duplicate of #4240, so no need to re-open for now

@cypress-bot

This comment has been minimized.

Copy link

commented May 22, 2019

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

brian-mann added a commit that referenced this issue May 22, 2019

Fix sending forms with large request bodies (#4241)
* add e2e test for submitting forms over https on localhost

* add multipart/form-data test

* add multiparty to parse multipart/form-data streams

* test form submission with attachments

* add repro for #4253

* stream_buffer failing on large body size

* wip: stream buffer fixes

* add eslint + require spec helper

* always cleanup on error and on response

* WIP: continue refactoring stream buffer

- utilize ‘finish’ and ‘chunk’ events to know when to push into
internal readable buffer instead of using `readable.push(‘’)`
- recursively call readable.push(…) until it returns false
- add tests for recursive push calls
- add tests for ensuring readables don’t end until writeable buffer does

* fix remaining tests after stream buffer refactor

* use path.resolve not path.join for handling cy.readFile + cy.writeFile

* consolidate e2e form multipart tests with existing ones

- use env var for passing around path to large earth image
- dynamically fetch large earth.jpg img and gitignore it prior to
running tests
- finish tests + passing implementation

* reader() -> createReadStream()

* guard against reqBodyBuffer being null


Co-authored-by: Brian Mann <brian.mann86@gmail.com>
@cypress-bot

This comment has been minimized.

Copy link

commented May 23, 2019

Released in 3.3.1.

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.