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

feat: Allow explicit null encoding for readFile/writeFile #18534

Merged
merged 16 commits into from Oct 26, 2021

Conversation

BlueWinds
Copy link
Contributor

@BlueWinds BlueWinds commented Oct 18, 2021

User facing changelog

When null is passed as the encoding to cy.readFile(), the file is treated as binary and read as a Buffer. Similarly, null passed as the encoding to cy.writeFile() allows direct writing of buffers.

If encoding is unspecified, the default remains 'utf8', matching current behavior.

Additional details

This should significantly ease the effort of working with binary files from within cypress tests.

As an example:

    cy.writeFile('foo.bin', Buffer.from([0, 0, 12, 54. 255]), { encoding: null })
    cy.readFile('foo.bin', { encoding: null }).should('eql', Buffer.from([0, 0, 12, 54, 255]))

How has the user experience changed?

image
(this screenshot does not exactly match the above example code)

PR Tasks

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Oct 18, 2021

Thanks for taking the time to open a PR!

@BlueWinds BlueWinds changed the title Allow explicit null encoding for readFile/writeFile feat: Allow explicit null encoding for readFile/writeFile Oct 18, 2021
@cypress
Copy link

cypress bot commented Oct 18, 2021



Test summary

4212 0 50 2Flakiness 0


Run details

Project cypress
Status Passed
Commit 5905fdf
Started Oct 25, 2021 8:23 PM
Ended Oct 25, 2021 8:33 PM
Duration 09:43 💡
OS Linux Debian - 10.9
Browser Chrome 95

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@BlueWinds BlueWinds marked this pull request as ready for review October 18, 2021 19:49
@BlueWinds BlueWinds requested a review from a team as a code owner October 18, 2021 19:49
@BlueWinds BlueWinds requested review from mjhenkes, emilyrohrbough, sainthkh and flotwig and removed request for a team, mjhenkes and emilyrohrbough October 18, 2021 19:49
@BlueWinds
Copy link
Contributor Author

I haven't written docs for these changes yet, wanted to get some eyes on it and see if the approach was right before first. @sainthkh, @jennifer-shehane suggested you might be interested in taking a look at these changes.

Copy link
Contributor

@sainthkh sainthkh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello!

The code is good and there are only a few minor changes.

1. User facing changelog

When { encoding: null } is passed to cy.readFile(), the file is treated as binary and read as a Buffer. Similarly, { encoding: null } passed to cy.writeFile() allows direct writing of buffers.

Although { encoding: value } works, it is recommended to pass encoding as the second arg. So, it might be better to change this like:

When null is passed to encoding of cy.readFile(), the file is treated as binary and read as a Buffer. Similarly, null passed to encoding of cy.writeFile() allows direct writing of buffers.

2. Add null to Encodings types.

type Encodings = 'ascii' | 'base64' | 'binary' | 'hex' | 'latin1' | 'utf8' | 'utf-8' | 'ucs2' | 'ucs-2' | 'utf16le' | 'utf-16le'

3. I haven't tested it myself, but it seems that cy.fixture would work correctly if null is given as encoding. I think this should be added to the cy.fixture doc, too. As we all know, this issue started with cy.fixture problem.

@BlueWinds
Copy link
Contributor Author

  1. User facing changelog

When { encoding: null } is passed to cy.readFile(), the file is treated as binary and read as a Buffer. Similarly, { encoding: null } passed to cy.writeFile() allows direct writing of buffers.

Although { encoding: value } works, it is recommended to pass encoding as the second arg. So, it might be better to change this like:

When null is passed to encoding of cy.readFile(), the file is treated as binary and read as a Buffer. Similarly, null passed to encoding of cy.writeFile() allows direct writing of buffers.

Done.

  1. Add null to Encodings types.

type Encodings = 'ascii' | 'base64' | 'binary' | 'hex' | 'latin1' | 'utf8' | 'utf-8' | 'ucs2' | 'ucs-2' | 'utf16le' | 'utf-16le'

Done.

  1. I haven't tested it myself, but it seems that cy.fixture would work correctly if null is given as encoding. I think this should be added to the cy.fixture doc, too. As we all know, this issue started with cy.fixture problem.

It doesn't work with fixtures at the moment. I'll fix it in an upcoming commit here - the behavior should definitely be symetrical between read/writeFile and fixture.

Copy link
Contributor

@sainthkh sainthkh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

I just left a comment about the missing comment.

I don't have authority to commit this PR. So, someone in the team will do the job.

Copy link
Contributor

@sainthkh sainthkh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments should be changed or they'll be unclear.

packages/server/test/unit/fixture_spec.js Outdated Show resolved Hide resolved
sainthkh
sainthkh previously approved these changes Oct 25, 2021
Copy link
Contributor

@sainthkh sainthkh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍

packages/server/lib/files.js Outdated Show resolved Hide resolved
packages/driver/src/cy/commands/files.ts Show resolved Hide resolved
if (options.encoding === null) {
response = Buffer.from(response)
} else if (response instanceof ArrayBuffer) {
// Cypress' behavior is to base64 encode binary files if the user
Copy link
Contributor Author

@BlueWinds BlueWinds Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flotwig - As part of removing the server-side transform of buffers to base64 before transmitting (based on your review, which I 100% agree with), we now have to explicitly do so on the driver side unless a null encoding is specified, in order to maintain backwards compatibility.

In a vacuum it would make more conceptual sense to remove the default of utf8 for undefined encoding (and unknown file types) and base64 encoding for binary files, but that would turn this into a breaking change, so instead I ended up with this fairly messy set of conditionals spread around the driver in order to maintain backwards compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a vacuum it would make more conceptual sense to remove the default of utf8 for undefined encoding (and unknown file types) and base64 encoding for binary files, but that would turn this into a breaking change

Yeah, and I wonder if that breaking change would even be welcome. I would guess that many people are relying on the existing behavior that treats everything as utf8 by default.

if (options.encoding === null) {
response = Buffer.from(response)
} else if (response instanceof ArrayBuffer) {
// Cypress' behavior is to base64 encode binary files if the user
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a vacuum it would make more conceptual sense to remove the default of utf8 for undefined encoding (and unknown file types) and base64 encoding for binary files, but that would turn this into a breaking change

Yeah, and I wonder if that breaking change would even be welcome. I would guess that many people are relying on the existing behavior that treats everything as utf8 by default.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 10, 2021

Released in 9.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v9.0.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Nov 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

reading binary file from fixture differs from drop event file
3 participants