prism_checker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +28 -0
  3. data/README.md +673 -0
  4. data/lib/prism_checker/absence_expectation.rb +9 -0
  5. data/lib/prism_checker/check_dispatcher.rb +168 -0
  6. data/lib/prism_checker/checker.rb +83 -0
  7. data/lib/prism_checker/colorizer.rb +9 -0
  8. data/lib/prism_checker/config.rb +14 -0
  9. data/lib/prism_checker/element_wrapper.rb +59 -0
  10. data/lib/prism_checker/expectation_classifier.rb +71 -0
  11. data/lib/prism_checker/item_checker/any.rb +25 -0
  12. data/lib/prism_checker/item_checker/array.rb +27 -0
  13. data/lib/prism_checker/item_checker/checkbox.rb +29 -0
  14. data/lib/prism_checker/item_checker/element.rb +52 -0
  15. data/lib/prism_checker/item_checker/elements.rb +53 -0
  16. data/lib/prism_checker/item_checker/image.rb +22 -0
  17. data/lib/prism_checker/item_checker/input.rb +27 -0
  18. data/lib/prism_checker/item_checker/item_check/empty.rb +17 -0
  19. data/lib/prism_checker/item_checker/item_check/empty_array.rb +17 -0
  20. data/lib/prism_checker/item_checker/item_check/number.rb +17 -0
  21. data/lib/prism_checker/item_checker/item_check/regexp.rb +17 -0
  22. data/lib/prism_checker/item_checker/item_check/string.rb +25 -0
  23. data/lib/prism_checker/item_checker/item_value/array.rb +13 -0
  24. data/lib/prism_checker/item_checker/item_value/element.rb +13 -0
  25. data/lib/prism_checker/item_checker/item_value/elements.rb +13 -0
  26. data/lib/prism_checker/item_checker/item_value/image.rb +13 -0
  27. data/lib/prism_checker/item_checker/item_value/input.rb +13 -0
  28. data/lib/prism_checker/item_checker/item_value/page.rb +13 -0
  29. data/lib/prism_checker/item_checker/item_value/string.rb +13 -0
  30. data/lib/prism_checker/item_checker/item_value/textarea.rb +13 -0
  31. data/lib/prism_checker/item_checker/nil.rb +35 -0
  32. data/lib/prism_checker/item_checker/page.rb +38 -0
  33. data/lib/prism_checker/item_checker/string.rb +26 -0
  34. data/lib/prism_checker/item_checker/textarea.rb +26 -0
  35. data/lib/prism_checker/item_classifier.rb +126 -0
  36. data/lib/prism_checker/node/array.rb +26 -0
  37. data/lib/prism_checker/node/bad_expectation.rb +7 -0
  38. data/lib/prism_checker/node/base.rb +140 -0
  39. data/lib/prism_checker/node/check_fail.rb +7 -0
  40. data/lib/prism_checker/node/expectation.rb +15 -0
  41. data/lib/prism_checker/node/hash.rb +27 -0
  42. data/lib/prism_checker/report_builder.rb +78 -0
  43. data/lib/prism_checker.rb +19 -0
  44. metadata +261 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 293259849111a692566479fa23b337d18445cdff5d2ba171ebaf387d859cd2f6
