UNPKG

@revoloo/cypress6

Version:

Cypress.io end to end testing tool

116 lines (92 loc) 3.65 kB
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 { @observable hookId: string @observable hookName: HookName @observable hookNumber?: number @observable invocationDetails?: FileDetails @observable invocationOrder?: number @observable commands: CommandModel[] = [] @observable isStudio: boolean @observable 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 } @computed 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 } @computed get hasFailedCommand () { return !!_.find(this.commands, { state: 'failed' }) } @computed 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() } }