Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into issue-6407-warn-for-read-only-properties
Browse files Browse the repository at this point in the history
davidmunechika authored Dec 10, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents abfabc0 + f79bdd6 commit de7b436
Showing 28 changed files with 1,378 additions and 1,367 deletions.
13 changes: 3 additions & 10 deletions cli/types/cypress.d.ts
Original file line number Diff line number Diff line change
@@ -2209,12 +2209,9 @@ declare namespace Cypress {
* @see https://on.cypress.io/writefile
```
cy.writeFile('path/to/message.txt', 'Hello World')
.then((text) => {
expect(text).to.equal('Hello World') // true
})
```
*/
writeFile<C extends FileContents>(filePath: string, contents: C, encoding: Encodings): Chainable<C>
writeFile(filePath: string, contents: FileContents, encoding: Encodings): Chainable<null>
/**
* Write to a file with the specified encoding and contents.
*
@@ -2223,12 +2220,10 @@ declare namespace Cypress {
cy.writeFile('path/to/ascii.txt', 'Hello World', {
flag: 'a+',
encoding: 'ascii'
}).then((text) => {
expect(text).to.equal('Hello World') // true
})
```
*/
writeFile<C extends FileContents>(filePath: string, contents: C, options?: Partial<WriteFileOptions>): Chainable<C>
writeFile(filePath: string, contents: FileContents, options?: Partial<WriteFileOptions & Timeoutable>): Chainable<null>
/**
* Write to a file with the specified encoding and contents.
*
@@ -2238,12 +2233,10 @@ declare namespace Cypress {
```
cy.writeFile('path/to/ascii.txt', 'Hello World', 'utf8', {
flag: 'a+',
}).then((text) => {
expect(text).to.equal('Hello World') // true
})
```
*/
writeFile<C extends FileContents>(filePath: string, contents: C, encoding: Encodings, options?: Partial<WriteFileOptions>): Chainable<C>
writeFile(filePath: string, contents: FileContents, encoding: Encodings, options?: Partial<WriteFileOptions & Timeoutable>): Chainable<null>

/**
* jQuery library bound to the AUT
100 changes: 99 additions & 1 deletion packages/driver/cypress/integration/commands/files_spec.js
Original file line number Diff line number Diff line change
@@ -145,6 +145,7 @@ describe('src/cy/commands/files', () => {
if (attrs.name === 'readFile') {
expect(log.get('state')).to.eq('pending')
expect(log.get('message')).to.eq('foo.json')
expect(log.get('timeout')).to.eq(Cypress.config('defaultCommandTimeout'))
}
})

@@ -321,6 +322,54 @@ describe('src/cy/commands/files', () => {

cy.readFile('foo.json').should('equal', 'contents')
})

it('throws when the read timeout expires', function (done) {
Cypress.backend.callsFake(() => {
return new Cypress.Promise(() => { /* Broken promise for timeout */ })
})

cy.on('fail', (err) => {
const { lastLog } = this

assertLogLength(this.logs, 1)
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq(stripIndent`\
\`cy.readFile("foo")\` timed out after waiting \`10ms\`.
`)

expect(err.docsUrl).to.eq('https://on.cypress.io/readfile')

done()
})

cy.readFile('foo', { timeout: 10 })
})

it('uses defaultCommandTimeout config value if option not provided', {
defaultCommandTimeout: 42,
}, function (done) {
Cypress.backend.callsFake(() => {
return new Cypress.Promise(() => { /* Broken promise for timeout */ })
})

cy.on('fail', (err) => {
const { lastLog } = this

assertLogLength(this.logs, 1)
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq(stripIndent`\
\`cy.readFile("foo")\` timed out after waiting \`42ms\`.
`)

expect(err.docsUrl).to.eq('https://on.cypress.io/readfile')

done()
})

cy.readFile('foo')
})
})
})

@@ -394,7 +443,7 @@ describe('src/cy/commands/files', () => {
Cypress.backend.resolves(okResponse)

cy.writeFile('foo.txt', 'contents').then((subject) => {
expect(subject).to.not.exist
expect(subject).to.eq(null)
})
})

@@ -481,6 +530,7 @@ describe('src/cy/commands/files', () => {
if (attrs.name === 'writeFile') {
expect(log.get('state')).to.eq('pending')
expect(log.get('message')).to.eq('foo.txt', 'contents')
expect(log.get('timeout')).to.eq(Cypress.config('defaultCommandTimeout'))
}
})

