howitzer 0.0.3 → 1.0.1

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.
Files changed (81) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +32 -0
  5. data/GETTING_STARTED.md +529 -0
  6. data/Gemfile +4 -2
  7. data/LICENSE +2 -2
  8. data/README.md +57 -13
  9. data/Rakefile +9 -2
  10. data/bin/howitzer +79 -31
  11. data/generators/base_generator.rb +87 -0
  12. data/generators/config/config_generator.rb +16 -20
  13. data/generators/config/templates/default.yml +26 -7
  14. data/generators/cucumber/cucumber_generator.rb +20 -26
  15. data/generators/{tasks → cucumber}/templates/cucumber.rake +0 -0
  16. data/generators/{config → cucumber}/templates/cucumber.yml +0 -0
  17. data/generators/emails/emails_generator.rb +11 -18
  18. data/generators/emails/templates/example_email.rb +1 -0
  19. data/generators/pages/pages_generator.rb +16 -18
  20. data/generators/pages/templates/example_menu.rb +1 -0
  21. data/generators/pages/templates/example_page.rb +1 -1
  22. data/generators/root/root_generator.rb +18 -20
  23. data/generators/root/templates/.gitignore +2 -1
  24. data/generators/root/templates/Gemfile +3 -2
  25. data/generators/root/templates/Rakefile +10 -0
  26. data/generators/root/templates/boot.rb +3 -9
  27. data/generators/rspec/rspec_generator.rb +23 -0
  28. data/generators/rspec/templates/example_spec.rb +7 -0
  29. data/generators/rspec/templates/rspec.rake +34 -0
  30. data/generators/rspec/templates/spec_helper.rb +56 -0
  31. data/generators/tasks/tasks_generator.rb +11 -17
  32. data/generators/tasks/templates/common.rake +15 -0
  33. data/howitzer.gemspec +13 -2
  34. data/lib/howitzer.rb +1 -0
  35. data/lib/howitzer/helpers.rb +87 -2
  36. data/lib/howitzer/init.rb +0 -1
  37. data/lib/howitzer/patches/rawler_patched.rb +86 -0
  38. data/lib/howitzer/settings.rb +27 -0
  39. data/lib/howitzer/utils.rb +3 -12
  40. data/lib/howitzer/utils/capybara_patched.rb +3 -2
  41. data/lib/howitzer/utils/capybara_settings.rb +158 -24
  42. data/lib/howitzer/utils/data_generator/data_storage.rb +35 -1
  43. data/lib/howitzer/utils/data_generator/gen.rb +45 -3
  44. data/lib/howitzer/utils/email/email.rb +44 -5
  45. data/lib/howitzer/utils/email/mail_client.rb +28 -22
  46. data/lib/howitzer/utils/email/mailgun_helper.rb +30 -4
  47. data/lib/howitzer/utils/locator_store.rb +111 -19
  48. data/lib/howitzer/utils/log.rb +137 -0
  49. data/lib/howitzer/utils/page_validator.rb +86 -0
  50. data/lib/howitzer/vendor/firebug-1.12.1-fx.xpi +0 -0
  51. data/lib/howitzer/vendor/firepath-0.9.7-fx.xpi +0 -0
  52. data/lib/howitzer/version.rb +2 -2
  53. data/lib/howitzer/web_page.rb +159 -19
  54. data/spec/active_resource.rb +0 -0
  55. data/spec/config/custom.yml +1 -0
  56. data/spec/config/default.yml +28 -0
  57. data/spec/spec_helper.rb +46 -1
  58. data/spec/support/boot_helper.rb +15 -0
  59. data/spec/support/generator_helper.rb +13 -0
  60. data/spec/support/logger_helper.rb +12 -0
  61. data/spec/unit/bin/howitzer_spec.rb +175 -0
  62. data/spec/unit/generators/generators_spec.rb +175 -0
  63. data/spec/unit/lib/capybara_settings_spec.rb +170 -0
  64. data/spec/unit/lib/helpers_spec.rb +619 -0
  65. data/spec/unit/lib/init_spec.rb +14 -0
  66. data/spec/unit/lib/settings_spec.rb +17 -0
  67. data/spec/unit/lib/utils/data_generator/data_storage_spec.rb +62 -0
  68. data/spec/unit/lib/utils/data_generator/gen_spec.rb +151 -0
  69. data/spec/unit/lib/utils/email/email_spec.rb +75 -0
  70. data/spec/unit/lib/utils/email/mail_client_spec.rb +115 -0
  71. data/spec/unit/lib/utils/email/mailgun_helper_spec.rb +95 -0
  72. data/spec/unit/lib/utils/locator_store_spec.rb +122 -0
  73. data/spec/unit/lib/utils/log_spec.rb +107 -0
  74. data/spec/unit/lib/utils/page_validator_spec.rb +142 -0
  75. data/spec/unit/lib/web_page_spec.rb +250 -0
  76. data/spec/unit/version_spec.rb +8 -0
  77. metadata +215 -15
  78. data/Gemfile.lock +0 -103
  79. data/History.md +0 -20
  80. data/lib/howitzer/utils/logger.rb +0 -108
  81. data/spec/howitzer/version_spec.rb +0 -8
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ coverage
2
+ .idea
3
+ .rvmrc
4
+ *.gem
5
+ vendor/bundle/*
6
+ spec/log/*
7
+ Gemfile.lock
8
+ doc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require fuubar
3
+ --format Fuubar
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
data/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ ## In git
2
+
3
+ ### New Features
4
+
5
+ ### Bugfixes
6
+
7
+ ## [v1.0.1](https://github.com/romikoops/howitzer/compare/v1.0...v1.0.1)
8
+
9
+ ### Bugfixes
10
+ - Fixed unit tests
11
+ - Fixed correct Ruby version supporting
12
+
13
+ ## [v1.0](https://github.com/romikoops/howitzer/compare/v0.0.3...v1.0)
14
+
15
+ It is major release, so there are many new features, refactoring, unit tests, code documentation.
16
+
17
+ **Caution**: It is not going to support old versions anymore.
18
+
19
+
20
+ ## [v0.0.3](https://github.com/romikoops/howitzer/compare/v0.0.1...v0.0.3)
21
+
22
+ ### New Features
23
+
24
+ * Added supporting poltergeist driver
25
+
26
+ ### Bugfixes
27
+
28
+ * Fixed problem with dependencies
29
+
30
+ ## [v0.0.1](https://github.com/romikoops/howitzer/tree/v0.0.1)
31
+
32
+ Initial version
@@ -0,0 +1,529 @@
1
+ Getting Started
2
+ ===============
3
+
4
+ ## Jump to Section
5
+ * [Pages](#pages)
6
+ * [Validations](#validations)
7
+ * [Locators](#locators)
8
+ * [Pages With Static Information](#pages-with-static-information)
9
+ * [Redefining of the pen method](#redefining-of-the-open-method)
10
+ * [Good Practices](#good-practices)
11
+ * [Emails](#emails)
12
+ * [Logging](#logging)
13
+ * [BUILT-IN Logging](#built-in-logging)
14
+ * [Extended Logging](#extended-logging)
15
+ * [Data Generators](#data-generators)
16
+ * [Data Storage](#data-storage)
17
+ * [Generator](#generator)
18
+ * [Cucumber Tranformers](#cucumber-transformers)
19
+ * [RSpec Folder Structure](#rspec-folder-structure)
20
+
21
+ Pages
22
+ ------
23
+ [[Back To Top]](#jump-to-section)
24
+
25
+ Pages - are classes that’s describe real web pages. For example, 'Home page' can be described as:
26
+
27
+ ```ruby
28
+ class HomePage < WebPage
29
+ end
30
+ ```
31
+
32
+ Thus, we realize that each page is inherited from a parent class 'Web Page', which contains the common methods for all pages.
33
+
34
+ Each page contains required constant URL(the relative URL of the page):
35
+
36
+ **Example :**
37
+
38
+ ```ruby
39
+ class HomePage < WebPage
40
+ URL = '/'
41
+ end
42
+ ```
43
+
44
+ ### Validations
45
+ [[Back To Top]](#jump-to-section)
46
+
47
+ Pape Object pattern does not expect using any validations on UI driver level. But at the same time, each page must have
48
+ some anchor in order to identify page exclusively.
49
+
50
+ ```ruby
51
+ validates <type>, options
52
+ ```
53
+
54
+ Howitzer providers 3 different validation types:
55
+
56
+
57
+ Validation Type | Options | Value Type | Description
58
+ :-----------------:|:-------:|:-------------:|:-----------------------------------------:
59
+ : url | pattern | Regexp | matches current url to pattern
60
+ : title | pattern | Regexp | matches current pate title to pattern
61
+ : element_presence | locator | String/Symbol | find element by locator on current page
62
+
63
+ **Example 1:**
64
+
65
+ ```ruby
66
+ class HomePage < WebPage
67
+ URL = '/'
68
+ validates :url, pattern: /#{Regexp.escape(settings.app_host)}\/?\z/
69
+ end
70
+ ```
71
+
72
+ **Example 2:**
73
+
74
+ ```ruby
75
+ class LoginPage < WebPage
76
+ URL = '/users/sign_in'
77
+ validates :title, pattern: /Sign In\z/
78
+ end
79
+ ```
80
+
81
+ **Example 3:**
82
+
83
+ ```ruby
84
+ class LoginPage < WebPage
85
+ URL = '/users/sign_in'
86
+
87
+ validates :element_presence, locator: :sign_in_btn
88
+
89
+ add_locator :sign_in_btn, '#sign_in'
90
+ end
91
+ ```
92
+
93
+ Howitzer allows use all 3 validations, but only 1 is really required. If any validation is failed, exception will be raised.
94
+
95
+ **CAUTION:** Page validation is triggered in 2 cases only:
96
+
97
+ 1. < Web Page Class >.open(url)
98
+ 2. < Web Page Class >.given
99
+
100
+
101
+ ### Locators ###
102
+ [[Back To Top]](#jump-to-section)
103
+
104
+ Locator is a search item (selector) of one or more elements on a 'Web page'.
105
+
106
+ The table below lists the types of locators, the possible methods of searching and Capybara methods, which may be called.
107
+
108
+
109
+ Locator Type | Search Methods | Capybara Methods
110
+ :----------------:|:-----------------------:|:----------------------------:
111
+ : locator | css(by default), path | find, all, first
112
+ : link_locator | id, text | click_link, find_link
113
+ : field_locator | id, name, text | find_field, fill_in
114
+ : button_locator | id, name, text | click_button, find_button
115
+
116
+ Each page contains a description of all elements by adding the appropriate locators that are preceded by the prefix **add_**
117
+
118
+ **Example:**
119
+ ```ruby
120
+ class HomePage < WebPage
121
+ URL = '/'
122
+ validates :url, pattern: /#{Regexp.escape(settings.app_host)}\/?\z/
123
+
124
+ add_locator :test_locator_name1, '.foo' #css locator, default
125
+ add_locator :test_locator_name2, css: '.foo' #css locator
126
+ add_locator :test_locator_name3, xpath: '//div[@value="bar"]' #css locator
127
+
128
+ add_link_locator :test_link_locator1, 'Foo' #link locator by 'Foo' text
129
+ add_link_locator :test_link_locator1, 'bar' #link locator by 'bar' id
130
+
131
+ add_field_locator :test_field_locator1, 'Foo' #field locator by 'Foo' text
132
+ add_field_locator :test_field_locator2, 'bar' #field locator by 'bar' id
133
+ add_field_locator :test_field_locator3, 'bas' #field locator by 'baz' name
134
+ end
135
+ ```
136
+
137
+ ### Pages with static information ###
138
+ [[Back To Top]](#jump-to-section)
139
+
140
+ In case of repeated static information in several different pages, it would be good decision to move up these methods into separate module.
141
+
142
+ **Example:**
143
+ ```ruby
144
+ module TopMenu
145
+ def self.included(base)
146
+ base.class_eval do
147
+ add_link_locator :test_link_locator1, 'Foo'
148
+ end
149
+ end
150
+
151
+ def open_menu
152
+ log.info "Open menu"
153
+ click_link locator(:test_link_locator1)
154
+ end
155
+ end
156
+ ```
157
+ #### Redefining of the *open* method #####
158
+
159
+ It is used when you need to open a page with additional parameters.
160
+
161
+ **Example:**
162
+ ```ruby
163
+ class MyPage < WebPage
164
+ def self.open(url="#{app_url}#{self::URL}+'?no_popup=true'")
165
+ super
166
+ end
167
+ end
168
+ ```
169
+
170
+ ### Good practices ###
171
+ [[Back To Top]](#jump-to-section)
172
+
173
+
174
+ **First rule:** do not get tied to the interface. Thats means that the name and description of the methods you should use a common phrases.
175
+
176
+ **Example:**
177
+ ```ruby
178
+ class MyPage < WebPage
179
+ def submit_form
180
+
181
+ end
182
+
183
+ def fill_form(value)
184
+
185
+ end
186
+ end
187
+ ```
188
+ **Second rule:** any ACTION methods should return an instance of the page.
189
+ This allows you to do the following:
190
+
191
+ ```ruby
192
+ MyPage.open.fill_form.submit_form
193
+ ```
194
+ **Example:**
195
+ ```
196
+ class MyPage < WebPage
197
+ def fill_form
198
+ ..............
199
+ MyPage.given
200
+ end
201
+ end
202
+ ```
203
+
204
+ **Third rule:** coding of checks in the methods in the class pages are __prohibited.__
205
+
206
+ **Example:**
207
+ ```ruby
208
+ class MyPage < WebPage
209
+ def submit_form
210
+ ….
211
+ end
212
+
213
+ def get_all_prices
214
+
215
+ prices
216
+ end
217
+ end
218
+ ```
219
+ my_page_spec.rb
220
+ ```ruby
221
+ require 'spec_helper'
222
+
223
+ describe “some feature” do
224
+ context “when...” do
225
+ it {expect(MyPage.get_all_prices).to include(400)}
226
+ end
227
+ end
228
+ ```
229
+ **Fourth rule:** all ACTION methods should create log entries
230
+
231
+ **Example:**
232
+ ```ruby
233
+ class MyPage < WebPage
234
+ def submit_form
235
+ log.info { "[ACTION] Submit form" }
236
+ ….
237
+ end
238
+
239
+ def fill_form
240
+ log.info { "[ACTION] Fill form" }
241
+
242
+ end
243
+ end
244
+ ```
245
+
246
+ Emails
247
+ ------
248
+ [[Back To Top]](#jump-to-section)
249
+
250
+ _**Email**_ class uses `Mailgun` gem and allows you to work with the mailbox.
251
+ Class corresponds to one letter. Used to test the notifications.
252
+
253
+ **.find_by_recipient (recipient)** - search for the letter recipient. The parameter receives email recipient.
254
+
255
+ **.find (recipient, subject)** - same as the **self.find_by_recipient (recipient)**, but only in case, when we do not know in advance what kind of _subject_ has email.
256
+
257
+ **\#plain_text_body** - receiving text of messages
258
+
259
+ **\#get_mime_part** - allows you to receive the attachment of email
260
+
261
+ **Example:**
262
+ ```ruby
263
+ class MyEmail < Email
264
+ SUBJECT = 'TEST SUBJECT' # specify the subject of an email
265
+ end
266
+ ```
267
+
268
+ Example, how custom class might look like:
269
+ ```ruby
270
+ class MyEmail <Email
271
+ SUBJECT = "Test email" # specify the subject of an email
272
+
273
+ def addressed_to? (new_user) # check that the letter were sent to proper recipient
274
+ / Hi # {new_user} / === plain_text_body
275
+ end
276
+ end
277
+ ```
278
+
279
+ Logging
280
+ -------
281
+ [[Back To Top]](#jump-to-section)
282
+
283
+ *Howitzer* allows logging to the text file, HTML and output to the console.
284
+
285
+ ### BUILT-IN logging ###
286
+
287
+ *Howitzer* uses the opportunity of Cucumber and RSpec generate HTML, JUnit logging. HTML provide ability to view the log in HTML, JUnit - use the logs in CI, accordingly.
288
+
289
+
290
+ Running of an built-in HTML generators for RSpec and Cucumber logging, is available if you run the tests using a `rake` tasks.
291
+
292
+ **Example:**
293
+
294
+ Running **_RSpec_** tests through `rake` tasks.
295
+ ```bash
296
+ rake rspec: all
297
+ ```
298
+
299
+ **Example:**
300
+
301
+ Running **_Cucumber_** tests through `rake` tasks.
302
+ ```bash
303
+ rake cucumber: all
304
+ ```
305
+
306
+ Manually running of the tests with automatic logging is also possible.
307
+
308
+ **Example:**
309
+
310
+ Manual start of some specific RSpec tests:
311
+ ```bash
312
+ rspec spec / my_spec.rb - format html-out =. / log / log.html
313
+ ```
314
+
315
+ Running RSpec tests manually:
316
+ ```bash
317
+ rspec - format html-out =. / log / log.html
318
+ ```
319
+
320
+ Manual start of certain _feature_:
321
+ ```bash
322
+ cucumber features / first.feature - format html-out =. / log / log.html
323
+ ```
324
+ Manual start all _features_:
325
+ ```bash
326
+ cucumber - format html - out =. / log / log.html
327
+ ```
328
+
329
+ ### Extended logging ###
330
+ [[Back To Top]](#jump-to-section)
331
+
332
+ Extended logging to a text file and to the console also available.
333
+ It uses the _log manager_ provided by **_log_** method.
334
+
335
+ _Howitzer_ has 4 levels of logging: _**FATAL, WARN, INFO, DEBUG.**_
336
+
337
+ FATAL <WARN <INFO <DEBUG
338
+
339
+ **Example:**
340
+ ```bash
341
+ log.info "info message"
342
+ ```
343
+
344
+ To create a record with a different level, use the appropriate method.
345
+
346
+ **Example:**
347
+ ```bash
348
+ log.warn "warning message"
349
+ log.fatal "fatal message"
350
+ ```
351
+
352
+ If the option `settings.debug_mode` = true, logger will record messages with **DEBUG** status.
353
+
354
+ Logs are generated in the **log** _directory_ .
355
+ ```bash
356
+ / log
357
+ log.txt
358
+ log.html
359
+ TEST-(your-feature-name). Xml
360
+ ```
361
+ Examples of using logs in **Pages** and **Email**.
362
+
363
+ **Example:** with **Page.**
364
+
365
+ ```ruby
366
+ class MyPage < WebPage
367
+ def submit_form
368
+ log.info "[ACTION] Submit form"
369
+
370
+ end
371
+
372
+ def fill_form
373
+ log.info "[ACTION] Fill form"
374
+
375
+ end
376
+ end
377
+ ```
378
+
379
+ **Example:** with **Email.**
380
+ ```ruby
381
+ class TestEmail < Email
382
+ SUBJECT = "Test email"
383
+
384
+ def addressed_to?(new_user)
385
+ if /Hi #{new_user}/ === plain_text_body
386
+ log.info "some message"
387
+ else
388
+ log.warn "some mesage"
389
+ end
390
+ end
391
+ end
392
+ ```
393
+
394
+ ## Data Generators ##
395
+ [[Back To Top]](#jump-to-section)
396
+
397
+ Data generator allows to generate some data structures like User and store it to own Memory storage
398
+
399
+ ### Data Storage ###
400
+
401
+ Data Storage is simple key value storage, which uses namespaces (for example, :user, :sauce, etc).
402
+
403
+ This module has next methods:
404
+
405
+
406
+ Method | Description
407
+ :------------------------------------:|:--------------------------------------------------:
408
+ | DataStorage.store(ns,key,value) | Adds data to storage, where ns - uniq namespace name
409
+ | DataStorage::extract(ns, key=nil) | Gets data from storage by namespace and key. If key is not specified, then it will returns all data from namespace
410
+ | DataStorage::clear_ns(ns) | Removes namespace with data
411
+
412
+ **Example:**
413
+ ```ruby
414
+ DataStorage.store(:user, 1, User.new('Peter'))
415
+ DataStorage.store(:user, 2, User.new('Dan'))
416
+ DataStorage.store(:post, "post1", Post.new("Amazing post"))
417
+ ```
418
+
419
+ In memory it looks like:
420
+
421
+ ```ruby
422
+ {
423
+ user: {
424
+ 1 => User.new('Peter'),
425
+ 2 => User.new('Dan')
426
+ },
427
+ post: {
428
+ "post1" => Post.new("Amazing post")
429
+ }
430
+ }
431
+ ```
432
+
433
+ ### Generator ####
434
+ [[Back To Top]](#jump-to-section)
435
+
436
+ This module has standard methods for generate test data. It has one standard data object for generate, because this is
437
+ more common for almost all tests:
438
+
439
+ _DataGenerator::Gen::User._
440
+
441
+ _DataGenerator::Gen::User_ has the params:
442
+
443
+ :login, :domain, :email, :password, :mailbox, :first_name, :last_name, :full_name
444
+
445
+ To generate this object use _Gen::user(params={})_ method.
446
+
447
+ Also you can reopen _Gen_ module to add your own objects to generate, also use this module to generate some other data
448
+ specific for your tests.
449
+ When using Cucumber create Gen.rb file in **/features/support** directory. When using Rspec create
450
+ _Gen.rb_ file in **/spec/support** directory.
451
+
452
+ ### Cucumber Transformers ###
453
+
454
+ In **/features/support/tranformers.rb** file are described Cucumber transformers (to see more info visit this one:
455
+ [https://github.com/cucumber/cucumber/wiki/Step-Argument-Transforms](https://github.com/cucumber/cucumber/wiki/Step-Argument-Transforms)).
456
+ We are using transformers to use generated data objects in tests. For example let’s imagine that we need to
457
+ write _sign_up.feature:_
458
+
459
+ ```ruby
460
+ Feature: Sign Up
461
+
462
+ In order to use all functionality of the system
463
+ As unregistered user
464
+ I want to register to the system
465
+
466
+ Scenario: correct credentials
467
+ Given Register page
468
+ And new UNIQ_USER user # it’s generate User object with generated test data that are transformed in hash in _transformers.rb_ file.
469
+ When I put next register data and apply it
470
+
471
+ |username |email |password |
472
+ |UNIQ_USER[:username]|UNIQ_USER[:email] | UNIQ_USER[:password]|
473
+ ```
474
+ Last line will automatically replace UNIQ_USER[:username] for generated data, which you can use.
475
+
476
+ You can wright your own transformers for some other generated objects, that you will generate
477
+ in _DataGenerator::Gen_ module.
478
+
479
+
480
+ ## RSpec Folder Structure ##
481
+ [[Back To Top]](#jump-to-section)
482
+
483
+ **/spec** folder contains all supporting .rspec code and tests.
484
+ There is **spec_helper.rb** file where all .rspec settings are. You could edit this .rspec settings for your purposes.
485
+
486
+ **/spec/support** contains helpers code, for example code that generates test data.
487
+ It’s better to you modules here in every created files. Methods from this folder will be accessible in every **_spec.rb** file
488
+ and every **_page.rb** file.
489
+
490
+ All **_spec.rb** files should contains in folder that has tests priority meaning in it’s name.
491
+ You should create folders in **/spec** to add there tests with needed priority level and edit constant **TEST_TYPES**
492
+ in **/tasks/rspec.rake** file to add a name of create folder as symbol in list.
493
+
494
+ To run tests by priority level user **Rake** tasks in **/tasks/rspec.rake** file. Constant
495
+ **TEST_TYPES = [:all, :health, :bvt, :p1]** has a list of available tests priorities as a standard settings.
496
+ To run all tests in **/spec** folder use this:
497
+
498
+ ```bash
499
+ rake rspec:all
500
+ ```
501
+ (_:all_ will run all tests in **/spec** folder). For example, to run _:bvt_ tests you need to create
502
+ **/spec/bvt** folder and add some **_spec.rb** files there, than run Rake task by:
503
+
504
+ ```bash
505
+ rake rspec:bvt
506
+ ```
507
+ For running tests with less priority level use _:p1_:
508
+
509
+ ```bash
510
+ rake rspec:p1
511
+ ```
512
+
513
+ Also there is a standard option to run _Smoke_ tests:
514
+
515
+ ```bash
516
+ rake rspec:health
517
+ ```
518
+ In every directory that is in **/spec** folder, the name of is represents priority of tests that are in it,
519
+ you can create subfolders that represents the business areas of tests. In **/tasks/rspec.rake** there is a constant:
520
+
521
+ **TEST_AREAS = []**
522
+
523
+ You can add here business areas of created tests that are in subfolders, names should be equal, for example:
524
+ If *TEST_AREAS = [:accounts]* and there is a folder with specs in it: **/spec/bvt/accounts.**
525
+ You can run all tests from this folder by command:
526
+
527
+ ```bash
528
+ rake rspec:bvt:accounts
529
+ ```