@revoloo/cypress6
Version:
Cypress.io end to end testing tool
116 lines (92 loc) • 3.65 kB
text/typescript
import _ from 'lodash'
import { observable, computed } from 'mobx'
import { FileDetails } from '@packages/ui-components'
import { Alias } from '../instruments/instrument-model'
import Err from '../errors/err-model'
import CommandModel from '../commands/command-model'
export type HookName = 'before all' | 'before each' | 'after all' | 'after each' | 'test body' | 'studio commands'
export interface HookProps {
hookId: string
hookName: HookName
invocationDetails?: FileDetails
isStudio?: boolean
}
export default class Hook implements HookProps {
hookId: string
hookName: HookName
hookNumber?: number
invocationDetails?: FileDetails
invocationOrder?: number
commands: CommandModel[] = []
isStudio: boolean
failed = false
private _aliasesWithDuplicatesCache: Array<Alias> | null = null
private _currentNumber = 1
constructor (props: HookProps) {
this.hookId = props.hookId
this.hookName = props.hookName
this.invocationDetails = props.invocationDetails
this.isStudio = !!props.isStudio
}
get aliasesWithDuplicates () {
// Consecutive duplicates only appear once in command array, but hasDuplicates is true
// Non-consecutive duplicates appear multiple times in command array, but hasDuplicates is false
// This returns aliases that have consecutive or non-consecutive duplicates
let consecutiveDuplicateAliases: Array<Alias> = []
const aliases: Array<Alias> = this.commands.map((command) => {
if (command.alias) {
if (command.hasDuplicates) {
consecutiveDuplicateAliases.push(command.alias)
}
return command.alias
}
return null
})
const nonConsecutiveDuplicateAliases = aliases.filter((alias, i) => {
return aliases.indexOf(alias) === i && aliases.lastIndexOf(alias) !== i
})
const aliasesWithDuplicates = consecutiveDuplicateAliases.concat(nonConsecutiveDuplicateAliases)
// do a deep compare here to see if we can use the cached aliases, which will allow mobx's
// @computed identity comparison to pass, preventing unnecessary re-renders
// https://github.com/cypress-io/cypress/issues/4411
if (!_.isEqual(aliasesWithDuplicates, this._aliasesWithDuplicatesCache)) {
this._aliasesWithDuplicatesCache = aliasesWithDuplicates
}
return this._aliasesWithDuplicatesCache
}
get hasFailedCommand () {
return !!_.find(this.commands, { state: 'failed' })
}
get showStudioPrompt () {
return this.isStudio && !this.hasFailedCommand && (!this.commands.length || (this.commands.length === 1 && this.commands[0].name === 'visit'))
}
addCommand (command: CommandModel) {
if (!command.event && !this.isStudio) {
command.number = this._currentNumber
this._currentNumber++
}
if (this.isStudio && command.name === 'visit') {
command.number = 1
}
const lastCommand = _.last(this.commands)
if (lastCommand &&
lastCommand.isMatchingEvent &&
lastCommand.isMatchingEvent(command) &&
lastCommand.addDuplicate) {
lastCommand.addDuplicate(command)
} else {
this.commands.push(command)
}
}
removeCommand (commandId: number) {
const commandIndex = _.findIndex(this.commands, { id: commandId })
this.commands.splice(commandIndex, 1)
}
commandMatchingErr (errToMatch: Err) {
return _(this.commands)
.filter(({ err }) => {
return err && err.message === errToMatch.message && err.message !== undefined
})
.last()
}
}