4
+ data.tar.gz: 9545a7363e5d73a6b949818c80e8fd4b50d8bfc12037be33c95af88a4466f8df
5
+ SHA512:
6
+ metadata.gz: 27f8df44e17367ec6982399925dbf2faf4313bb4f17c22f4cc59cf28841be5f80b11b2c77d114ca9645a748efc91fafe5ddd90982d3f740d1998860b0b2b4d22
7
+ data.tar.gz: e2a7351f54cdd62d8365a97d169b29a3b5befa9acb3dbf9f30cffae1097a405fd982a87862b70d717d2fb7674324406cdc3872c1eb9dc7b93d47fab0f05df4d6
data/LICENSE.md ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2011-2021, The SitePrism team
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its contributors
16
+ may be used to endorse or promote products derived from this software without
17
+ specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,673 @@
1
+ ![ci workflow](https://github.com/prism-checker/prism_checker/actions/workflows/ci-main.yml/badge.svg)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/c497733cb53175decd0f/maintainability)](https://codeclimate.com/github/prism-checker/prism_checker/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/c497733cb53175decd0f/test_coverage)](https://codeclimate.com/github/prism-checker/prism_checker/test_coverage)
4
+
5
+ ## Overview
6
+
7
+ Prism checker - short and easy-to-read browser tests with clear error messages.
8
+ Prism checker - extensions for rspec and minitest, built on top of the site_prism gem and uses its Page Object Model.
9
+
10
+ For example, we need to test the online shop cart:
11
+
12
+ ![Cart](doc/images/cart.png "Cart")
13
+
14
+ Corresponding SitePrism Page Object Model:
15
+
16
+ ```ruby
17
+ class Cart < SitePrism::Page
18
+ set_url '/cart.html'
19
+
20
+ element :header, 'h1'
21
+
22
+ sections :cart_items, '[data-test="cart-item"]' do
23
+ element :name, '[data-test="cart-item-name"]'
24
+ element :image, '[data-test="cart-item-image"]'
25
+ element :price, '[data-test="cart-item-price"]'
26
+ element :quantity, '[data-test="cart-item-quantity"]'
27
+ element :total, '[data-test="cart-item-total"]'
28
+ end
29
+
30
+ section :checkout, '[data-test="cart-checkout"]' do
31
+ element :total, '[data-test="cart-checkout-total"]'
32
+ element :checkout_button, '[data-test="cart-checkout-button"]'
33
+ end
34
+ end
35
+ ```
36
+
37
+ A typical test would look like this:
38
+
39
+ ```ruby
40
+ describe 'Cart' do
41
+ it 'is correct' do
42
+ page = Cart.new
43
+ page.load
44
+
45
+ expect(page.header.text).to eq('Shopping Cart')
46
+
47
+ expect(page.cart_items.size).to eq(2)
48
+
49
+ expect(page.cart_items[0].visible?).to be_truthy
50
+ expect(page.cart_items[0].name.text).to match('Cup')
51
+ expect(page.cart_items[0].quantity.value).to match('1')
52
+ expect(page.cart_items[0].image[:src]).to match('cup.png')
53
+ expect(page.cart_items[0].price.text).to match('19.00')
54
+ expect(page.cart_items[0].total.text).to match('19.00')
55
+
56
+ expect(page.cart_items[1].visible?).to be_truthy
57
+ expect(page.cart_items[1].name.text).to match('Cap')
58
+ expect(page.cart_items[1].quantity.value).to match('2')
59
+ expect(page.cart_items[1].image[:src]).to match('cap.png')
60
+ expect(page.cart_items[1].price.text).to match('24.00')
61
+ expect(page.cart_items[1].total.text).to match('48.00')
62
+
63
+ expect(page.checkout.visible?).to be_truthy
64
+ expect(page.checkout.total.text).to match('67.99')
65
+ expect(page.checkout.checkout_button.text).to match('Checkout')
66
+ end
67
+ end
68
+ ```
69
+
70
+ Using gem prism_checker, the same test will look much cleaner and simpler:
71
+
72
+ ```ruby
73
+ describe 'Cart' do
74
+ it 'is correct' do
75
+ page = Cart.new
76
+ page.load
77
+
78
+ expect(page).to be_like(
79
+ header: 'Shopping Cart',
80
+ cart_items: [
81
+ {
82
+ name: 'Cup',
83
+ quantity: '1',
84
+ image: 'cup.png',
85
+ price: '19.00',
86
+ total: '19.00'
87
+ },
88
+ {
89
+ name: 'Cap',
90
+ quantity: '2',
91
+ image: 'cap.png',
92
+ price: '24.00',
93
+ total: '48.00'
94
+ }
95
+ ],
96
+ checkout: {
97
+ total: '67.00',
98
+ checkout_button: 'Checkout'
99
+ }
100
+ )
101
+ end
102
+ end
103
+
104
+ ```
105
+
106
+ In case of errors, an easy-to-read message will be displayed:
107
+
108
+ ![Result](doc/images/result.png "Result")
109
+
110
+ **Note.**
111
+ _All examples are for rsepc, for mintest it will be the same, but instead of expect(page).be_like(expectation) it will be assert_page_like(page, expectation)_
112
+
113
+ ## Install
114
+ To install PrismChecker:
115
+
116
+ ### RSpec
117
+
118
+ ```bash
119
+ gem install prism_checker_rspec
120
+ ```
121
+ ### MiniTest
122
+
123
+ ```bash
124
+ gem install prism_checker_minitest
125
+ ```
126
+
127
+ ## Examples
128
+ ### Common cases
129
+
130
+ Page and Page Object Model:
131
+
132
+ ![Cart](doc/images/cart.png "Cart")
133
+
134
+ ```ruby
135
+ class Cart < SitePrism::Page
136
+ element :header, 'h1'
137
+
138
+ sections :cart_items, '[data-test="cart-item"]' do
139
+ element :name, '[data-test="cart-item-name"]'
140
+ element :price, '[data-test="cart-item-price"]'
141
+ end
142
+
143
+ section :checkout, '[data-test="cart-checkout"]' do
144
+ element :total, '[data-test="cart-checkout-total"]'
145
+ element :checkout_button, '[data-test="cart-checkout-button"]'
146
+ end
147
+ end
148
+ ```
149
+
150
+
151
+ #### Check text on the page
152
+
153
+ ```ruby
154
+ @page = Cart.new
155
+ page.load
156
+
157
+ expect(page).to be_like('Shopping Cart')
158
+
159
+ # Same as
160
+ # expect(page.loaded?).to eq(true)
161
+ # expect(page).to match('Shopping Cart')
162
+ ```
163
+
164
+
165
+ #### Check element and section
166
+
167
+ ```ruby
168
+ @page = Cart.new
169
+ page.load
170
+
171
+ expect(page).to be_like(
172
+ header: 'Shopping Cart',
173
+ checkout: {
174
+ total: '67.99',
175
+ checkout_button: 'Checkout'
176
+ }
177
+ )
178
+
179
+ # Same as
180
+ # expect(page.loaded?).to eq(true)
181
+ # expect(page.header.visible?).to eq(true)
182
+ # expect(page.header.text).to match('Shopping Cart')
183
+ # expect(page.checkout.visible?).to eq(true)
184
+ # expect(page.checkout.total.visible?).to eq(true)
185
+ # expect(page.checkout.total.text).to match('67.99')
186
+ # expect(page.checkout.checkout_button.visible?).to eq(true)
187
+ # expect(page.checkout.checkout_button.text).to match('Checkout')
188
+ ```
189
+
190
+
191
+ #### Check element
192
+
193
+ ```ruby
194
+ @page = Cart.new
195
+ page.load
196
+
197
+ # page.header is inspected, not page
198
+
199
+ expect(page.header).to be_like('Shopping Cart')
200
+
201
+ # Same as
202
+ # expect(page.header.visible?).to eq(true)
203
+ # expect(page.header.text).to match('Shopping Cart')
204
+ ```
205
+ ```ruby
206
+ @page = Cart.new
207
+ page.load
208
+
209
+ # page is inspected
210
+
211
+ expect(page).to be_like(header: 'Shopping Cart')
212
+
213
+ # Same as
214
+ # expect(page.loaded?).to eq(true)
215
+ # expect(page.header.visible?).to eq(true)
216
+ # expect(page.header.text).to match('Shopping Cart')
217
+ ```
218
+
219
+
220
+ #### Check section
221
+
222
+ ```ruby
223
+ expect(page.checkout).to be_like(
224
+ total: '67.99',
225
+ checkout_button: 'Checkout'
226
+ )
227
+
228
+ # Same as
229
+ # expect(page.checkout.visible?).to eq(true)
230
+ # expect(page.checkout.total.visible?).to eq(true)
231
+ # expect(page.checkout.total.text).to match('67.99')
232
+ # expect(page.checkout.checkout_button.visible?).to eq(true)
233
+ # expect(page.checkout.checkout_button.text).to match('Checkout')
234
+ ```
235
+ ```ruby
236
+ expect(page).to be_like(
237
+ checkout: {
238
+ total: '67.99',
239
+ checkout_button: 'Checkout'
240
+ }
241
+ )
242
+
243
+ # Same as
244
+ # expect(page.loaded?).to eq(true)
245
+ # expect(page.checkout.visible?).to eq(true)
246
+ # expect(page.checkout.total.visible?).to eq(true)
247
+ # expect(page.checkout.total.text).to match('67.99')
248
+ # expect(page.checkout.checkout_button.visible?).to eq(true)
249
+ # expect(page.checkout.checkout_button.text).to match('Checkout')
250
+ ```
251
+
252
+
253
+ #### Check sections
254
+
255
+ ```ruby
256
+ expect(page).to be_like(
257
+ cart_items: [
258
+ {
259
+ name: 'Cup',
260
+ image: 'cup.png'
261
+ },
262
+ {
263
+ name: 'Cap',
264
+ image: 'cap.png'
265
+ }
266
+ ])
267
+
268
+ # Same as
269
+ # expect(page.loaded?).to eq(true)
270
+ # expect(page.cart_items.size).to eq([{:name=>"Cup", :image=>"cup.png"}, {:name=>"Cap", :image=>"cap.png"}].size)
271
+ # expect(page.cart_items[0].visible?).to eq(true)
272
+ # expect(page.cart_items[0].name.visible?).to eq(true)
273
+ # expect(page.cart_items[0].name.text).to match('Cup')
274
+ # expect(page.cart_items[0].image.visible?).to eq(true)
275
+ # expect(page.cart_items[0].image['src']).to match('cup.png')
276
+ # expect(page.cart_items[1].visible?).to eq(true)
277
+ # expect(page.cart_items[1].name.visible?).to eq(true)
278
+ # expect(page.cart_items[1].name.text).to match('Cap')
279
+ # expect(page.cart_items[1].image.visible?).to eq(true)
280
+ # expect(page.cart_items[1].image['src']).to match('cap.png')
281
+ ```
282
+ ```ruby
283
+ expect(page).to be_like(cart_items: 2)
284
+
285
+ # Same as
286
+ # expect(page.loaded?).to eq(true)
287
+ # expect(page.cart_items.size).to eq(2)
288
+ ```
289
+ ```ruby
290
+ expect(page).to be_like(cart_items: [{name: 'Cup'}, {}])
291
+
292
+ # Same as
293
+ # expect(page.loaded?).to eq(true)
294
+ # expect(page.cart_items.size).to eq([{:name=>"Cup"}, {}].size)
295
+ # expect(page.cart_items[0].visible?).to eq(true)
296
+ # expect(page.cart_items[0].name.visible?).to eq(true)
297
+ # expect(page.cart_items[0].name.text).to match('Cup')
298
+ # expect(page.cart_items[1].visible?).to eq(true)
299
+ ```
300
+
301
+ Warning! It is not possible to pass directly array:
302
+ ```ruby
303
+ expect(page.cart_items).to be_like([{name: 'Cup'}, {name: 'Cap'}]) # Error
304
+ expect(page).to be_like(cart_items: [{name: 'Cup'}, {name: 'Cap'}]) # Ok
305
+ ```
306
+
307
+
308
+ #### Check elements
309
+
310
+ ```ruby
311
+ expect(page).to be_like(
312
+ items: [
313
+ 'Item 1',
314
+ 'Item 2'
315
+ ])
316
+
317
+ # Same as
318
+ # expect(page.loaded?).to eq(true)
319
+ # expect(page.items.size).to eq(["Item 1", "Item 2"].size)
320
+ # expect(page.items[0].visible?).to eq(true)
321
+ # expect(page.items[0].text).to match('Item 1')
322
+ # expect(page.items[1].visible?).to eq(true)
323
+ # expect(page.items[1].text).to match('Item 2')
324
+ ```
325
+ ```ruby
326
+ expect(page).to be_like(items: 2)
327
+
328
+ # Same as
329
+ # expect(page.loaded?).to eq(true)
330
+ # expect(page.items.size).to eq(2)
331
+ ```
332
+ ### HTML elements
333
+ Page Object Model:
334
+ ```ruby
335
+ class HtmlElements < SitePrism::Page
336
+ set_url '/html_elements.html'
337
+
338
+ element :input, 'input.input'
339
+ element :textarea, 'textarea.textarea'
340
+ element :button, 'button'
341
+ element :button_input, 'input.button'
342
+ element :image, 'img.image'
343
+ elements :radios, 'input.radio'
344
+ elements :checkboxes, 'input.checkbox'
345
+ elements :selects, 'select.select'
346
+ end
347
+ ```
348
+
349
+ #### Input
350
+
351
+ ```ruby
352
+ expect(page).to be_like(input: 'Some text')
353
+
354
+ # Same as
355
+ # expect(page.loaded?).to eq(true)
356
+ # expect(page.input.visible?).to eq(true)
357
+ # expect(page.input.value).to match('Some text')
358
+ ```
359
+ ```ruby
360
+ expect(page.input).to be_like(
361
+ value: 'Some text',
362
+ class: 'input',
363
+ readonly: false,
364
+ disabled: false
365
+ )
366
+
367
+ # Same as
368
+ # expect(page.input.visible?).to eq(true)
369
+ # expect(page.input.value).to match('Some text')
370
+ # expect(page.input[:class]).to match('input')
371
+ # expect(page.input.readonly?).to eq(false)
372
+ # expect(page.input.disabled?).to eq(false)
373
+ ```
374
+
375
+ #### Button
376
+
377
+ ```ruby
378
+ expect(page).to be_like(button: 'Button')
379
+
380
+ # Same as
381
+ # expect(page.loaded?).to eq(true)
382
+ # expect(page.button.visible?).to eq(true)
383
+ # expect(page.button.text).to match('Button')
384
+ ```
385
+ ```ruby
386
+ expect(page.button).to be_like(
387
+ text: 'Button',
388
+ disabled: false
389
+ )
390
+
391
+ # Same as
392
+ # expect(page.button.visible?).to eq(true)
393
+ # expect(page.button.text).to match('Button')
394
+ # expect(page.button.disabled?).to eq(false)
395
+ ```
396
+
397
+ #### Textarea
398
+
399
+ ```ruby
400
+ expect(page).to be_like(textarea: 'Some text')
401
+
402
+ # Same as
403
+ # expect(page.loaded?).to eq(true)
404
+ # expect(page.textarea.visible?).to eq(true)
405
+ # expect(page.textarea.value).to match('Some text')
406
+ ```
407
+ ```ruby
408
+ expect(page.textarea).to be_like(
409
+ value: /Some text/,
410
+ class: 'textarea'
411
+ )
412
+
413
+ # Same as
414
+ # expect(page.textarea.visible?).to eq(true)
415
+ # expect(page.textarea.value).to match(/Some text/)
416
+ # expect(page.textarea[:class]).to match('textarea')
417
+ ```
418
+
419
+ #### Image
420
+
421
+ ```ruby
422
+ expect(page).to be_like(image: /logo.png$/)
423
+
424
+ # Same as
425
+ # expect(page.loaded?).to eq(true)
426
+ # expect(page.image.visible?).to eq(true)
427
+ # expect(page.image['src']).to match(/logo.png$/)
428
+ ```
429
+ ```ruby
430
+ expect(page.image).to be_like(
431
+ src: 'logo.png',
432
+ class: 'logo',
433
+ alt: 'Logo'
434
+ )
435
+
436
+ # Same as
437
+ # expect(page.image.visible?).to eq(true)
438
+ # expect(page.image.src).to match('logo.png')
439
+ # expect(page.image[:class]).to match('logo')
440
+ # expect(page.image[:alt]).to match('Logo')
441
+ ```
442
+
443
+ #### Radio
444
+
445
+ ```ruby
446
+ expect(page).to be_like(radios: [
447
+ {
448
+ checked: false,
449
+ name: 'radio1'
450
+ },
451
+ {
452
+ checked: true,
453
+ },
454
+ {
455
+ checked: false,
456
+ },
457
+ ])
458
+
459
+ # Same as
460
+ # expect(page.loaded?).to eq(true)
461
+ # expect(page.radios.size).to eq([{:checked=>false, :name=>"radio1"}, {:checked=>true}, {:checked=>false}].size)
462
+ # expect(page.radios[0].visible?).to eq(true)
463
+ # expect(page.radios[0].checked?).to eq(false)
464
+ # expect(page.radios[0].name).to match('radio1')
465
+ # expect(page.radios[1].visible?).to eq(true)
466
+ # expect(page.radios[1].checked?).to eq(true)
467
+ # expect(page.radios[2].visible?).to eq(true)
468
+ # expect(page.radios[2].checked?).to eq(false)
469
+ ```
470
+ ```ruby
471
+ expect(page).to be_like(radios: [
472
+ false,
473
+ true,
474
+ false
475
+ ])
476
+
477
+ # Same as
478
+ # expect(page.loaded?).to eq(true)
479
+ # expect(page.radios.size).to eq([false, true, false].size)
480
+ # expect(page.radios[0].visible?).to eq(true)
481
+ # expect(page.radios[0].checked?).to eq(false)
482
+ # expect(page.radios[1].visible?).to eq(true)
483
+ # expect(page.radios[1].checked?).to eq(true)
484
+ # expect(page.radios[2].visible?).to eq(true)
485
+ # expect(page.radios[2].checked?).to eq(false)
486
+ ```
487
+
488
+ #### Check box
489
+
490
+ ```ruby
491
+ expect(page).to be_like(checkboxes: [
492
+ {
493
+ checked: false,
494
+ id: "checkbox-not-checked"
495
+ },
496
+ {
497
+ checked: true,
498
+ }
499
+ ])
500
+
501
+ # Same as
502
+ # expect(page.loaded?).to eq(true)
503
+ # expect(page.checkboxes.size).to eq([{:checked=>false, :id=>"checkbox-not-checked"}, {:checked=>true}].size)
504
+ # expect(page.checkboxes[0].visible?).to eq(true)
505
+ # expect(page.checkboxes[0].checked?).to eq(false)
506
+ # expect(page.checkboxes[0].id).to match('checkbox-not-checked')
507
+ # expect(page.checkboxes[1].visible?).to eq(true)
508
+ # expect(page.checkboxes[1].checked?).to eq(true)
509
+ ```
510
+ ```ruby
511
+ expect(page).to be_like(checkboxes: [
512
+ false,
513
+ true
514
+ ])
515
+
516
+ # Same as
517
+ # expect(page.loaded?).to eq(true)
518
+ # expect(page.checkboxes.size).to eq([false, true].size)
519
+ # expect(page.checkboxes[0].visible?).to eq(true)
520
+ # expect(page.checkboxes[0].checked?).to eq(false)
521
+ # expect(page.checkboxes[1].visible?).to eq(true)
522
+ # expect(page.checkboxes[1].checked?).to eq(true)
523
+ ```
524
+ ```ruby
525
+ expect(page.checkboxes[0]).to be_like(
526
+ checked: false,
527
+ id: "checkbox-not-checked"
528
+ )
529
+
530
+ # Same as
531
+ # expect(page.checkboxes[0].visible?).to eq(true)
532
+ # expect(page.checkboxes[0].checked?).to eq(false)
533
+ # expect(page.checkboxes[0].id).to match('checkbox-not-checked')
534
+ ```
535
+
536
+ #### Select
537
+
538
+ ```ruby
539
+ expect(page).to be_like(selects: [
540
+ {
541
+ value: /^$/,
542
+ id: 'select-not-selected'
543
+ },
544
+ {
545
+ value: 'option2',
546
+ id: 'select-selected'
547
+ }
548
+ ])
549
+
550
+ # Same as
551
+ # expect(page.loaded?).to eq(true)
552
+ # expect(page.selects.size).to eq([{:value=>/^$/, :id=>"select-not-selected"}, {:value=>"option2", :id=>"select-selected"}].size)
553
+ # expect(page.selects[0].visible?).to eq(true)
554
+ # expect(page.selects[0].value).to match(/^$/)
555
+ # expect(page.selects[0].id).to match('select-not-selected')
556
+ # expect(page.selects[1].visible?).to eq(true)
557
+ # expect(page.selects[1].value).to match('option2')
558
+ # expect(page.selects[1].id).to match('select-selected')
559
+ ```
560
+ ### Visibility
561
+ Page Object Model:
562
+ ```ruby
563
+ class Visibility < SitePrism::Page
564
+ set_url '/visibility.html'
565
+
566
+ elements :list_items, 'li'
567
+ section :article, 'article' do
568
+ # ...
569
+ end
570
+ end
571
+ ```
572
+
573
+ #### Element or section
574
+
575
+ ```ruby
576
+ expect(page).to be_like(article: :invisible)
577
+
578
+ # Same as
579
+ # expect(page.loaded?).to eq(true)
580
+ # expect(page.article.invisible?).to eq(true)
581
+ ```
582
+
583
+ #### Elements or sections
584
+
585
+ ```ruby
586
+ expect(page).to be_like(list_items: [
587
+ 'Element 1',
588
+ :invisible,
589
+ :invisible,
590
+ :visible
591
+ ])
592
+
593
+ # Same as
594
+ # expect(page.loaded?).to eq(true)
595
+ # expect(page.list_items.size).to eq(["Element 1", :invisible, :invisible, :visible].size)
596
+ # expect(page.list_items[0].visible?).to eq(true)
597
+ # expect(page.list_items[0].text).to match('Element 1')
598
+ # expect(page.list_items[1].invisible?).to eq(true)
599
+ # expect(page.list_items[2].invisible?).to eq(true)
600
+ # expect(page.list_items[3].visible?).to eq(true)
601
+ ```
602
+ ### Absence
603
+ Page Object Model:
604
+ ```ruby
605
+ class Absence < SitePrism::Page
606
+ set_url '/absence.html'
607
+
608
+ element :article, 'article'
609
+ end
610
+ ```
611
+
612
+ #### Element or section
613
+
614
+ ```ruby
615
+ expect(page).to be_like(article: :absent)
616
+
617
+ # Same as
618
+ # expect(page.loaded?).to eq(true)
619
+ # expect(page.has_no_article?).to eq(true)
620
+ ```
621
+
622
+ #### Delay before checking absence
623
+
624
+ Sometimes we need to sleep before checking absence. Use :absent[delay in seconds]
625
+ ```ruby
626
+ expect(page).to be_like(article: :absent3)
627
+
628
+ # Same as
629
+ # expect(page.loaded?).to eq(true)
630
+ # sleep 3
631
+ # expect(page.has_no_article?).to eq(true)
632
+ ```
633
+ ### String comparison
634
+
635
+ #### Exact match and inclusion
636
+
637
+ By default the inclusion of a substring in a string is checked
638
+ ```ruby
639
+ PrismChecker.string_comparison = :inclusion # default value
640
+ expect(page.header).to be_like('Shopping Cart')
641
+
642
+ # Same as
643
+ # expect(page.header.visible?).to eq(true)
644
+ # expect(page.header.text).to match('Shopping Cart')
645
+ ```
646
+ To compare strings exactly, use :exact
647
+ ```ruby
648
+ PrismChecker.string_comparison = :exact
649
+ expect(page.header).to be_like('Shopping Cart')
650
+
651
+ # Same as
652
+ # expect(page.header.visible?).to eq(true)
653
+ # expect(page.header.text).to eq('Shopping Cart')
654
+ ```
655
+
656
+ #### Empty string
657
+
658
+ When the comparison method is :inclusion, and it is necessary to compare with an empty string, it can be done in this way
659
+ ```ruby
660
+ expect(page.element_without_text).to be_like(:empty)
661
+
662
+ # Same as
663
+ # expect(page.element_without_text.visible?).to eq(true)
664
+ # expect(page.element_without_text.text.empty?).to eq(true)
665
+ ```
666
+ or
667
+ ```ruby
668
+ expect(page.element_without_text).to be_like(/^$/)
669
+
670
+ # Same as
671
+ # expect(page.element_without_text.visible?).to eq(true)
672
+ # expect(page.element_without_text.text).to match(/^$/)
673
+ ```
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AbsenceExpectation
4
+ attr_reader :delay
5
+
6
+ def initialize(delay)
7
+ @delay = delay
8
+ end
9
+ end