From 2e52a2b68cb7d4b0ad360a21f7cabcabc6334556 Mon Sep 17 00:00:00 2001 From: BlueWinds Date: Mon, 18 Oct 2021 12:10:02 -0700 Subject: [PATCH] Allow explicit null encoding for readFile/writeFile --- .../integration/commands/files_spec.js | 31 +++++++++++++++++++ packages/driver/src/cy/commands/files.ts | 17 +++++++--- packages/server/lib/files.js | 6 ++-- packages/server/test/unit/files_spec.js | 14 +++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/packages/driver/cypress/integration/commands/files_spec.js b/packages/driver/cypress/integration/commands/files_spec.js index 8050db9b1b..3fd24daa89 100644 --- a/packages/driver/cypress/integration/commands/files_spec.js +++ b/packages/driver/cypress/integration/commands/files_spec.js @@ -37,6 +37,21 @@ describe('src/cy/commands/files', () => { }) }) + it('passes explicit null encoding through to server and decodes response', () => { + Cypress.backend.resolves({ + contents: Buffer.from('\n').toString('base64'), + filePath: '/path/to/foo.json', + }) + + cy.readFile('foo.json', null).then(() => { + expect(Cypress.backend).to.be.calledWith( + 'read:file', + 'foo.json', + { encoding: null }, + ) + }).should('eql', Buffer.from('\n')) + }) + it('sets the contents as the subject', () => { Cypress.backend.resolves(okResponse) @@ -340,6 +355,22 @@ describe('src/cy/commands/files', () => { }) }) + it('explicit null encoding is sent to server as base64 string', () => { + Cypress.backend.resolves(okResponse) + + cy.writeFile('foo.txt', Buffer.from([0, 0, 54, 255]), null).then(() => { + expect(Cypress.backend).to.be.calledWith( + 'write:file', + 'foo.txt', + 'AAA2/w==', + { + encoding: 'base64', + flag: 'w', + }, + ) + }) + }) + it('can take encoding as part of options', () => { Cypress.backend.resolves(okResponse) diff --git a/packages/driver/src/cy/commands/files.ts b/packages/driver/src/cy/commands/files.ts index a7d994b25a..3a5ed50469 100644 --- a/packages/driver/src/cy/commands/files.ts +++ b/packages/driver/src/cy/commands/files.ts @@ -11,11 +11,11 @@ export default (Commands, Cypress, cy) => { if (_.isObject(encoding)) { userOptions = encoding - encoding = null + encoding = undefined } options = _.defaults({}, userOptions, { - encoding: encoding != null ? encoding : 'utf8', + encoding: encoding === undefined ? 'utf8' : encoding, log: true, }) @@ -53,6 +53,10 @@ export default (Commands, Cypress, cy) => { args: { cmd: 'readFile', action: 'read', file, filePath: err.filePath, error: err.message }, }) }).then(({ contents, filePath }) => { + if (options.encoding === null) { + contents = Buffer.from(contents, 'base64') + } + consoleProps['File Path'] = filePath consoleProps['Contents'] = contents @@ -85,11 +89,11 @@ export default (Commands, Cypress, cy) => { if (_.isObject(encoding)) { userOptions = encoding - encoding = null + encoding = undefined } options = _.defaults({}, userOptions, { - encoding: encoding ? encoding : 'utf8', + encoding: encoding === undefined ? 'utf8' : encoding, flag: userOptions.flag ? userOptions.flag : 'w', log: true, }) @@ -120,6 +124,11 @@ export default (Commands, Cypress, cy) => { }) } + if (Buffer.isBuffer(contents)) { + contents = contents.toString('base64') + options.encoding = 'base64' + } + if (_.isObject(contents)) { contents = JSON.stringify(contents, null, 2) } diff --git a/packages/server/lib/files.js b/packages/server/lib/files.js index 3cb8a3732c..4b2d96f014 100644 --- a/packages/server/lib/files.js +++ b/packages/server/lib/files.js @@ -6,10 +6,10 @@ module.exports = { const filePath = path.resolve(projectRoot, file) const readFn = path.extname(filePath) === '.json' ? fs.readJsonAsync : fs.readFileAsync - return readFn(filePath, options.encoding || 'utf8') + return readFn(filePath, options.encoding === undefined ? 'utf8' : options.encoding) .then((contents) => { return { - contents, + contents: options.encoding === null ? contents.toString('base64') : contents, filePath, } }) @@ -22,7 +22,7 @@ module.exports = { writeFile (projectRoot, file, contents, options = {}) { const filePath = path.resolve(projectRoot, file) const writeOptions = { - encoding: options.encoding || 'utf8', + encoding: options.encoding === undefined ? 'utf8' : options.encoding, flag: options.flag || 'w', } diff --git a/packages/server/test/unit/files_spec.js b/packages/server/test/unit/files_spec.js index de0a37dc69..c3b3cecba4 100644 --- a/packages/server/test/unit/files_spec.js +++ b/packages/server/test/unit/files_spec.js @@ -41,6 +41,12 @@ describe('lib/files', () => { }) }) + it('explicit null encoding is sent to driver as base64 string', function () { + return files.readFile(this.projectRoot, 'tests/_fixtures/ascii.foo', { encoding: null }).then(({ contents }) => { + expect(contents).to.eql(Buffer.from('\n').toString('base64')) + }) + }) + it('parses json to valid JS object', function () { return files.readFile(this.projectRoot, 'tests/_fixtures/users.json').then(({ contents }) => { expect(contents).to.eql([ @@ -75,6 +81,14 @@ describe('lib/files', () => { }) }) + it('explicit null encoding is read from driver as base64 string', function () { + return files.writeFile(this.projectRoot, '.projects/write_file.txt', Buffer.from(''), { encoding: null }).then(() => { + return files.readFile(this.projectRoot, '.projects/write_file.txt', { encoding: null }).then(({ contents }) => { + expect(contents).to.eql(Buffer.from('').toString('base64')) + }) + }) + }) + it('overwrites existing file by default', function () { return files.writeFile(this.projectRoot, '.projects/write_file.txt', 'foo').then(() => { return files.readFile(this.projectRoot, '.projects/write_file.txt').then(({ contents }) => {