diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 2e576727860b..b76af718c3c5 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -2519,7 +2519,7 @@ declare namespace Cypress { action: 'select' | 'drag-drop' } - interface BlurOptions extends Loggable, Forceable { } + interface BlurOptions extends Loggable, Timeoutable, Forceable { } interface CheckOptions extends Loggable, Timeoutable, ActionableOptions { interval: number diff --git a/packages/driver/cypress/integration/commands/screenshot_spec.js b/packages/driver/cypress/integration/commands/screenshot_spec.js index 0045c2a7b24a..acb4837802e8 100644 --- a/packages/driver/cypress/integration/commands/screenshot_spec.js +++ b/packages/driver/cypress/integration/commands/screenshot_spec.js @@ -761,9 +761,9 @@ describe('src/cy/commands/screenshot', () => { cy.get('.short-element').within(() => { cy.screenshot({ capture: 'runner' }) }).then(() => { - // the runner was captured - expect(Cypress.action.withArgs('cy:before:screenshot').args[0][1].appOnly).to.be.true - expect(Cypress.automation.withArgs('take:screenshot').args[0][1].capture).to.equal('viewport') + // the runner was captured ("appOnly === true" means to hide the runner UI) + expect(Cypress.action.withArgs('cy:before:screenshot').args[0][1].appOnly).to.be.false + expect(Cypress.automation.withArgs('take:screenshot').args[0][1].capture).to.equal('runner') }) }) diff --git a/packages/driver/src/cy/commands/actions/focus.ts b/packages/driver/src/cy/commands/actions/focus.ts index 5f5bc457a762..e866def4c133 100644 --- a/packages/driver/src/cy/commands/actions/focus.ts +++ b/packages/driver/src/cy/commands/actions/focus.ts @@ -4,16 +4,29 @@ import $dom from '../../../dom' import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import $elements from '../../../dom/elements' +import type { Log } from '../../../cypress/log' + +interface InternalFocusOptions extends Partial { + _log?: Log + $el: JQuery + error: boolean + verify: boolean +} + +interface InternalBlurOptions extends Partial { + _log?: Log + $el: JQuery + $focused: JQuery + error: boolean + verify: boolean +} export default (Commands, Cypress, cy) => { return Commands.addAll({ prevSubject: ['element', 'window'] }, { - // TODO: any -> Partial - focus (subject, options: any = {}) { - const userOptions = options - + focus (subject, userOptions: Partial = {}) { // we should throw errors by default! // but allow them to be silenced - options = _.defaults({}, userOptions, { + const options: InternalFocusOptions = _.defaults({}, userOptions, { $el: subject, error: true, log: true, @@ -85,13 +98,10 @@ export default (Commands, Cypress, cy) => { return verifyAssertions() }, - // TODO: any -> Partial - blur (subject, options: any = {}) { - const userOptions = options - + blur (subject, userOptions: Partial = {}) { // we should throw errors by default! // but allow them to be silenced - options = _.defaults({}, userOptions, { + const options: InternalBlurOptions = _.defaults({}, userOptions, { $el: subject, $focused: cy.getFocused(), error: true, diff --git a/packages/driver/src/cy/commands/actions/scroll.ts b/packages/driver/src/cy/commands/actions/scroll.ts index 48077d99b2eb..f918f0f459a4 100644 --- a/packages/driver/src/cy/commands/actions/scroll.ts +++ b/packages/driver/src/cy/commands/actions/scroll.ts @@ -5,6 +5,7 @@ import Promise from 'bluebird' import $dom from '../../../dom' import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' +import type { Log } from '../../../cypress/log' const findScrollableParent = ($el, win) => { const $parent = $dom.getParent($el) @@ -28,12 +29,26 @@ const isNaNOrInfinity = (item) => { return _.isNaN(num) || !_.isFinite(num) } +interface InternalScrollIntoViewOptions extends Partial { + _log?: Log + $el: JQuery + $parent: any + axis: string + offset?: object +} + +interface InternalScrollToOptions extends Partial { + _log?: Log + $el: any + x: number + y: number + error?: any + axis: string +} + export default (Commands, Cypress, cy, state) => { Commands.addAll({ prevSubject: 'element' }, { - // TODO: any -> Partial - scrollIntoView (subject, options: any = {}) { - const userOptions = options - + scrollIntoView (subject, userOptions: Partial = {}) { if (!_.isObject(userOptions)) { $errUtils.throwErrByPath('scrollIntoView.invalid_argument', { args: { arg: userOptions } }) } @@ -49,7 +64,7 @@ export default (Commands, Cypress, cy, state) => { $errUtils.throwErrByPath('scrollIntoView.multiple_elements', { args: { num: subject.length } }) } - options = _.defaults({}, userOptions, { + const options: InternalScrollIntoViewOptions = _.defaults({}, userOptions, { $el: subject, $parent: state('window'), log: true, @@ -115,9 +130,6 @@ export default (Commands, Cypress, cy, state) => { const scrollIntoView = () => { return new Promise((resolve, reject) => { // scroll our axes - // TODO: done() came from jQuery animate(), specifically, EffectsOptions at misc.d.ts - // The type definition should be fixed at @types/jquery.scrollto. - // @ts-ignore return $(options.$parent).scrollTo(options.$el, { axis: options.axis, easing: options.easing, @@ -157,10 +169,8 @@ export default (Commands, Cypress, cy, state) => { }) Commands.addAll({ prevSubject: ['optional', 'element', 'window'] }, { - // TODO: any -> Partial - scrollTo (subject, xOrPosition, yOrOptions, options: any = {}) { + scrollTo (subject, xOrPosition, yOrOptions, userOptions: Partial = {}) { let x; let y - let userOptions = options // check for undefined or null values if (xOrPosition === undefined || xOrPosition === null) { @@ -261,7 +271,7 @@ export default (Commands, Cypress, cy, state) => { $errUtils.throwErrByPath('scrollTo.multiple_containers', { args: { num: $container.length } }) } - options = _.defaults({}, userOptions, { + const options: InternalScrollToOptions = _.defaults({}, userOptions, { $el: $container, log: true, duration: 0, @@ -361,10 +371,7 @@ export default (Commands, Cypress, cy, state) => { const scrollTo = () => { return new Promise((resolve, reject) => { - // scroll our axis' - // TODO: done() came from jQuery animate(), specifically, EffectsOptions at misc.d.ts - // The type definition should be fixed at @types/jquery.scrollto. - // @ts-ignore + // scroll our axis $(options.$el).scrollTo({ left: x, top: y }, { axis: options.axis, easing: options.easing, diff --git a/packages/driver/src/cy/commands/actions/select.ts b/packages/driver/src/cy/commands/actions/select.ts index 12b3a28ea7c7..e21e2e31d806 100644 --- a/packages/driver/src/cy/commands/actions/select.ts +++ b/packages/driver/src/cy/commands/actions/select.ts @@ -5,13 +5,19 @@ import $dom from '../../../dom' import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import $elements from '../../../dom/elements' +import type { Log } from '../../../cypress/log' const newLineRe = /\n/g +interface InternalSelectOptions extends Partial { + _log?: Log + $el: JQuery + error?: any +} + export default (Commands, Cypress, cy) => { Commands.addAll({ prevSubject: 'element' }, { - // TODO: any -> Partial - select (subject, valueOrTextOrIndex, options: any = {}) { + select (subject, valueOrTextOrIndex, userOptions: Partial = {}) { if ( !_.isNumber(valueOrTextOrIndex) && !_.isString(valueOrTextOrIndex) @@ -28,9 +34,7 @@ export default (Commands, Cypress, cy) => { $errUtils.throwErrByPath('select.invalid_array_argument', { args: { value: JSON.stringify(valueOrTextOrIndex) } }) } - const userOptions = options - - options = _.defaults({}, userOptions, { + const options: InternalSelectOptions = _.defaults({}, userOptions, { $el: subject, log: true, force: false, @@ -55,7 +59,7 @@ export default (Commands, Cypress, cy) => { }, }) - options._log.snapshot('before', { next: 'after' }) + options._log!.snapshot('before', { next: 'after' }) } let node diff --git a/packages/driver/src/cy/commands/actions/submit.ts b/packages/driver/src/cy/commands/actions/submit.ts index cbd61919c931..de2b6e10474a 100644 --- a/packages/driver/src/cy/commands/actions/submit.ts +++ b/packages/driver/src/cy/commands/actions/submit.ts @@ -5,14 +5,17 @@ import $dom from '../../../dom' import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import $actionability from '../../actionability' +import type { Log } from '../../../cypress/log' + +interface InternalSubmitOptions extends Partial{ + _log?: Log + $el: JQuery +} export default (Commands, Cypress, cy) => { Commands.addAll({ prevSubject: 'element' }, { - // TODO: any -> Partial - submit (subject, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + submit (subject: JQuery, userOptions: Partial = {}) { + const options: InternalSubmitOptions = _.defaults({}, userOptions, { log: true, $el: subject, }) @@ -35,7 +38,7 @@ export default (Commands, Cypress, cy) => { }, }) - options._log.snapshot('before', { next: 'after' }) + options._log!.snapshot('before', { next: 'after' }) } if (!options.$el.is('form')) { diff --git a/packages/driver/src/cy/commands/actions/type.ts b/packages/driver/src/cy/commands/actions/type.ts index e131970b38f8..a168ebf88160 100644 --- a/packages/driver/src/cy/commands/actions/type.ts +++ b/packages/driver/src/cy/commands/actions/type.ts @@ -8,23 +8,33 @@ import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import $actionability from '../../actionability' import $Keyboard from '../../../cy/keyboard' +import type { Log } from '../../../cypress/log' + import debugFn from 'debug' const debug = debugFn('cypress:driver:command:type') +interface InternalTypeOptions extends Partial { + _log?: Log + $el: JQuery + ensure?: object + verify: boolean + interval?: number +} + +interface InternalClearOptions extends Partial { + _log?: Log + ensure?: object +} + export default function (Commands, Cypress, cy, state, config) { const { keyboard } = cy.devices - // Note: These "change type of `any` to X" comments are written instead of changing them directly - // because Cypress extends user-given options with Cypress internal options. - // These comments will be removed after removing `// @ts-nocheck` comments in `packages/driver`. - // TODO: change the type of `any` to `Partial` - function type (subject, chars, options: any = {}) { - const userOptions = options + function type (subject, chars, userOptions: Partial = {}) { let updateTable // allow the el we're typing into to be // changed by options -- used by cy.clear() - options = _.defaults({}, userOptions, { + const options: InternalTypeOptions = _.defaults({}, userOptions, { $el: subject, log: true, verify: true, @@ -110,7 +120,7 @@ export default function (Commands, Cypress, cy, state, config) { }, }) - options._log.snapshot('before', { next: 'after' }) + options._log!.snapshot('before', { next: 'after' }) } if (options.$el.length > 1) { @@ -572,11 +582,8 @@ export default function (Commands, Cypress, cy, state, config) { }) } - // TODO: change the type of `any` to `Partial` - function clear (subject, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + function clear (subject, userOptions: Partial = {}) { + const options: InternalClearOptions = _.defaults({}, userOptions, { log: true, force: false, waitForAnimations: config('waitForAnimations'), diff --git a/packages/driver/src/cy/commands/angular.ts b/packages/driver/src/cy/commands/angular.ts index 48661b05d8a2..f6b4bf374979 100644 --- a/packages/driver/src/cy/commands/angular.ts +++ b/packages/driver/src/cy/commands/angular.ts @@ -3,9 +3,14 @@ import $ from 'jquery' import Promise from 'bluebird' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' const ngPrefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-'] +interface InternalNgOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy, state) => { const findByNgBinding = (binding, options) => { const selector = '.ng-binding' @@ -89,10 +94,7 @@ export default (Commands, Cypress, cy, state) => { } Commands.addAll({ - // TODO: Change the options type from `any` to `Partial`. - ng (type, selector, options: any = {}) { - const userOptions = options - + ng (type: string, selector: string, userOptions: Partial = {}) { // what about requirejs / browserify? // we need to intelligently check to see if we're using those // and if angular is available through them. throw a very specific @@ -102,7 +104,7 @@ export default (Commands, Cypress, cy, state) => { $errUtils.throwErrByPath('ng.no_global') } - options = _.defaults({}, userOptions, { log: true }) + const options: InternalNgOptions = _.defaults({}, userOptions, { log: true }) if (options.log) { options._log = Cypress.log({ diff --git a/packages/driver/src/cy/commands/clock.ts b/packages/driver/src/cy/commands/clock.ts index aa202fbeff46..6ac0a36bb5a1 100644 --- a/packages/driver/src/cy/commands/clock.ts +++ b/packages/driver/src/cy/commands/clock.ts @@ -42,8 +42,7 @@ export default function (Commands, Cypress, cy, state) { }) return Commands.addAll({ type: 'utility' }, { - // TODO: change the options type from `any` to Partial. - clock (subject, now, methods, options: any = {}) { + clock (subject, now, methods, options: Partial = {}) { let userOptions = options const ctx = state('ctx') diff --git a/packages/driver/src/cy/commands/cookies.ts b/packages/driver/src/cy/commands/cookies.ts index 9002763dc0db..69075312e083 100644 --- a/packages/driver/src/cy/commands/cookies.ts +++ b/packages/driver/src/cy/commands/cookies.ts @@ -3,6 +3,7 @@ import Promise from 'bluebird' import $utils from '../../cypress/utils' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' import { $Location } from '../../cypress/location' // TODO: add hostOnly to COOKIE_PROPS @@ -78,6 +79,30 @@ function cookieValidatesSecurePrefix (options) { return options.secure === false } +interface InternalGetCookieOptions extends Partial { + _log?: Log + cookie?: Cypress.Cookie +} + +interface InternalGetCookiesOptions extends Partial { + _log?: Log + cookies?: Cypress.Cookie[] +} + +interface InternalSetCookieOptions extends Partial { + _log?: Log + name: string + cookie?: Cypress.Cookie +} + +type InternalClearCookieOptions = InternalGetCookieOptions + +interface InternalClearCookiesOptions extends Partial { + _log?: Log + cookies?: Cypress.Cookie[] + domain?: any +} + export default function (Commands, Cypress, cy, state, config) { const automateCookies = function (event, obj = {}, log, timeout) { const automate = () => { @@ -164,11 +189,8 @@ export default function (Commands, Cypress, cy, state, config) { }) return Commands.addAll({ - // TODO: change the type of `any` to `Partial` - getCookie (name, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + getCookie (name, userOptions: Partial = {}) { + const options: InternalGetCookieOptions = _.defaults({}, userOptions, { log: true, timeout: config('responseTimeout'), }) @@ -211,11 +233,8 @@ export default function (Commands, Cypress, cy, state, config) { .catch(handleBackendError('getCookie', 'reading the requested cookie from', onFail)) }, - // TODO: change the type of `any` to `Partial` - getCookies (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + getCookies (userOptions: Partial = {}) { + const options: InternalGetCookiesOptions = _.defaults({}, userOptions, { log: true, timeout: config('responseTimeout'), }) @@ -250,11 +269,8 @@ export default function (Commands, Cypress, cy, state, config) { .catch(handleBackendError('getCookies', 'reading cookies from', options._log)) }, - // TODO: change the type of `any` to `Partial` - setCookie (name, value, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + setCookie (name, value, userOptions: Partial = {}) { + const options: InternalSetCookieOptions = _.defaults({}, userOptions, { name, value, path: '/', @@ -332,11 +348,8 @@ export default function (Commands, Cypress, cy, state, config) { }).catch(handleBackendError('setCookie', 'setting the requested cookie in', onFail)) }, - // TODO: change the type of `any` to `Partial` - clearCookie (name, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + clearCookie (name, userOptions: Partial = {}) { + const options: InternalClearCookieOptions = _.defaults({}, userOptions, { log: true, timeout: config('responseTimeout'), }) @@ -382,11 +395,8 @@ export default function (Commands, Cypress, cy, state, config) { .catch(handleBackendError('clearCookie', 'clearing the requested cookie in', onFail)) }, - // TODO: change the type of `any` to `Partial` - clearCookies (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + clearCookies (userOptions: Partial = {}) { + const options: InternalClearCookiesOptions = _.defaults({}, userOptions, { log: true, timeout: config('responseTimeout'), }) @@ -396,12 +406,12 @@ export default function (Commands, Cypress, cy, state, config) { message: '', timeout: options.timeout, consoleProps () { - let c + const c = options.cookies const obj = {} obj['Yielded'] = 'null' - if ((c = options.cookies) && c.length) { + if (c && c.length) { obj['Cleared Cookies'] = c obj['Num Cookies'] = c.length } else { diff --git a/packages/driver/src/cy/commands/debugging.ts b/packages/driver/src/cy/commands/debugging.ts index 6318e904b9ef..8ac152cf0604 100644 --- a/packages/driver/src/cy/commands/debugging.ts +++ b/packages/driver/src/cy/commands/debugging.ts @@ -1,6 +1,7 @@ import _ from 'lodash' import $utils from '../../cypress/utils' +import type { Log } from '../../cypress/log' const resume = (state, resumeAll = true) => { const onResume = state('onResume') @@ -32,6 +33,14 @@ const getNextQueuedCommand = (state, queue) => { return search(state('index')) } +interface InternalPauseOptions extends Partial { + _log?: Log +} + +interface InternalDebugOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy, state, config) => { Cypress.on('resume:next', () => { return resume(state, false) @@ -42,18 +51,15 @@ export default (Commands, Cypress, cy, state, config) => { }) Commands.addAll({ type: 'utility', prevSubject: 'optional' }, { - // TODO: change the options type from `any` to `Loggable`. // pause should indefinitely pause until the user // presses a key or clicks in the UI to continue - pause (subject, options: any = {}) { + pause (subject, userOptions: Partial = {}) { // bail if we're in run mode, unless --headed and --no-exit flags are passed if (!config('isInteractive') && (!config('browser').isHeaded || config('exit'))) { return subject } - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + const options: InternalPauseOptions = _.defaults({}, userOptions, { log: true }) if (options.log) { options._log = Cypress.log({ @@ -72,8 +78,8 @@ export default (Commands, Cypress, cy, state, config) => { // pause on the very next one state('onPaused', null) - if (options.log) { - options._log.end() + if (options._log) { + options._log!.end() } } @@ -103,11 +109,8 @@ export default (Commands, Cypress, cy, state, config) => { return subject }, - // TODO: change `any` to Loggable - debug (subject, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + debug (subject, userOptions: Partial = {}) { + const options: InternalDebugOptions = _.defaults({}, userOptions, { log: true, }) diff --git a/packages/driver/src/cy/commands/exec.ts b/packages/driver/src/cy/commands/exec.ts index d6114590579f..a0131c604ef1 100644 --- a/packages/driver/src/cy/commands/exec.ts +++ b/packages/driver/src/cy/commands/exec.ts @@ -2,14 +2,17 @@ import _ from 'lodash' import Promise from 'bluebird' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' + +interface InternalExecOptions extends Partial { + _log?: Log + cmd?: string +} export default (Commands, Cypress, cy) => { Commands.addAll({ - // TODO: change the type of `any` to `Partical` - exec (cmd, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + exec (cmd: string, userOptions: Partial = {}) { + const options: InternalExecOptions = _.defaults({}, userOptions, { log: true, timeout: Cypress.config('execTimeout'), failOnNonZeroExit: true, diff --git a/packages/driver/src/cy/commands/files.ts b/packages/driver/src/cy/commands/files.ts index 473bc7b02d80..02512836a209 100644 --- a/packages/driver/src/cy/commands/files.ts +++ b/packages/driver/src/cy/commands/files.ts @@ -2,19 +2,26 @@ import _ from 'lodash' import { basename } from 'path' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' + +interface InternalReadFileOptions extends Partial { + _log?: Log + encoding: Cypress.Encodings +} + +interface InternalWriteFileOptions extends Partial { + _log?: Log +} export default (Commands, Cypress, cy, state) => { Commands.addAll({ - // TODO: change the type of `any` to `Partial` - readFile (file, encoding, options: any = {}) { - let userOptions = options - + readFile (file, encoding, userOptions: Partial = {}) { if (_.isObject(encoding)) { userOptions = encoding encoding = undefined } - options = _.defaults({}, userOptions, { + const options: InternalReadFileOptions = _.defaults({}, userOptions, { // https://github.com/cypress-io/cypress/issues/1558 // If no encoding is specified, then Cypress has historically defaulted // to `utf8`, because of it's focus on text files. This is in contrast to @@ -109,16 +116,13 @@ export default (Commands, Cypress, cy, state) => { return verifyAssertions() }, - // TODO: change the type of `any` to `Partial` - writeFile (fileName, contents, encoding, options: any = {}) { - let userOptions = options - + writeFile (fileName, contents, encoding, userOptions: Partial = {}) { if (_.isObject(encoding)) { userOptions = encoding encoding = undefined } - options = _.defaults({}, userOptions, { + const options: InternalWriteFileOptions = _.defaults({}, userOptions, { // https://github.com/cypress-io/cypress/issues/1558 // If no encoding is specified, then Cypress has historically defaulted // to `utf8`, because of it's focus on text files. This is in contrast to diff --git a/packages/driver/src/cy/commands/location.ts b/packages/driver/src/cy/commands/location.ts index 837d39b8a3d3..900d12cabca1 100644 --- a/packages/driver/src/cy/commands/location.ts +++ b/packages/driver/src/cy/commands/location.ts @@ -2,15 +2,21 @@ import _ from 'lodash' import Promise from 'bluebird' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' const { throwErrByPath } = $errUtils +interface InternalUrlOptions extends Partial { + _log?: Log +} + +interface InternalHashOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy) => { Commands.addAll({ - // TODO: change the type of `any` to `Partial` - url (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + url (userOptions: Partial = {}) { + const options: InternalUrlOptions = _.defaults({}, userOptions, { log: true }) if (options.log !== false) { options._log = Cypress.log({ @@ -38,11 +44,8 @@ export default (Commands, Cypress, cy) => { return resolveHref() }, - // TODO: change the type of `any` to `Partial` - hash (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + hash (userOptions: Partial = {}) { + const options: InternalHashOptions = _.defaults({}, userOptions, { log: true }) if (options.log !== false) { options._log = Cypress.log({ diff --git a/packages/driver/src/cy/commands/misc.ts b/packages/driver/src/cy/commands/misc.ts index 5a0db7a0f094..54d862663cc6 100644 --- a/packages/driver/src/cy/commands/misc.ts +++ b/packages/driver/src/cy/commands/misc.ts @@ -4,6 +4,12 @@ import Promise from 'bluebird' import $Command from '../../cypress/command' import $dom from '../../dom' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' + +interface InternalWrapOptions extends Partial { + _log?: Log + timeout: number +} export default (Commands, Cypress, cy, state) => { Commands.addAll({ prevSubject: 'optional' }, { @@ -49,11 +55,8 @@ export default (Commands, Cypress, cy, state) => { return null }, - // TODO: change the type of `any` to `Partial` - wrap (arg, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + wrap (arg, userOptions: Partial = {}) { + const options: InternalWrapOptions = _.defaults({}, userOptions, { log: true, timeout: Cypress.config('defaultCommandTimeout'), }) @@ -68,7 +71,7 @@ export default (Commands, Cypress, cy, state) => { }) if ($dom.isElement(arg)) { - options._log.set({ $el: arg }) + options._log!.set({ $el: arg }) } } diff --git a/packages/driver/src/cy/commands/navigation.ts b/packages/driver/src/cy/commands/navigation.ts index 97bbb11359e7..da2a73e2b2d7 100644 --- a/packages/driver/src/cy/commands/navigation.ts +++ b/packages/driver/src/cy/commands/navigation.ts @@ -5,7 +5,7 @@ import Promise from 'bluebird' import $utils from '../../cypress/utils' import $errUtils from '../../cypress/error_utils' -import { LogUtils } from '../../cypress/log' +import { LogUtils, Log } from '../../cypress/log' import { bothUrlsMatchAndOneHasHash } from '../navigation' import { $Location } from '../../cypress/location' @@ -410,6 +410,10 @@ type InvalidContentTypeError = Error & { invalidContentType: boolean } +interface InternalVisitOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy, state, config) => { reset() @@ -693,14 +697,11 @@ export default (Commands, Cypress, cy, state, config) => { return $errUtils.throwErrByPath('go.invalid_argument', { onFail: options._log }) }, - // TODO: Change the type of `any` to `Partial`. - visit (url, options: any = {}) { - if (options.url && url) { - $errUtils.throwErrByPath('visit.no_duplicate_url', { args: { optionsUrl: options.url, url } }) + visit (url, userOptions: Partial = {}) { + if (userOptions.url && url) { + $errUtils.throwErrByPath('visit.no_duplicate_url', { args: { optionsUrl: userOptions.url, url } }) } - let userOptions = options - if (_.isObject(url) && _.isEqual(userOptions, {})) { // options specified as only argument userOptions = url @@ -717,7 +718,7 @@ export default (Commands, Cypress, cy, state, config) => { consoleProps['Options'] = _.pick(userOptions, VISIT_OPTS) } - options = _.defaults({}, userOptions, { + const options: InternalVisitOptions = _.defaults({}, userOptions, { auth: null, failOnStatusCode: true, retryOnNetworkFailure: true, @@ -972,14 +973,14 @@ export default (Commands, Cypress, cy, state, config) => { } } - if (options.log) { - let message = options._log.get('message') + if (options._log) { + let message = options._log!.get('message') if (redirects && redirects.length) { message = [message].concat(redirects).join(' -> ') } - options._log.set({ message }) + options._log!.set({ message }) } consoleProps['Resolved Url'] = url diff --git a/packages/driver/src/cy/commands/querying/focused.ts b/packages/driver/src/cy/commands/querying/focused.ts index 45f67366ae20..c96acf77cc4c 100644 --- a/packages/driver/src/cy/commands/querying/focused.ts +++ b/packages/driver/src/cy/commands/querying/focused.ts @@ -2,14 +2,17 @@ import _ from 'lodash' import Promise from 'bluebird' import $dom from '../../../dom' +import type { Log } from '../../../cypress/log' + +interface InternalFocusedOptions extends Partial{ + _log?: Log + verify: boolean +} export default (Commands, Cypress, cy, state) => { Commands.addAll({ - // TODO: any -> Partial - focused (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + focused (userOptions: Partial = {}) { + const options: InternalFocusedOptions = _.defaults({}, userOptions, { verify: true, log: true, }) @@ -23,7 +26,7 @@ export default (Commands, Cypress, cy, state) => { return } - options._log.set({ + options._log!.set({ $el, consoleProps () { const ret = $el ? $dom.getElements($el) : '--nothing--' diff --git a/packages/driver/src/cy/commands/querying/querying.ts b/packages/driver/src/cy/commands/querying/querying.ts index aa80eeb3c268..0c4ffb9f1d93 100644 --- a/packages/driver/src/cy/commands/querying/querying.ts +++ b/packages/driver/src/cy/commands/querying/querying.ts @@ -4,14 +4,25 @@ import Promise from 'bluebird' import $dom from '../../../dom' import $elements from '../../../dom/elements' import $errUtils from '../../../cypress/error_utils' +import type { Log } from '../../../cypress/log' import { resolveShadowDomInclusion } from '../../../cypress/shadow_dom_utils' import { getAliasedRequests, isDynamicAliasingPossible } from '../../net-stubbing/aliasing' +interface InternalGetOptions extends Partial { + _log?: Log + _retries?: number + filter?: any + onRetry?: Function + verify?: boolean +} + +interface InternalContainsOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy, state) => { Commands.addAll({ - // TODO: any -> Partial - get (selector, options: any = {}) { - const userOptions = options + get (selector, userOptions: Partial = {}) { const ctx = this if ((userOptions === null) || _.isArray(userOptions) || !_.isPlainObject(userOptions)) { @@ -20,7 +31,7 @@ export default (Commands, Cypress, cy, state) => { }) } - options = _.defaults({}, userOptions, { + const options: InternalGetOptions = _.defaults({}, userOptions, { retry: true, withinSubject: state('withinSubject'), log: true, @@ -28,7 +39,7 @@ export default (Commands, Cypress, cy, state) => { verify: true, }) - options.includeShadowDom = resolveShadowDomInclusion(Cypress, userOptions.includeShadowDom) + options.includeShadowDom = resolveShadowDomInclusion(Cypress, options.includeShadowDom) let aliasObj const consoleProps: Record = {} @@ -100,7 +111,7 @@ export default (Commands, Cypress, cy, state) => { return consoleProps } - options._log.set(obj) + options._log!.set(obj) } let allParts @@ -263,14 +274,14 @@ export default (Commands, Cypress, cy, state) => { consoleProps.Yielded = $dom.getElements($el) consoleProps.Elements = $el != null ? $el.length : undefined - options._log.set({ $el }) + options._log!.set({ $el }) } const getElements = () => { let $el try { - let scope = options.withinSubject + let scope: (typeof options.withinSubject) | Node[] = options.withinSubject if (options.includeShadowDom) { const root = options.withinSubject ? options.withinSubject[0] : cy.state('document') @@ -295,7 +306,7 @@ export default (Commands, Cypress, cy, state) => { return err } - options._log.error(err) + options._log!.error(err) } throw err @@ -305,7 +316,7 @@ export default (Commands, Cypress, cy, state) => { // and we have been explictly told to filter // then just attempt to filter out elements from our within subject if (!$el.length && options.withinSubject && options.filter) { - const filtered = options.withinSubject.filter(selector) + const filtered = (options.withinSubject as JQuery).filter(selector) // reset $el if this found anything if (filtered.length) { @@ -350,10 +361,7 @@ export default (Commands, Cypress, cy, state) => { }) Commands.addAll({ prevSubject: ['optional', 'window', 'document', 'element'] }, { - // TODO: any -> Partial - contains (subject, filter, text, options: any = {}) { - let userOptions = options - + contains (subject, filter, text, userOptions: Partial = {}) { // nuke our subject if its present but not an element. // in these cases its either window or document but // we dont care. @@ -389,7 +397,7 @@ export default (Commands, Cypress, cy, state) => { $errUtils.throwErrByPath('contains.regex_conflict') } - options = _.defaults({}, userOptions, { log: true, matchCase: true }) + const options: InternalContainsOptions = _.defaults({}, userOptions, { log: true, matchCase: true }) if (!(_.isString(text) || _.isFinite(text) || _.isRegExp(text))) { $errUtils.throwErrByPath('contains.invalid_argument') @@ -459,7 +467,7 @@ export default (Commands, Cypress, cy, state) => { consoleProps.Yielded = $dom.getElements($el) consoleProps.Elements = $el != null ? $el.length : undefined - options._log.set({ $el }) + options._log!.set({ $el }) } // find elements by the :cy-contains psuedo selector diff --git a/packages/driver/src/cy/commands/querying/root.ts b/packages/driver/src/cy/commands/querying/root.ts index 579bc461d31f..6847c9b955e3 100644 --- a/packages/driver/src/cy/commands/querying/root.ts +++ b/packages/driver/src/cy/commands/querying/root.ts @@ -1,12 +1,14 @@ import _ from 'lodash' +import type { Log } from '../../../cypress/log' + +interface InternalRootOptions extends Partial { + _log?: Log +} export default (Commands, Cypress, cy, state) => { Commands.addAll({ - // TODO: any -> Partial - root (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + root (userOptions: Partial = {}) { + const options: InternalRootOptions = _.defaults({}, userOptions, { log: true }) if (options.log !== false) { options._log = Cypress.log({ @@ -16,8 +18,8 @@ export default (Commands, Cypress, cy, state) => { } const log = ($el) => { - if (options.log) { - options._log.set({ $el }) + if (options._log) { + options._log!.set({ $el }) } return $el diff --git a/packages/driver/src/cy/commands/screenshot.ts b/packages/driver/src/cy/commands/screenshot.ts index 53987c587c0b..585cd08639e8 100644 --- a/packages/driver/src/cy/commands/screenshot.ts +++ b/packages/driver/src/cy/commands/screenshot.ts @@ -8,6 +8,7 @@ import $Screenshot from '../../cypress/screenshot' import $dom from '../../dom' import $errUtils from '../../cypress/error_utils' import $utils from '../../cypress/utils' +import type { Log } from '../../cypress/log' const getViewportHeight = (state) => { // TODO this doesn't seem correct @@ -410,6 +411,10 @@ const takeScreenshot = (Cypress, state, screenshotConfig, options: TakeScreensho .finally(after) } +interface InternalScreenshotOptions extends Partial { + _log?: Log +} + export default function (Commands, Cypress, cy, state, config) { // failure screenshot when not interactive Cypress.on('runnable:after:run:async', (test, runnable) => { @@ -440,10 +445,7 @@ export default function (Commands, Cypress, cy, state, config) { }) Commands.addAll({ prevSubject: ['optional', 'element', 'window', 'document'] }, { - // TODO: any -> Partial - screenshot (subject, name, options: any = {}) { - let userOptions = options - + screenshot (subject, name, userOptions: Partial = {}) { if (_.isObject(name)) { userOptions = name name = null @@ -452,7 +454,7 @@ export default function (Commands, Cypress, cy, state, config) { // make sure when we capture the entire test runner // we are not limited to "within" subject // https://github.com/cypress-io/cypress/issues/14253 - if (options.capture !== 'runner') { + if (userOptions.capture !== 'runner') { const withinSubject = state('withinSubject') if (withinSubject && $dom.isElement(withinSubject)) { @@ -463,7 +465,7 @@ export default function (Commands, Cypress, cy, state, config) { // TODO: handle hook titles const runnable = state('runnable') - options = _.defaults({}, userOptions, { + const options: InternalScreenshotOptions = _.defaults({}, userOptions, { log: true, timeout: config('responseTimeout'), }) diff --git a/packages/driver/src/cy/commands/task.ts b/packages/driver/src/cy/commands/task.ts index ff07b7bf8d7e..7223b95084e7 100644 --- a/packages/driver/src/cy/commands/task.ts +++ b/packages/driver/src/cy/commands/task.ts @@ -4,14 +4,16 @@ import Promise from 'bluebird' import $utils from '../../cypress/utils' import $errUtils from '../../cypress/error_utils' import $stackUtils from '../../cypress/stack_utils' +import type { Log } from '../../cypress/log' + +interface InternalTaskOptions extends Partial { + _log?: Log +} export default (Commands, Cypress, cy) => { Commands.addAll({ - // TODO: any -> Partial - task (task, arg, options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { + task (task, arg, userOptions: Partial = {}) { + const options: InternalTaskOptions = _.defaults({}, userOptions, { log: true, timeout: Cypress.config('taskTimeout'), }) diff --git a/packages/driver/src/cy/commands/window.ts b/packages/driver/src/cy/commands/window.ts index a4005d888443..908e81189a25 100644 --- a/packages/driver/src/cy/commands/window.ts +++ b/packages/driver/src/cy/commands/window.ts @@ -2,6 +2,7 @@ import _ from 'lodash' import Promise from 'bluebird' import $errUtils from '../../cypress/error_utils' +import type { Log } from '../../cypress/log' const viewports = { 'macbook-16': '1536x960', @@ -35,6 +36,24 @@ type CurrentViewport = Pick // refresh would cause viewport to hang let currentViewport: CurrentViewport | null = null +interface InternalTitleOptions extends Partial { + _log?: Log +} + +interface InternalWindowOptions extends Partial { + _log?: Log + error?: any +} + +interface InternalDocumentOptions extends Partial { + _log?: Log + error?: any +} + +interface InternalViewportOptions extends Partial { + _log?: Log +} + export default (Commands, Cypress, cy, state) => { const defaultViewport: CurrentViewport = _.pick(Cypress.config() as Cypress.Config, 'viewportWidth', 'viewportHeight') @@ -78,11 +97,8 @@ export default (Commands, Cypress, cy, state) => { } Commands.addAll({ - // TODO: any -> Partial - title (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + title (userOptions: Partial = {}) { + const options: InternalTitleOptions = _.defaults({}, userOptions, { log: true }) if (options.log) { options._log = Cypress.log({ timeout: options.timeout }) @@ -101,11 +117,8 @@ export default (Commands, Cypress, cy, state) => { return resolveTitle() }, - // TODO: any -> Partial - window (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + window (userOptions: Partial = {}) { + const options: InternalWindowOptions = _.defaults({}, userOptions, { log: true }) if (options.log) { options._log = Cypress.log({ timeout: options.timeout }) @@ -144,11 +157,8 @@ export default (Commands, Cypress, cy, state) => { return verifyAssertions() }, - // TODO: any -> Partial - document (options: any = {}) { - const userOptions = options - - options = _.defaults({}, userOptions, { log: true }) + document (userOptions: Partial = {}) { + const options: InternalDocumentOptions = _.defaults({}, userOptions, { log: true }) if (options.log) { options._log = Cypress.log({ timeout: options.timeout }) @@ -188,15 +198,12 @@ export default (Commands, Cypress, cy, state) => { return verifyAssertions() }, - // TODO: any -> Partial - viewport (presetOrWidth, heightOrOrientation, options: any = {}) { - const userOptions = options - + viewport (presetOrWidth, heightOrOrientation, userOptions: Partial = {}) { if (_.isObject(heightOrOrientation)) { - options = heightOrOrientation + userOptions = heightOrOrientation } - options = _.defaults({}, userOptions, { log: true }) + const options: InternalViewportOptions = _.defaults({}, userOptions, { log: true }) let height let width @@ -208,10 +215,6 @@ export default (Commands, Cypress, cy, state) => { const isPreset = typeof presetOrWidth === 'string' options._log = Cypress.log({ - // TODO: timeout below should be removed - // because cy.viewport option doesn't support `timeout` - // @see https://docs.cypress.io/api/commands/viewport#Arguments - timeout: options.timeout, consoleProps () { const obj: Record = {} diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts index f03306b6fa21..c44791ce2fc3 100644 --- a/packages/driver/src/cy/keyboard.ts +++ b/packages/driver/src/cy/keyboard.ts @@ -12,6 +12,7 @@ import type { HTMLTextLikeElement } from '../dom/elements' import $selection from '../dom/selection' import $utils from '../cypress/utils' import $window from '../dom/window' +import type { Log } from '../cypress/log' const debug = Debug('cypress:driver:keyboard') @@ -680,7 +681,7 @@ export interface typeOptions { force?: boolean simulated?: boolean release?: boolean - _log?: any + _log?: Log delay?: number onError?: Function onEvent?: Function diff --git a/packages/driver/src/cy/video-recorder.ts b/packages/driver/src/cy/video-recorder.ts index 980d4aa75e7b..008d4cb6c8d4 100644 --- a/packages/driver/src/cy/video-recorder.ts +++ b/packages/driver/src/cy/video-recorder.ts @@ -24,8 +24,6 @@ export const initVideoRecorder = (Cypress) => { mimeType: 'video/webm', } - // TODO: update TypeScript to 4.4+. - // @ts-ignore const mediaRecorder = new window.MediaRecorder(stream, options) mediaRecorder.start(200) diff --git a/packages/driver/src/cypress/browser.ts b/packages/driver/src/cypress/browser.ts index 559d74843496..a3d188955c06 100644 --- a/packages/driver/src/cypress/browser.ts +++ b/packages/driver/src/cypress/browser.ts @@ -35,8 +35,7 @@ const _isBrowser = (browser, matcher, errPrefix) => { } } -// TODO: change the type of `any` to `IsBrowserMatcher` -const isBrowser = (config, obj: any = '', errPrefix: string = '`Cypress.isBrowser()`') => { +const isBrowser = (config, obj: Cypress.IsBrowserMatcher = '', errPrefix: string = '`Cypress.isBrowser()`') => { return _ .chain(obj) .concat([]) diff --git a/packages/driver/src/cypress/log.ts b/packages/driver/src/cypress/log.ts index 88ec76a1a60a..9418a200bb6a 100644 --- a/packages/driver/src/cypress/log.ts +++ b/packages/driver/src/cypress/log.ts @@ -219,7 +219,7 @@ const defaults = function (state: Cypress.State, config, obj) { return obj } -class Log { +export class Log { cy: any state: Cypress.State config: any diff --git a/patches/@types+jquery.scrollto+1.4.29.dev.patch b/patches/@types+jquery.scrollto+1.4.29.dev.patch new file mode 100644 index 000000000000..8c79239f7a1c --- /dev/null +++ b/patches/@types+jquery.scrollto+1.4.29.dev.patch @@ -0,0 +1,58 @@ +diff --git a/node_modules/@types/jquery.scrollto/index.d.ts b/node_modules/@types/jquery.scrollto/index.d.ts +index 0a00c69..126a3d0 100755 +--- a/node_modules/@types/jquery.scrollto/index.d.ts ++++ b/node_modules/@types/jquery.scrollto/index.d.ts +@@ -6,7 +6,7 @@ + + /// + +-interface ScrollToOptions { ++interface JQueryScrollToOptions extends JQuery.EffectsOptions { + /** + * Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'. + */ +@@ -48,7 +48,7 @@ interface ScrollToOptions { + onAfterFirst?: (() => void) | undefined; + } + +-interface JQuery { ++interface JQuery { + /** + * Scroll the matched elements + */ +@@ -60,7 +60,7 @@ interface JQuery { + * @param duration The OVERALL length of the animation + * @param settings Set of settings. + */ +- (target: any, duration?: number, settings?: ScrollToOptions): JQuery; ++ (target: any, duration?: number, settings?: JQueryScrollToOptions): JQuery; + /** + * Scroll the matched elements + * +@@ -76,7 +76,7 @@ interface JQuery { + * @param settings Set of settings. + * @param onAfter The onAfter callback. + */ +- (target: any, settings: ScrollToOptions, onAfter?: Function): JQuery; ++ (target: any, settings: JQueryScrollToOptions, onAfter?: Function): JQuery; + + }; + +@@ -94,7 +94,7 @@ interface JQueryStatic { + * @param duration The OVERALL length of the animation + * @param settings Set of settings. + */ +- (target: any, duration?: number, settings?: ScrollToOptions): JQuery; ++ (target: any, duration?: number, settings?: JQueryScrollToOptions): JQuery; + /** + * Scroll window + * +@@ -110,7 +110,7 @@ interface JQueryStatic { + * @param settings Set of settings. + * @param onAfter The onAfter callback. + */ +- (target: any, settings: ScrollToOptions, onAfter?: Function): JQuery; ++ (target: any, settings: JQueryScrollToOptions, onAfter?: Function): JQuery; + + }; +