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

chore: Improve pkg/driver types part 2 #21610

Merged
merged 17 commits into from Jun 28, 2022
Merged
4 changes: 2 additions & 2 deletions packages/driver/cypress/e2e/commands/actions/click.cy.js
Expand Up @@ -745,7 +745,7 @@ describe('src/cy/commands/actions/click', () => {
cy.get('#three-buttons button').click({ multiple: true }).then(() => {
const calls = cy.timeout.getCalls()

const num = _.filter(calls, (call) => _.isEqual(call.args, [50, true, 'click']))
const num = _.filter(calls, (call) => _.isEqual(call.args, [50, true]))

expect(num.length).to.eq(count)
})
Expand Down Expand Up @@ -3239,7 +3239,7 @@ describe('src/cy/commands/actions/click', () => {
cy.get('#three-buttons button').dblclick().then(() => {
const calls = cy.timeout.getCalls()

const num = _.filter(calls, (call) => _.isEqual(call.args, [50, true, 'dblclick']))
const num = _.filter(calls, (call) => _.isEqual(call.args, [50, true]))

expect(num.length).to.eq(count)
})
Expand Down
13 changes: 8 additions & 5 deletions packages/driver/cypress/e2e/cypress/command_queue.cy.ts
@@ -1,6 +1,8 @@
import _ from 'lodash'
import type { IStability } from '../../../src/cy/stability'
import $Command from '../../../src/cypress/command'
import { CommandQueue } from '../../../src/cypress/command_queue'
import type { StateFunc } from '../../../src/cypress/state'

const createCommand = (props = {}) => {
return $Command.create(_.extend({
Expand All @@ -22,15 +24,16 @@ const log = (props = {}) => {

describe('src/cypress/command_queue', () => {
let queue
const state = () => {}
const state = (() => {}) as StateFunc
const timeout = () => {}
const whenStable = () => {}
const cleanup = () => {}
const whenStable = {} as IStability
const cleanup = () => 0
const fail = () => {}
const isCy = () => {}
const isCy = () => true
const clearTimeout = () => {}

beforeEach(() => {
queue = new CommandQueue(state, timeout, whenStable, cleanup, fail, isCy)
queue = new CommandQueue(state, timeout, whenStable, cleanup, fail, isCy, clearTimeout)

queue.add(createCommand({
name: 'get',
Expand Down
9 changes: 7 additions & 2 deletions packages/driver/src/cy/actionability.ts
Expand Up @@ -4,7 +4,7 @@ import Promise from 'bluebird'

import debugFn from 'debug'
import $dom from '../dom'
import type { ElWindowPostion, ElViewportPostion } from '../dom/coordinates'
import type { ElWindowPostion, ElViewportPostion, ElementPositioning } from '../dom/coordinates'
import $elements from '../dom/elements'
import $errUtils from '../cypress/error_utils'
const debug = debugFn('cypress:driver:actionability')
Expand Down Expand Up @@ -290,7 +290,12 @@ const ensureNotAnimating = function (cy, $el, coordsHistory, animationDistanceTh
cy.ensureElementIsNotAnimating($el, coordsHistory, animationDistanceThreshold)
}

const verify = function (cy, $el, config, options, callbacks) {
interface VerifyCallbacks {
onReady?: ($el: any, coords: ElementPositioning) => any
onScroll?: ($el: any, type: 'element' | 'window' | 'container') => any
}

const verify = function (cy, $el, config, options, callbacks: VerifyCallbacks) {
_.defaults(options, {
scrollBehavior: config('scrollBehavior'),
ensure: {
Expand Down
6 changes: 3 additions & 3 deletions packages/driver/src/cy/chai.ts
Expand Up @@ -35,11 +35,11 @@ const imageMarkdown = /!\[.*?\]\(.*?\)/g
const doubleslashRe = /\\\\/g
const escapedDoubleslashRe = /__double_slash__/g

type CreateFunc = ((specWindow, state, assertFn) => ({
type CreateFunc = (specWindow: SpecWindow, state: StateFunc, assertFn: $Cy['assert']) => ({
chai: Chai.ChaiStatic
expect: (val: any, message?: string) => Chai.Assertion
assert: any
}))
})
export let create: CreateFunc | null = null

chai.use(sinonChai)
Expand Down Expand Up @@ -439,7 +439,7 @@ chai.use((chai, u) => {
})
}

const captureUserInvocationStack = (specWindow, state: StateFunc, ssfi) => {
const captureUserInvocationStack = (specWindow: SpecWindow, state: StateFunc, ssfi) => {
// we need a user invocation stack with the top line being the point where
// the error occurred for the sake of the code frame
// in chrome, stack lines from another frame don't appear in the
Expand Down
9 changes: 6 additions & 3 deletions packages/driver/src/cy/commands/actions/click.ts
Expand Up @@ -5,6 +5,9 @@ import $dom from '../../../dom'
import $utils from '../../../cypress/utils'
import $errUtils from '../../../cypress/error_utils'
import $actionability from '../../actionability'
import type { ElViewportPostion } from '../../../dom/coordinates'
import type { $Cy } from '../../../cypress/cy'
import type { ForceEl } from '../../mouse'

const formatMouseEvents = (events) => {
return _.map(events, (val, key) => {
Expand Down Expand Up @@ -39,12 +42,12 @@ type MouseActionOptions = {
positionOrX: string | number
y: number
userOptions: Record<string, any>
onReady: Function
onReady: (fromElViewport: ElViewportPostion, forceEl: ForceEl) => any
onTable: Function
defaultOptions?: Record<string, any>
}

export default (Commands, Cypress, cy, state, config) => {
export default (Commands, Cypress, cy: $Cy, state, config) => {
const { mouse, keyboard } = cy.devices

const mouseAction = (eventName, { subject, positionOrX, y, userOptions, onReady, onTable, defaultOptions }: MouseActionOptions) => {
Expand Down Expand Up @@ -128,7 +131,7 @@ export default (Commands, Cypress, cy, state, config) => {

// add this delay delta to the runnables timeout because we delay
// by it below before performing each click
cy.timeout($actionability.delay, true, eventName)
cy.timeout($actionability.delay, true)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice to clean this up.


const createLog = (domEvents, fromElWindow, fromAutWindow) => {
let consoleObj
Expand Down
5 changes: 5 additions & 0 deletions packages/driver/src/cy/commands/xhr.ts
Expand Up @@ -60,6 +60,11 @@ const setRequest = (state, xhr, alias) => {
return state('requests', requests)
}

export type XHRRequest = {
xhr: any
alias: any
}

export interface XHRResponse {
xhr: any
alias: any
Expand Down
5 changes: 1 addition & 4 deletions packages/driver/src/cy/focused.ts
Expand Up @@ -237,7 +237,4 @@ export const create = (state: StateFunc) => ({
},
})

export interface IFocused extends Omit<
ReturnType<typeof create>,
'documentHasFocus' | 'interceptFocus' | 'interceptBlur'
> {}
export interface IFocused extends ReturnType<typeof create> {}
2 changes: 1 addition & 1 deletion packages/driver/src/cy/jquery.ts
Expand Up @@ -10,7 +10,7 @@ const remoteJQueryisNotSameAsGlobal = (remoteJQuery) => {

// eslint-disable-next-line @cypress/dev/arrow-body-multiline-braces
export const create = (state: StateFunc) => ({
$$ (selector, context) {
$$ (selector, context?) {
if (context == null) {
context = state('document')
}
Expand Down
20 changes: 5 additions & 15 deletions packages/driver/src/cy/keyboard.ts
Expand Up @@ -13,6 +13,7 @@ import $selection from '../dom/selection'
import $utils from '../cypress/utils'
import $window from '../dom/window'
import type { Log } from '../cypress/log'
import type { StateFunc } from '../cypress/state'

const debug = Debug('cypress:driver:keyboard')

Expand All @@ -23,17 +24,6 @@ export interface KeyboardModifiers {
shift: boolean
}

export interface KeyboardState {
keyboardModifiers?: KeyboardModifiers
}

export interface ProxyState<T> {
<K extends keyof T>(arg: K): T[K] | undefined
<K extends keyof T>(arg: K, arg2: T[K] | null): void
}

export type State = ProxyState<KeyboardState>

Comment on lines -26 to -36
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code is added before StateFunc type is created. Now, it's OK to remove them.

interface KeyDetailsPartial extends Partial<KeyDetails> {
key: string
}
Expand Down Expand Up @@ -169,11 +159,11 @@ const joinKeyArrayToString = (keyArr: KeyInfo[]) => {
}).join('')
}

type modifierKeyDetails = KeyDetails & {
type KeyModifiers = {
key: keyof typeof keyToModifierMap
}

const isModifier = (details: KeyInfo): details is modifierKeyDetails => {
const isModifier = (details: KeyInfo): details is KeyDetails & KeyModifiers => {
return details.type === 'key' && !!keyToModifierMap[details.key]
Comment on lines -172 to 167
Copy link
Contributor Author

Choose a reason for hiding this comment

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

modifierKeyDetails doesn't follow the TS naming conventions (naming types with the capital letter.) And KeyDetails & cause errors in other files.

}

Expand Down Expand Up @@ -697,7 +687,7 @@ export interface typeOptions {
}

export class Keyboard {
constructor (private state: State) {}
constructor (private state: StateFunc) {}

type (opts: typeOptions) {
const options = _.defaults({}, opts, {
Expand Down Expand Up @@ -1108,7 +1098,7 @@ export class Keyboard {
return details
}

flagModifier (key: modifierKeyDetails, setTo = true) {
flagModifier (key: KeyModifiers, setTo = true) {
debug('handleModifier', key.key)
const modifier = keyToModifierMap[key.key]

Expand Down
19 changes: 10 additions & 9 deletions packages/driver/src/cy/mouse.ts
Expand Up @@ -8,17 +8,22 @@ import debugFn from 'debug'
import type { StateFunc } from '../cypress/state'
import type { IFocused } from './focused'
import type { ICypress } from '../cypress'
import type { ElViewportPostion } from '../dom/coordinates'

const debug = debugFn('cypress:driver:mouse')

export type ForceEl = false | HTMLElement

export type MouseCoords = { x?: number, y?: number}

/**
* @typedef Coords
* @property {number} x
* @property {number} y
* @property {Document} doc
*/

const getLastHoveredEl = (state): HTMLElement | null => {
const getLastHoveredEl = (state: StateFunc): HTMLElement | null => {
let lastHoveredEl = state('mouseLastHoveredEl')
const lastHoveredElAttached = lastHoveredEl && $elements.isAttachedEl(lastHoveredEl)

Expand All @@ -40,7 +45,7 @@ const defaultPointerDownUpOptions = {
pressure: 0.5,
}

const getMouseCoords = (state) => {
const getMouseCoords = (state: StateFunc) => {
return state('mouseCoords')
}

Expand Down Expand Up @@ -205,11 +210,7 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused,
}, modifiersEventOptions, coordsEventOptions)
},

/**
* @param {Coords} coords
* @param {HTMLElement} forceEl
*/
move (fromElViewport, forceEl?) {
move (fromElViewport: ElViewportPostion, forceEl?: ForceEl) {
debug('mouse.move', fromElViewport)

const lastHoveredEl = getLastHoveredEl(state)
Expand Down Expand Up @@ -241,7 +242,7 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused,
* - send move events to elToHover (bubbles)
* - elLastHovered = elToHover
*/
_moveEvents (el, coords) {
_moveEvents (el: HTMLElement, coords: ElViewportPostion) {
// events are not fired on disabled elements, so we don't have to take that into account
const win = $dom.getWindowByElement(el)
const { x, y } = coords
Expand Down Expand Up @@ -386,7 +387,7 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused,
* @param {Coords} coords
* @returns {HTMLElement}
*/
getElAtCoords ({ x, y, doc }) {
getElAtCoords ({ x, y, doc }: ElViewportPostion) {
const el = $dom.elementFromPoint(doc, x, y)

return el
Expand Down
8 changes: 6 additions & 2 deletions packages/driver/src/cy/overrides.ts
@@ -1,9 +1,13 @@
import _ from 'lodash'
// @ts-ignore
import { registerFetch } from 'unfetch'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

//@ts-ignore is unnecessary because the type of registerFetch is added with patch-package.

import $selection from '../dom/selection'

export const create = (state, config, focused, snapshots) => {
import type { ICypress } from '../cypress'
import type { StateFunc } from '../cypress/state'
import type { IFocused } from './focused'
import type { ISnapshots } from './snapshots'

export const create = (state: StateFunc, config: ICypress['config'], focused: IFocused, snapshots: ISnapshots) => {
const wrapNativeMethods = function (contentWindow) {
try {
// return null to trick contentWindow into thinking
Expand Down
9 changes: 4 additions & 5 deletions packages/driver/src/cy/snapshots.ts
@@ -1,13 +1,15 @@
import $ from 'jquery'
import _ from 'lodash'
import type { $Cy } from '../cypress/cy'
import type { StateFunc } from '../cypress/state'
import $dom from '../dom'
import { create as createSnapshotsCSS } from './snapshots_css'

export const HIGHLIGHT_ATTR = 'data-cypress-el'

export const FINAL_SNAPSHOT_NAME = 'final state'

export const create = ($$, state) => {
export const create = ($$: $Cy['$$'], state: StateFunc) => {
const snapshotsCss = createSnapshotsCSS($$, state)
const snapshotsMap = new WeakMap()
const snapshotDocument = new Document()
Expand Down Expand Up @@ -296,7 +298,4 @@ export const create = ($$, state) => {
}
}

export interface ISnapshots extends Omit<
ReturnType<typeof create>,
'onCssModified' | 'onBeforeWindowLoad'
> {}
export interface ISnapshots extends ReturnType<typeof create> {}
2 changes: 1 addition & 1 deletion packages/driver/src/cy/stability.ts
Expand Up @@ -55,7 +55,7 @@ export const create = (Cypress: ICypress, state: StateFunc) => ({
state('anticipatingCrossOriginResponse', request)
},

whenStableOrAnticipatingCrossOriginResponse (fn, command) {
whenStableOrAnticipatingCrossOriginResponse (fn, command?) {
const commandIsOrigin = command?.get('name') === 'origin'
const commandIsEndLogGroup = command?.get('name') === 'end-logGroup'

Expand Down
7 changes: 3 additions & 4 deletions packages/driver/src/cy/xhrs.ts
@@ -1,12 +1,11 @@
/* globals cy */
import _ from 'lodash'

import $errUtils from '../cypress/error_utils'
import type { StateFunc } from '../cypress/state'

const validAliasApiRe = /^(\d+|all)$/

const xhrNotWaitedOnByIndex = (state, alias, index, prop) => {
const xhrNotWaitedOnByIndex = (state: StateFunc, alias: string, index: number, prop: 'requests' | 'responses') => {
// find the last request or response
// which hasnt already been used.
let xhrs = state(prop) || []
Expand All @@ -28,7 +27,7 @@ const xhrNotWaitedOnByIndex = (state, alias, index, prop) => {

// eslint-disable-next-line @cypress/dev/arrow-body-multiline-braces
export const create = (state: StateFunc) => ({
getIndexedXhrByAlias (alias, index) {
getIndexedXhrByAlias (alias: string, index: number) {
let prop
let str

Expand Down Expand Up @@ -60,7 +59,7 @@ export const create = (state: StateFunc) => ({
getRequestsByAlias (alias) {
let prop

if (_.indexOf(alias, '.') === -1 || _.keys(cy.state('aliases')).includes(alias)) {
if (_.indexOf(alias, '.') === -1 || _.keys(state('aliases')).includes(alias)) {
prop = null
} else {
// potentially valid prop
Expand Down