-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathcheck.coffee
144 lines (118 loc) · 3.99 KB
/
check.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
_ = require("lodash")
Promise = require("bluebird")
$dom = require("../../../dom")
$utils = require("../../../cypress/utils")
$errUtils = require("../../../cypress/error_utils")
$elements = require("../../../dom/elements")
checkOrUncheck = (type, subject, values = [], options = {}) ->
## we're not handling conversion of values to strings
## in case we've received numbers
## if we're not an array but we are an object
## reassign options to values
if not _.isArray(values) and _.isObject(values)
options = values
values = []
else
## make sure we're an array of values
values = [].concat(values)
## keep an array of subjects which
## are potentially reduced down
## to new filtered subjects
matchingElements = []
_.defaults options,
$el: subject
log: true
force: false
isNoop = ($el) ->
switch type
when "check"
$el.prop("checked")
when "uncheck"
not $el.prop("checked")
isAcceptableElement = ($el) ->
switch type
when "check"
$el.is(":checkbox,:radio")
when "uncheck"
$el.is(":checkbox")
## does our el have a value
## in the values array?
## or values array is empty
elHasMatchingValue = ($el) ->
value = $elements.getNativeProp($el.get(0), "value")
values.length is 0 or value in values
## blow up if any member of the subject
## isnt a checkbox or radio
checkOrUncheckEl = (el, index) =>
$el = $dom.wrap(el)
if not isAcceptableElement($el)
node = $dom.stringify($el)
word = $utils.plural(options.$el, "contains", "is")
phrase = if type is "check" then " and `:radio`" else ""
$errUtils.throwErrByPath("check_uncheck.invalid_element", {
onFail: options._log
args: { node, word, phrase, cmd: type }
})
isElActionable = elHasMatchingValue($el)
if isElActionable
matchingElements.push(el)
consoleProps = {
"Applied To": $dom.getElements($el)
"Elements": $el.length
}
if options.log and isElActionable
## figure out the options which actually change the behavior of clicks
deltaOptions = $utils.filterOutOptions(options)
options._log = Cypress.log
message: deltaOptions
$el: $el
consoleProps: ->
_.extend consoleProps, {
Options: deltaOptions
}
options._log.snapshot("before", {next: "after"})
## if the checkbox was already checked
## then notify the user of this note
## and bail
if isNoop($el)
if !options.force
## still ensure visibility even if the command is noop
cy.ensureVisibility($el, options._log)
if options._log
inputType = if $el.is(":radio") then "radio" else "checkbox"
consoleProps.Note = "This #{inputType} was already #{type}ed. No operation took place."
options._log.snapshot().end()
return null
## if we didnt pass in any values or our
## el's value is in the array then check it
if isElActionable
cy.now("click", $el, {
$el: $el
log: false
verify: false
_log: options._log
force: options.force
timeout: options.timeout
interval: options.interval
}).then ->
options._log.snapshot().end() if options._log
return null
## return our original subject when our promise resolves
Promise
.resolve(options.$el.toArray())
.each(checkOrUncheckEl)
.then ->
## filter down our $el to the
## matching elements
options.$el = options.$el.filter(matchingElements)
do verifyAssertions = =>
cy.verifyUpcomingAssertions(options.$el, options, {
onRetry: verifyAssertions
})
module.exports = (Commands, Cypress, cy, state, config) ->
Commands.addAll({ prevSubject: "element" }, {
check: (subject, values, options) ->
checkOrUncheck.call(@, "check", subject, values, options)
uncheck: (subject, values, options) ->
checkOrUncheck.call(@, "uncheck", subject, values, options)
})