@@ -601,6 +651,54 @@ describe('src/cy/commands/files', () => {

cy.writeFile('foo.txt', 'contents')
})

it('throws when the write timeout expires', function (done) {
Cypress.backend.callsFake(() => {
return new Cypress.Promise(() => {})
})

cy.on('fail', (err) => {
const { lastLog } = this

assertLogLength(this.logs, 1)
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq(stripIndent`
\`cy.writeFile("foo.txt")\` timed out after waiting \`10ms\`.
`)

expect(err.docsUrl).to.eq('https://on.cypress.io/writefile')

done()
})

cy.writeFile('foo.txt', 'contents', { timeout: 10 })
})

it('uses defaultCommandTimeout config value if option not provided', {
defaultCommandTimeout: 42,
}, function (done) {
Cypress.backend.callsFake(() => {
return new Cypress.Promise(() => { /* Broken promise for timeout */ })
})

cy.on('fail', (err) => {
const { lastLog } = this

assertLogLength(this.logs, 1)
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq(stripIndent`
\`cy.writeFile("foo.txt")\` timed out after waiting \`42ms\`.
`)

expect(err.docsUrl).to.eq('https://on.cypress.io/writefile')

done()
})

cy.writeFile('foo.txt', 'contents')
})
})
})
})
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ describe('src/cy/commands/request', () => {
followRedirect: true,
timeout: RESPONSE_TIMEOUT,
method: 'GET',
retryIntervals: [0, 100, 200, 200],
})

const options = backend.firstCall.args[1]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash'
import $Command from '../../../src/cypress/command'
import $CommandQueue from '../../../src/cypress/command_queue'
import { CommandQueue } from '../../../src/cypress/command_queue'

