scoutui 2.0.3.13.pre → 2.0.3.14.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfaa410be9c5fd6446abf3b4e38f87818add2761
4
- data.tar.gz: 634ea5ac53446a9a873a9d3552df6e6ddff0a739
3
+ metadata.gz: 50ad761505f75ae60fe1f9e0af0c13f48d139b98
4
+ data.tar.gz: 9893c66040a64e21cdb608fb75c2461a818b31c1
5
5
  SHA512:
6
- metadata.gz: a270587c067edd35289dc756168085df21ffa040d90849236592f438f5505d85df9fac302a4bcb5b16d7efc8f414145e4ec97ea1a017e266c36c262282b8d0b6
7
- data.tar.gz: e70f51d5a752bdeb644ad96f0552a4463bf3012cbb32519b92449959ca44a54a3ae53d0ad27ac11b09e818561950721adca8b77b2fd4210359a4f0b858ba184c
6
+ metadata.gz: 4ec7fa1cfc570898012d67f1592cb1ca65e8e6543fdeab29ccfb35d551904f128933025168e85d8cadc50ea8cb749ede7b448ff3fd4930dc84afa40834feaf5a
7
+ data.tar.gz: 0a4002f547265322fbc82654f8c664337a10c4dc0e1fa7f80fd691bef4ab390a2058123590b21243a2e1887b76fe39244501f1e096ca35c773063e8bab48c240
@@ -0,0 +1,48 @@
1
+ {
2
+
3
+
4
+ "main": {
5
+
6
+
7
+ "nav": {
8
+
9
+ "home": {
10
+ "locator": "css=.page-header--logo",
11
+ "visible_when": "always"
12
+ },
13
+
14
+
15
+ "findYourCar": {
16
+ "locator": "//a[text()='Find Your Car']",
17
+ "visible_when": "always"
18
+ },
19
+
20
+ "basic_search": {
21
+ "locator": "//nav//a[@href='/search']",
22
+ "visible_when": "always"
23
+ }
24
+
25
+
26
+
27
+ }
28
+
29
+
30
+
31
+ },
32
+
33
+
34
+ "basic_search": {
35
+ "free_text": {
36
+ "locator": "//input[@name='FreeText']",
37
+ "visible_when": "always"
38
+ },
39
+
40
+ "go": {
41
+ "locator": "//button[text()='Go']",
42
+ "visible_when": "always"
43
+ }
44
+ }
45
+
46
+
47
+
48
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+
3
+
4
+ "search_results": {
5
+
6
+
7
+ "results": {
8
+
9
+ "header": {
10
+ "reqid": "REQ-HEADER",
11
+ "locator": "//span[text()='Applied filters']",
12
+ "visible_when": "title(Search Results)"
13
+ }
14
+
15
+
16
+ }
17
+
18
+
19
+
20
+ }
21
+
22
+
23
+
24
+
25
+
26
+
27
+ }
@@ -0,0 +1,63 @@
1
+ page:
2
+ name: Home
3
+ description: Navigate to a specified URL and wait until the expected elements are present
4
+ url: http://www.carmax.com
5
+ ---
6
+ page:
7
+ name: Highlight Example
8
+ action: highlight(page(main).get(nav).get(findYourCar))
9
+ ---
10
+ page:
11
+ timeout: 5
12
+ name: Click Find Your Car
13
+ action: click(page(main).get(nav).get(findYourCar))
14
+ expected:
15
+ wait1: //header//*[text()='Pricex']
16
+ ---
17
+ page:
18
+ name: Basic Search
19
+ timeout: 5
20
+ action: click(page(main).get(nav).get(basic_search))
21
+ expected:
22
+ wait: page(basic_search).get(free_text)
23
+ assertions: [
24
+ elvis: {
25
+ "locator": "//button[@text()='Go']",
26
+ "visible_when": "visible(page(basic_search).get(free_text))"
27
+ },
28
+ better_assert: {
29
+ "locator": "page(basic_search)"
30
+ }
31
+ ]
32
+ ---
33
+ page:
34
+ name: Popup
35
+ timeout: 5
36
+ execute_when: visible(//area[@alt='no'])
37
+ action: click(//area[@alt='no'])
38
+ ---
39
+ page:
40
+ name: Enter Porsche
41
+ action: type(page(basic_search).get(free_text), Porsche 911)
42
+ expected:
43
+ wait: //a[contains(@href, 'Porsche%20911')]
44
+ ---
45
+ page:
46
+ action: highlight(//a[contains(@href, 'Porsche%20911')])
47
+ ---
48
+ page:
49
+ action: mouseover(//a[contains(@href, 'Porsche%20911')])
50
+ ---
51
+ page:
52
+ action: click(page(basic_search).get(go))
53
+ assertions: [
54
+ assert1: {
55
+ "locator": "page(search_results).get(results)"
56
+ }
57
+ ]
58
+ ---
59
+ page:
60
+ name: Pause after Nav.
61
+ action: pause
62
+ skipit: false
63
+
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bash
2
+
3
+
4
+ ##
5
+ # Pre-req - Sauce Connect is running
6
+ ##
7
+
8
+ setup()
9
+ {
10
+ HOST="https://www.carmax.com"
11
+ CAPS="--capabilities ../../common/capabilities/win10.chrome50.json"
12
+ CAPS="--capabilities ../../common/capabilities/win10.ff46.json"
13
+ CAPS=
14
+
15
+ USER_ID="terrybrown@commasavvy.com"
16
+ PASSWORD="password1"
17
+ TESTCFG=../testconfig/test.config.json
18
+
19
+
20
+ TITLE="CARMAX"
21
+ VIEWPORT="1024x768"
22
+
23
+ MODEL="../appmodel/main.nav.json,../appmodel/search_results.json"
24
+
25
+ EYES="--eyes --app ${TITLE} --title ${TITLE}"
26
+ EYES=
27
+
28
+ SAUCE="--sauce --sauce_name ${TITLE}"
29
+ SAUCE=
30
+
31
+ CMD="../commands/commands.yml"
32
+ CMD="../commands/basic_search.yml"
33
+ }
34
+
35
+
36
+
37
+
38
+ setup
39
+
40
+
41
+ ruby $SCOUTUI_BIN \
42
+ --config ${TESTCFG} \
43
+ --user "expense.admin@scoutui.com" --password password1 \
44
+ ${EYES} \
45
+ --viewport ${VIEWPORT} \
46
+ ${SAUCE} \
47
+ ${CAPS} \
48
+ --host ${HOST} \
49
+ --pages ${MODEL} \
50
+ --debug \
51
+ --dut "${CMD}"
52
+
@@ -0,0 +1,372 @@
1
+ {
2
+ "id": "251936793025015",
3
+ "batchId": "00000251936793025188",
4
+ "batchSessionId": "00000251936793025015",
5
+ "runningSessionId": "MDAwMDAyNTE5MzY3OTMwMjUxODg~;MDAwMDAyNTE5MzY3OTMwMjUwMTU~",
6
+ "startInfo": {
7
+ "sessionType": "Sequential",
8
+ "isTransient": false,
9
+ "ignoreBaseline": false,
10
+ "baselineEnvName": null,
11
+ "envName": null,
12
+ "appIdOrName": "Login.Francais",
13
+ "branchName": null,
14
+ "parentBranchName": null,
15
+ "scenarioIdOrName": "Login.Francais",
16
+ "batchInfo": {
17
+ "id": "40c03594-1943-4f89-8cd2-5f338b708fd0",
18
+ "name": "Login.Francais",
19
+ "startedAt": "2016-06-09T14:29:34-07:00"
20
+ },
21
+ "environment": {
22
+ "inferred": "useragent:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
23
+ "os": "Windows 10.0",
24
+ "hostingApp": "Firefox",
25
+ "displaySize": {
26
+ "width": 1280,
27
+ "height": 1024
28
+ }
29
+ },
30
+ "matchLevel": "Layout",
31
+ "defaultMatchSettings": {
32
+ "matchLevel": "Layout",
33
+ "ignore": [
34
+
35
+ ],
36
+ "layout": [
37
+
38
+ ],
39
+ "content": [
40
+
41
+ ],
42
+ "floating": [
43
+
44
+ ],
45
+ "splitTopHeight": 0,
46
+ "splitBottomHeight": 0,
47
+ "exact": null
48
+ },
49
+ "agentId": "eyes.selenium.ruby/2.30.0"
50
+ },
51
+ "expectedOutput": [
52
+ {
53
+ "tag": "Fill Login Form",
54
+ "image": {
55
+ "id": "se~df8a56d3-fa46-404c-aebe-0ab7a5234bba",
56
+ "size": {
57
+ "width": 1280,
58
+ "height": 1024
59
+ }
60
+ },
61
+ "thumbprint": {
62
+ "id": "se~64dccbdb-e9af-440b-aca3-21ce664e3154",
63
+ "size": {
64
+ "width": 220,
65
+ "height": 176
66
+ }
67
+ },
68
+ "matchSettings": {
69
+ "matchLevel": "Layout",
70
+ "ignore": [
71
+ {
72
+ "left": 407,
73
+ "top": 62,
74
+ "width": 873,
75
+ "height": 852
76
+ },
77
+ {
78
+ "left": 0,
79
+ "top": 501,
80
+ "width": 440,
81
+ "height": 376
82
+ },
83
+ {
84
+ "left": 199,
85
+ "top": 66,
86
+ "width": 245,
87
+ "height": 101
88
+ },
89
+ {
90
+ "left": 58,
91
+ "top": 175,
92
+ "width": 294,
93
+ "height": 31
94
+ },
95
+ {
96
+ "left": 60,
97
+ "top": 245,
98
+ "width": 362,
99
+ "height": 32
100
+ }
101
+ ],
102
+ "layout": [
103
+
104
+ ],
105
+ "content": [
106
+
107
+ ],
108
+ "floating": [
109
+
110
+ ],
111
+ "splitTopHeight": 0,
112
+ "splitBottomHeight": 0,
113
+ "exact": null
114
+ },
115
+ "annotationSettings": null,
116
+ "appEnvironment": {
117
+ "inferred": "useragent:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
118
+ "os": "Windows 10.0",
119
+ "hostingApp": "Firefox",
120
+ "displaySize": {
121
+ "width": 1280,
122
+ "height": 1024
123
+ }
124
+ }
125
+ },
126
+ {
127
+ "tag": "SubmitForm LoginForm",
128
+ "image": {
129
+ "id": "se~a4e2111b-0689-4445-b019-57f6fcebaf76",
130
+ "size": {
131
+ "width": 1280,
132
+ "height": 1024
133
+ }
134
+ },
135
+ "thumbprint": {
136
+ "id": "se~338e643a-43ca-4e7f-8001-19f87abae236",
137
+ "size": {
138
+ "width": 220,
139
+ "height": 176
140
+ }
141
+ },
142
+ "matchSettings": {
143
+ "matchLevel": "Layout",
144
+ "ignore": [
145
+
146
+ ],
147
+ "layout": [
148
+
149
+ ],
150
+ "content": [
151
+
152
+ ],
153
+ "floating": [
154
+
155
+ ],
156
+ "splitTopHeight": 0,
157
+ "splitBottomHeight": 0,
158
+ "exact": null
159
+ },
160
+ "annotationSettings": null,
161
+ "appEnvironment": {
162
+ "inferred": "useragent:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
163
+ "os": "Windows 10.0",
164
+ "hostingApp": "Firefox",
165
+ "displaySize": {
166
+ "width": 1280,
167
+ "height": 1024
168
+ }
169
+ }
170
+ },
171
+ {
172
+ "tag": "Landing Page",
173
+ "image": {
174
+ "id": "se~0525f4d6-6c6b-4fa2-8ac1-3064a66a3ccb",
175
+ "size": {
176
+ "width": 1263,
177
+ "height": 1206
178
+ }
179
+ },
180
+ "thumbprint": {
181
+ "id": "se~d9ce0143-ab2d-42f1-b3fe-ab8587b3a077",
182
+ "size": {
183
+ "width": 209,
184
+ "height": 200
185
+ }
186
+ },
187
+ "matchSettings": {
188
+ "matchLevel": "Layout",
189
+ "ignore": [
190
+ {
191
+ "left": 1096,
192
+ "top": 999,
193
+ "width": 167,
194
+ "height": 24
195
+ },
196
+ {
197
+ "left": 445,
198
+ "top": 740,
199
+ "width": 788,
200
+ "height": 172
201
+ }
202
+ ],
203
+ "layout": [
204
+
205
+ ],
206
+ "content": [
207
+
208
+ ],
209
+ "floating": [
210
+
211
+ ],
212
+ "splitTopHeight": 0,
213
+ "splitBottomHeight": 0,
214
+ "exact": null
215
+ },
216
+ "annotationSettings": null,
217
+ "appEnvironment": {
218
+ "inferred": "useragent:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
219
+ "os": "Windows 10.0",
220
+ "hostingApp": "Firefox",
221
+ "displaySize": {
222
+ "width": 1280,
223
+ "height": 1024
224
+ }
225
+ }
226
+ }
227
+ ],
228
+
229
+
230
+
231
+ "actualOutput": [
232
+ {
233
+ "image": {
234
+ "id": "sa~819b8141-a8e2-44d2-9559-fd3c948bf3c7",
235
+ "size": {
236
+ "width": 1280,
237
+ "height": 1024
238
+ }
239
+ },
240
+ "thumbprint": {
241
+ "id": "sa~7f3cfc1f-664b-4991-9b9d-2ed8dac4cb59",
242
+ "size": {
243
+ "width": 220,
244
+ "height": 176
245
+ }
246
+ },
247
+ "imageMatchSettings": {
248
+ "matchLevel": "Layout",
249
+ "ignore": [
250
+
251
+ ],
252
+ "layout": [
253
+
254
+ ],
255
+ "content": [
256
+
257
+ ],
258
+ "floating": [
259
+
260
+ ],
261
+ "splitTopHeight": 0,
262
+ "splitBottomHeight": 0,
263
+ "exact": null
264
+ },
265
+ "ignoreExpectedOutputSettings": false,
266
+ "expectedImageId": null,
267
+ "expectedThumbprintId": null,
268
+ "isMatching": false,
269
+ "expectedMatchLevel": "None",
270
+ "occurredAt": "2016-06-09T21:30:18.6123465+00:00",
271
+ "userInputs": [
272
+
273
+ ],
274
+ "windowTitle": "Connexion à Concur | Solutions Concur",
275
+ "tag": "Fill Login Form",
276
+ "isPrimary": false
277
+ },
278
+ {
279
+ "image": {
280
+ "id": "sa~c4379ad8-30e3-4674-9225-14cbca4c3822",
281
+ "size": {
282
+ "width": 1280,
283
+ "height": 1024
284
+ }
285
+ },
286
+ "thumbprint": {
287
+ "id": "sa~4293cbb4-badf-483b-bcf1-d85c6542e737",
288
+ "size": {
289
+ "width": 220,
290
+ "height": 176
291
+ }
292
+ },
293
+ "imageMatchSettings": {
294
+ "matchLevel": "Layout",
295
+ "ignore": [
296
+
297
+ ],
298
+ "layout": [
299
+
300
+ ],
301
+ "content": [
302
+
303
+ ],
304
+ "floating": [
305
+
306
+ ],
307
+ "splitTopHeight": 0,
308
+ "splitBottomHeight": 0,
309
+ "exact": null
310
+ },
311
+ "ignoreExpectedOutputSettings": false,
312
+ "expectedImageId": null,
313
+ "expectedThumbprintId": null,
314
+ "isMatching": true,
315
+ "expectedMatchLevel": "None",
316
+ "occurredAt": "2016-06-09T21:31:05.9962035+00:00",
317
+ "userInputs": [
318
+
319
+ ],
320
+ "windowTitle": "Concur - cliquer. Terminé.",
321
+ "tag": "SubmitForm LoginForm",
322
+ "isPrimary": false
323
+ },
324
+ {
325
+ "image": {
326
+ "id": "sa~b96d917d-0d87-4f40-8d21-0ecddde11a1e",
327
+ "size": {
328
+ "width": 1263,
329
+ "height": 1206
330
+ }
331
+ },
332
+ "thumbprint": {
333
+ "id": "sa~34865536-0b04-4af7-993a-51095a41473f",
334
+ "size": {
335
+ "width": 209,
336
+ "height": 200
337
+ }
338
+ },
339
+ "imageMatchSettings": {
340
+ "matchLevel": "Layout",
341
+ "ignore": [
342
+
343
+ ],
344
+ "layout": [
345
+
346
+ ],
347
+ "content": [
348
+
349
+ ],
350
+ "floating": [
351
+
352
+ ],
353
+ "splitTopHeight": 0,
354
+ "splitBottomHeight": 0,
355
+ "exact": null
356
+ },
357
+ "ignoreExpectedOutputSettings": false,
358
+ "expectedImageId": null,
359
+ "expectedThumbprintId": null,
360
+ "isMatching": false,
361
+ "expectedMatchLevel": "None",
362
+ "occurredAt": "2016-06-09T21:31:21.4039792+00:00",
363
+ "userInputs": [
364
+
365
+ ],
366
+ "windowTitle": "Accueil",
367
+ "tag": "Landing Page",
368
+ "isPrimary": false
369
+ }
370
+ ],
371
+ "outputResolution": null
372
+ }
@@ -28,7 +28,8 @@ module Scoutui::Base
28
28
  end
29
29
 
30
30
  def getViewPort()
31
- arr=Scoutui::Base::UserVars.instance.getVar('eyes.viewport').match(/(\d+)\s*x\s*(\d+)$/i)
31
+ arr=Scoutui::Base::UserVars.instance.getVar('eyes.viewport').match(/^\s*(\d+)\s*x\s*(\d+)\s*$/i)
32
+ _sz={}
32
33
  if arr.size==3
33
34
  _sz = {width: arr[1].to_i, height: arr[2].to_i}
34
35
  end
@@ -15,19 +15,62 @@ module Scoutui::Commands
15
15
  begin
16
16
  _window_id = @cmd.match(/select_window\s*\((.*)\)/)[1].to_s.strip
17
17
 
18
+ matchWith={ :by => nil, :value => nil }
19
+ if _window_id.match(/^\d+$/)
20
+ matchWith = { :by => :index, :value => _window_id.to_i }
21
+ elsif _window_id.empty?
22
+ matchWith = { :by => :switch_new_window }
23
+ elsif _window_id.is_a?(String)
24
+ matchWith = { :by => :regex, :value => Regexp.new(_window_id)}
25
+ else
26
+ Scoutui::Logger::LogMgr.instance.warn __FILE__ + (__LINE__).to_s + " Unknown arg #{_window_id}"
27
+ end
28
+
18
29
  Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " ==> WindowID : #{_window_id}"
19
30
  Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " ==> handles : #{@drv.window_handles.length.to_s}"
20
31
 
21
- i=0
32
+ i=1
33
+
34
+ current_window=@drv.window_handle
35
+
36
+
22
37
  @drv.window_handles.each do |_w|
23
38
  puts __FILE__ + (__LINE__).to_s + "#{i}. #{_w.class.to_s}"
24
- @drv.switch_to.window(_w)
25
- Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " Title : #{@drv.title.to_s}"
39
+
40
+ if matchWith[:by]==:index && i==matchWith[:value]
41
+ Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " select_window : #{i}"
42
+ _rc=true
43
+ elsif matchWith[:by]==:switch_new_window && current_window!=_w
44
+
45
+ _rc = true
46
+
47
+ elsif matchWith[:by]==:regex
48
+ @drv.switch_to.window(_w)
49
+
50
+ if @drv.title.to_s.match(matchWith[:value])
51
+
52
+ Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " matched by regex"
53
+ _rc=true
54
+ else
55
+ @drv.switch_to.window(current_window)
56
+ end
57
+ end
58
+
59
+ Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " Active Title : #{@drv.title.to_s}"
60
+
61
+ if _rc
62
+
63
+ @drv.switch_to.window(_w) if matchWith[:by]!=:regex
64
+
65
+ puts __FILE__ + (__LINE__).to_s + " switched => #{@drv.title}"
66
+ break
67
+ end
68
+
69
+ i+=1
26
70
  end
27
71
 
28
72
  Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " switched to i #{i} given windowID #{_window_id}";
29
73
 
30
- _rc=true
31
74
  rescue => ex
32
75
  Scoutui::Logger::LogMgr.instance.debug "Error during processing: #{$!}"
33
76
  Scoutui::Logger::LogMgr.instance.debug "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
@@ -27,10 +27,19 @@ module Scoutui::Commands
27
27
 
28
28
  _rc=false
29
29
  begin
30
+ Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " navigate.to(#{url})"
31
+
32
+ _start=Time.now
30
33
  @drv.navigate.to(url)
34
+ _stop=Time.now
35
+ _duration=_stop - _start
36
+
37
+ puts __FILE__ + (__LINE__).to_s + " Perf navigate to #{url} : #{_duration}"
38
+ Scoutui::Logger::LogMgr.instance.debug __FILE__ + (__LINE__).to_s + " => title #{@drv.title.to_s}"
31
39
  _rc=true
32
- rescue
33
- ;
40
+ rescue => ex
41
+ Scoutui::Logger::LogMgr.instance.warn __FILE__ + (__LINE__).to_s + " Error during processing: #{ex.message}"
42
+ Scoutui::Logger::LogMgr.instance.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
34
43
  end
35
44
 
36
45
 
@@ -1,3 +1,3 @@
1
1
  module Scoutui
2
- VERSION = "2.0.3.13.pre"
2
+ VERSION = "2.0.3.14.pre"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scoutui
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3.13.pre
4
+ version: 2.0.3.14.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Kim
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-06-06 00:00:00.000000000 Z
12
+ date: 2016-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -185,6 +185,10 @@ files:
185
185
  - bin/scoutui_driver.rb
186
186
  - bin/setup
187
187
  - examples/capabilities/win10.chrome46.json
188
+ - examples/carmax/appmodel/main.nav.json
189
+ - examples/carmax/appmodel/search_results.json
190
+ - examples/carmax/commands/commands.yml
191
+ - examples/carmax/tests/test-carmax.sh
188
192
  - examples/ex1/commands.holidays.yml
189
193
  - examples/ex1/commands.yml
190
194
  - examples/ex1/test-example.sh
@@ -215,6 +219,7 @@ files:
215
219
  - examples/ex2/tests/test-example2.sh
216
220
  - examples/ex2/tests/test-example3.sauce.sh
217
221
  - examples/ex2/tests/test-example3.sh
222
+ - examples/eyes_results/response.json
218
223
  - lib/scoutui.rb
219
224
  - lib/scoutui/appmodel/q_model.rb
220
225
  - lib/scoutui/base/assertions.rb