const createCommand = (props = {}) => {
return $Command.create(_.extend({
@@ -23,14 +23,14 @@ const log = (props = {}) => {
describe('src/cypress/command_queue', () => {
let queue
const state = () => {}
const timeouts = { timeout () {} }
const stability = { whenStable () {} }
const timeout = () => {}
const whenStable = () => {}
const cleanup = () => {}
const fail = () => {}
const isCy = () => {}

beforeEach(() => {
queue = $CommandQueue.create(state, timeouts, stability, cleanup, fail, isCy)
queue = new CommandQueue(state, timeout, whenStable, cleanup, fail, isCy)

queue.add(createCommand({
name: 'get',
4 changes: 2 additions & 2 deletions packages/driver/cypress/integration/util/queue_spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import Bluebird from 'bluebird'

import $Queue from '../../../src/util/queue'
import { Queue } from '../../../src/util/queue'

const ids = (queueables) => queueables.map((q) => q.id)

describe('src/util/queue', () => {
let queue

beforeEach(() => {
queue = $Queue.create([
queue = new Queue([
{ id: '1' },
{ id: '2' },
{ id: '3' },
59 changes: 39 additions & 20 deletions packages/driver/src/cy/commands/files.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @ts-nocheck
import _ from 'lodash'
import Promise from 'bluebird'

import $errUtils from '../../cypress/error_utils'

@@ -22,6 +21,7 @@ export default (Commands, Cypress, cy) => {
// to restore the default node behavior.
encoding: encoding === undefined ? 'utf8' : encoding,
log: true,
timeout: Cypress.config('defaultCommandTimeout'),
})

const consoleProps = {}
@@ -43,21 +43,33 @@ export default (Commands, Cypress, cy) => {
})
}

// We clear the default timeout so we can handle
// the timeout ourselves
cy.clearTimeout()

const verifyAssertions = () => {
return Cypress.backend('read:file', file, _.pick(options, 'encoding'))
return Cypress.backend('read:file', file, _.pick(options, 'encoding')).timeout(options.timeout)
.catch((err) => {
if (err.code === 'ENOENT') {
return {
contents: null,
filePath: err.filePath,
}
if (err.name === 'TimeoutError') {
return $errUtils.throwErrByPath('files.timed_out', {
onFail: options._log,
args: { cmd: 'readFile', file, timeout: options.timeout },
})
}

return $errUtils.throwErrByPath('files.unexpected_error', {
onFail: options._log,
args: { cmd: 'readFile', action: 'read', file, filePath: err.filePath, error: err.message },
})
}).then(({ contents, filePath }) => {
// Non-ENOENT errors are not retried
if (err.code !== 'ENOENT') {
return $errUtils.throwErrByPath('files.unexpected_error', {
onFail: options._log,
args: { cmd: 'readFile', action: 'read', file, filePath: err.filePath, error: err.message },
})
}

return {
contents: null,
filePath: err.filePath,
}
}).then(({ filePath, contents }) => {
// https://github.com/cypress-io/cypress/issues/1558
// We invoke Buffer.from() in order to transform this from an ArrayBuffer -
// which socket.io uses to transfer the file over the websocket - into a
@@ -110,14 +122,15 @@ export default (Commands, Cypress, cy) => {
encoding: encoding === undefined ? 'utf8' : encoding,
flag: userOptions.flag ? userOptions.flag : 'w',
log: true,
timeout: Cypress.config('defaultCommandTimeout'),
})

const consoleProps = {}

if (options.log) {
options._log = Cypress.log({
message: fileName,
timeout: 0,
timeout: options.timeout,
consoleProps () {
return consoleProps
},
@@ -142,19 +155,25 @@ export default (Commands, Cypress, cy) => {
contents = JSON.stringify(contents, null, 2)
}

return Cypress.backend('write:file', fileName, contents, _.pick(options, ['encoding', 'flag']))
.then(({ contents, filePath }) => {
// We clear the default timeout so we can handle
// the timeout ourselves
cy.clearTimeout()

return Cypress.backend('write:file', fileName, contents, _.pick(options, 'encoding', 'flag')).timeout(options.timeout)
.then(({ filePath, contents }) => {
consoleProps['File Path'] = filePath
consoleProps['Contents'] = contents

return null
}).catch(Promise.TimeoutError, () => {
return $errUtils.throwErrByPath('files.timed_out', {
onFail: options._log,
args: { cmd: 'writeFile', file: fileName, timeout: options.timeout },
})
})
.catch((err) => {
if (err.name === 'TimeoutError') {
return $errUtils.throwErrByPath('files.timed_out', {
onFail: options._log,
args: { cmd: 'writeFile', file: fileName, timeout: options.timeout },
})
}

return $errUtils.throwErrByPath('files.unexpected_error', {
onFail: options._log,
args: { cmd: 'writeFile', action: 'write', file: fileName, filePath: err.filePath, error: err.message },
3 changes: 2 additions & 1 deletion packages/driver/src/cy/commands/navigation.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ let hasVisitedAboutBlank = null
let currentlyVisitingAboutBlank = null
let knownCommandCausedInstability = null

const REQUEST_URL_OPTS = 'auth failOnStatusCode retryOnNetworkFailure retryOnStatusCodeFailure method body headers'
const REQUEST_URL_OPTS = 'auth failOnStatusCode retryOnNetworkFailure retryOnStatusCodeFailure retryIntervals method body headers'
.split(' ')

const VISIT_OPTS = 'url log onBeforeLoad onLoad timeout requestTimeout'
@@ -712,6 +712,7 @@ export default (Commands, Cypress, cy, state, config) => {
failOnStatusCode: true,
retryOnNetworkFailure: true,
retryOnStatusCodeFailure: false,
retryIntervals: [0, 100, 200, 200],
method: 'GET',
body: null,
headers: {},
1 change: 1 addition & 0 deletions packages/driver/src/cy/commands/request.ts
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ const REQUEST_DEFAULTS = {
timeout: null,
followRedirect: true,
failOnStatusCode: true,
retryIntervals: [0, 100, 200, 200],
retryOnNetworkFailure: true,
retryOnStatusCodeFailure: false,
}
8 changes: 2 additions & 6 deletions packages/driver/src/cypress.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import browserInfo from './cypress/browser'
import $scriptUtils from './cypress/script_utils'

import $Commands from './cypress/commands'
import $Cy from './cypress/cy'
import { $Cy } from './cypress/cy'
import $dom from './dom'
import $Downloads from './cypress/downloads'
import $errorMessages from './cypress/error_messages'
@@ -227,12 +227,8 @@ class $Cypress {
// or parsed. we have not received any custom commands
// at this point
onSpecWindow (specWindow, scripts) {
const logFn = (...args) => {
return this.log.apply(this, args)
}

// create cy and expose globally
this.cy = $Cy.create(specWindow, this, this.Cookies, this.state, this.config, logFn)
this.cy = new $Cy(specWindow, this, this.Cookies, this.state, this.config)
window.cy = this.cy
this.isCy = this.cy.isCy
this.log = $Log.create(this, this.cy, this.state, this.config)
Loading

0 comments on commit de7b436

Please sign in to comment.