site_prism.vcr 0.0.1 → 0.1.0
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 +5 -13
- data/.travis.yml +1 -0
- data/CHANGELOG.md +78 -0
- data/Gemfile +2 -0
- data/README.md +61 -24
- data/TODO.md +28 -40
- data/lib/site_prism_vcr/applier.rb +20 -6
- data/lib/site_prism_vcr/dsl/adjuster.rb +40 -19
- data/lib/site_prism_vcr/dsl/initial_adjuster.rb +1 -1
- data/lib/site_prism_vcr/element.rb +8 -5
- data/lib/site_prism_vcr/fixture.rb +0 -1
- data/lib/site_prism_vcr/options.rb +12 -1
- data/lib/site_prism_vcr/patches/element_container.rb +4 -0
- data/lib/site_prism_vcr/patches/page.rb +25 -27
- data/lib/site_prism_vcr/version.rb +1 -1
- data/site_prism.vcr.gemspec +2 -2
- data/spec/integration/elements/apply_spec.rb +100 -0
- data/spec/integration/elements/events/click_spec.rb +20 -0
- data/spec/integration/{immediate_http_interactions/page_load_on_click_spec.rb → pages/custom_event_spec.rb} +5 -3
- data/spec/integration/{immediate_http_interactions/page_load_spec.rb → pages/load_spec.rb} +13 -9
- data/spec/spec_helper.rb +3 -0
- data/spec/support/shared/integration/custom_fixtures.rb +17 -0
- data/spec/support/shared/integration/exchange.rb +1 -1
- data/spec/support/shared/integration/home_path.rb +1 -1
- data/spec/support/shared/integration/waiter.rb +37 -25
- data/spec/support/site_prism/pages/home.rb +7 -0
- data/spec/support/site_prism/pages/{immediate_http_interactions → page_load}/home_path.rb +1 -1
- data/spec/support/site_prism/pages/{immediate_http_interactions → page_load}/one_request.rb +1 -1
- data/spec/support/site_prism/pages/{immediate_http_interactions → page_load}/subpage.rb +1 -1
- data/spec/support/site_prism/pages/{immediate_http_interactions → page_load}/two_requests.rb +1 -1
- data/spec/support/site_prism/pages/{immediate_http_interactions → page_load}/waiter_without_fixtures_ejection.rb +1 -1
- data/spec/unit/applier_spec.rb +74 -56
- data/spec/unit/dsl/adjuster_spec.rb +58 -47
- data/spec/unit/dsl/initial_adjuster_spec.rb +18 -12
- data/spec/unit/element_spec.rb +11 -13
- data/spec/unit/fixtures/handler_spec.rb +7 -2
- data/spec/unit/fixtures/manager_spec.rb +20 -4
- data/spec/unit/fixtures/modifiers/home_path_spec.rb +14 -3
- data/spec/unit/fixtures/modifiers/path_spec.rb +9 -3
- data/spec/unit/fixtures/tmp_keeper_spec.rb +1 -1
- data/spec/unit/fixtures_spec.rb +5 -5
- data/spec/unit/options_spec.rb +35 -1
- data/spec/unit/patches/element_container_spec.rb +25 -12
- data/spec/unit/patches/page_spec.rb +23 -30
- data/spec/unit/waiter_spec.rb +16 -4
- metadata +30 -30
- data/spec/integration/http_interactions_on_even/click_spec.rb +0 -75
- data/spec/unit/element_container_spec.rb +0 -48
    
        checksums.yaml
    CHANGED
    
    | @@ -1,15 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
             | 
| 5 | 
            -
              data.tar.gz: !binary |-
         | 
| 6 | 
            -
                YTU3ZWMxMGVkZWIyODA2MmQzZTcxZjZkMmZlNGQzMGI4MWVlNzhiZQ==
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: bea07665857e88334694b2c69c3d0ded874626cf
         | 
| 4 | 
            +
              data.tar.gz: 7320da925829386acea9991b1572e0f93a9d0dd4
         | 
| 7 5 | 
             
            SHA512:
         | 
| 8 | 
            -
              metadata.gz:  | 
| 9 | 
            -
             | 
| 10 | 
            -
                NTI2MDIyOGNkMjgyZjg1ZDJhODM2ZGMxNjA5M2RjMjc0NjVmNzQwOWNiY2Y0
         | 
| 11 | 
            -
                ZTI4NTA5OThkY2JmOTFhYzliM2IwOTRmYjAxNjJlODA1YjI3NWQ=
         | 
| 12 | 
            -
              data.tar.gz: !binary |-
         | 
| 13 | 
            -
                YjE4MTFlYjE2MmIwOGM5YzJmZGQxMTg5M2RlOTI2ZjQyYjZjYjAyMWNiMDYz
         | 
| 14 | 
            -
                OTlhM2ZhMDgwYzBkYzQ2NzQ3ZDY3YTA5YWI0YzkxOWQ0Njc3ZDU5OTljZDhm
         | 
| 15 | 
            -
                Mjk3MmNlMmY3Y2Q3ZmIyZWMxMTA5NTIxMWNlMWJkMjE4MzY2ZmQ=
         | 
| 6 | 
            +
              metadata.gz: a7829ce24f5eab5d1a203712c9d38a362b0607af3f1cfd4c1d0c0b12d386f2c9b829ed1e06589940a9a471f7089094f15bf30fee9d8b19d4813d2fe10eb45a8e
         | 
| 7 | 
            +
              data.tar.gz: 9ad8f2da29c6039106b5a7d03333c88b21cc87950926ab15806df271b1e044e8c6f03bfaf2afd9d042af250d218cf4100465692766f2380663a9450211e66d6d
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    ADDED
    
    | @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            # Version 0.1.0
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Changed
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              * dependencies. Now gem depends on Vcr 2.8.0 and SitePrism 2.5.
         | 
| 6 | 
            +
              * re-factored the way how Vcr cassettes could be applying for any event of a page.
         | 
| 7 | 
            +
                Before that change we had to use ugly way
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              ```ruby
         | 
| 10 | 
            +
                @cars.apply_vcr(-> { page.find('#cars').click }) do
         | 
| 11 | 
            +
                  fixtures ['cars']
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              ```
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              now we use chainable way for this purpose
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              ```ruby
         | 
| 18 | 
            +
                @cars = CarsPage.new
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                @cars.shift_event {
         | 
| 21 | 
            +
                  page.find('#cars').click
         | 
| 22 | 
            +
                }.apply_vcr do
         | 
| 23 | 
            +
                  fixtures ['cars']
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              ```
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## Fixed
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              * the issue with defining an action to be done over cassettes in the adjusting block. Now even if an action is defined before a list of cassettes, the adjusting block will be performed properly
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              ```ruby
         | 
| 32 | 
            +
                @products_page.cars_dropdown.click_and_apply_vcr do
         | 
| 33 | 
            +
                  replace
         | 
| 34 | 
            +
                  fixtures ['cars/ford/prices']
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              ```
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            ## Added
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              * possibility to apply Vcr cassettes for any event of an element. [Roman Rott and Dmitriy Nesteryuk]
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              ```ruby
         | 
| 43 | 
            +
                @products_page.cars_dropdown.shift_event{
         | 
| 44 | 
            +
                  set 'Ford'
         | 
| 45 | 
            +
                }.apply_vcr do
         | 
| 46 | 
            +
                  fixtures ['cars/ford/prices']
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              ```
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              * possibility to link Vcr with already defined elements, it will be helpful in case they are inherited
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              ```ruby
         | 
| 53 | 
            +
                class CarsPage < TransportPage
         | 
| 54 | 
            +
                  link_vcr_with_element :transport_details_link do
         | 
| 55 | 
            +
                    fixtures ['cars/ford']
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                @page = CarsPage.new
         | 
| 60 | 
            +
                @page.transport_details_link.click_and_apply_vcr
         | 
| 61 | 
            +
              ```
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              * possibility to redefine default options for a default waiter
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              ```ruby
         | 
| 66 | 
            +
                class ProductsPage < SitePrism::Page
         | 
| 67 | 
            +
                  link_vcr_with_element :details_link do
         | 
| 68 | 
            +
                    fixtures ['cars/ford']
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    waiter(eject_cassettes: false) { self.wait_until_loading_indicator_invisible } # default waiter with options
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                @page = ProductsPage.new
         | 
| 75 | 
            +
                @page.details_link.click_and_apply_vcr do
         | 
| 76 | 
            +
                  waiter_options(eject_cassettes: true) # redefines default options
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              ```
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,21 +1,21 @@ | |
| 1 1 | 
             
            # SitePrism.Vcr
         | 
| 2 2 |  | 
| 3 3 | 
             
            [](https://codeclimate.com/github/nestd/site_prism.vcr)
         | 
| 4 | 
            -
            [](https://travis-ci.org/dnesteryuk/site_prism.vcr)
         | 
| 5 | 
            +
            [](https://coveralls.io/r/dnesteryuk/site_prism.vcr)
         | 
| 6 | 
            +
            [](https://gemnasium.com/dnesteryuk/site_prism.vcr)
         | 
| 7 7 |  | 
| 8 8 | 
             
            The purpose of this gem is to give an easy way for integrating [SitePrism](https://github.com/natritmeyer/site_prism) (it is Page Object Model DSL for Capybara) and [VCR](https://github.com/vcr/vcr) (it is a powerful tool for recording and stubbing HTTP interactions).
         | 
| 9 9 |  | 
| 10 | 
            -
            Such integration allows you to write acceptance tests more easily since you receive handy tool for managing VCR cassettes. Those cassettes can be easily linked with SitePrism elements (in fact, Capybara elements since SitePrism doesn't have own elements). Afterwards those linked cassettes can be used for stubbing external API responses while  | 
| 10 | 
            +
            Such integration allows you to write acceptance tests more easily since you receive handy tool for managing VCR cassettes. Those cassettes can be easily linked with SitePrism elements (in fact, Capybara elements since SitePrism doesn't have own elements). Afterwards those linked cassettes can be used for stubbing external API responses while doing actions (click, change etc) over an element that cassettes are defined for.
         | 
| 11 11 |  | 
| 12 12 | 
             
            ## Features
         | 
| 13 13 |  | 
| 14 14 | 
             
              * Links VCR cassettes with SitePrism elements.
         | 
| 15 15 | 
             
              * Links VCR cassettes with SitePrism pages.
         | 
| 16 | 
            -
              * Applies VCR cassettes  | 
| 17 | 
            -
              * Applies VCR cassettes  | 
| 18 | 
            -
              * Defines a waiter which will be used for waiting until an expected element is on a page or until an expected element has disappeared from a page (It is very helpful when a few external API requests are being executed after  | 
| 16 | 
            +
              * Applies VCR cassettes on any event (click, change, blur etc).
         | 
| 17 | 
            +
              * Applies VCR cassettes on page loading.
         | 
| 18 | 
            +
              * Defines a waiter which will be used for waiting until an expected element is on a page or until an expected element has disappeared from a page (It is very helpful when a few external API requests are being executed after raising an event).
         | 
| 19 19 | 
             
              * Allows to redefine default VCR cassettes (cassettes which were specified while describing a SitePrism element or a SitePrism page).
         | 
| 20 20 | 
             
              * Allows to redefine a default waiter (a waiter which was specified while describing a SitePrism element or a SitePrism page).
         | 
| 21 21 |  | 
| @@ -51,6 +51,20 @@ end | |
| 51 51 |  | 
| 52 52 | 
             
            `fixtures` helper method is used for defining VCR cassettes. All cassettes are taken from a path which you have defined in `cassette_library_dir` configuration option of VCR. Please, refer to [documentation](https://relishapp.com/vcr/vcr/v/2-5-0/docs/configuration/cassette-library-dir) of VCR to get more info about configuration options.
         | 
| 53 53 |  | 
| 54 | 
            +
            You can specify cassettes for already defined elements, for example, your page inherits another one:
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            ```ruby
         | 
| 57 | 
            +
            class TransportPage < SitePrism::Page
         | 
| 58 | 
            +
              element :transport_details_link, '#car_details'
         | 
| 59 | 
            +
            end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            class CarsPage < TransportPage
         | 
| 62 | 
            +
              link_vcr_with_element :transport_details_link do
         | 
| 63 | 
            +
                fixtures ['cars/ford']
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| 66 | 
            +
            ```
         | 
| 67 | 
            +
             | 
| 54 68 | 
             
            #### Path helper method
         | 
| 55 69 |  | 
| 56 70 | 
             
            In case you have a lot of cassettes which are stored in some subdirectory, there is more better way for defining cassettes:
         | 
| @@ -66,7 +80,8 @@ class ProductsPage < SitePrism::Page | |
| 66 80 | 
             
            end
         | 
| 67 81 | 
             
            ```
         | 
| 68 82 |  | 
| 69 | 
            -
            The `path` helper method can be used a few times in a block to define cassettes. | 
| 83 | 
            +
            The `path` helper method can be used a few times in a block to define cassettes.
         | 
| 84 | 
            +
            The code above is identical to:
         | 
| 70 85 |  | 
| 71 86 | 
             
            ```ruby
         | 
| 72 87 | 
             
            class ProductsPage < SitePrism::Page
         | 
| @@ -100,7 +115,7 @@ class ProductsPage < SitePrism::Page | |
| 100 115 | 
             
            end
         | 
| 101 116 | 
             
            ```
         | 
| 102 117 |  | 
| 103 | 
            -
            If some  | 
| 118 | 
            +
            If some cassette name begins with `~/`, it means that a defined home path will be applied to find such cassette. The previous example is identical to this one:
         | 
| 104 119 |  | 
| 105 120 | 
             
            ```ruby
         | 
| 106 121 | 
             
            class ProductsPage < SitePrism::Page
         | 
| @@ -134,7 +149,7 @@ end | |
| 134 149 |  | 
| 135 150 | 
             
            ### Applying VCR cassettes on click
         | 
| 136 151 |  | 
| 137 | 
            -
             | 
| 152 | 
            +
            Cassettes can be applied on a click event:
         | 
| 138 153 |  | 
| 139 154 | 
             
            ```ruby
         | 
| 140 155 | 
             
            @products_page.car_details_link.click_and_apply_vcr
         | 
| @@ -229,7 +244,7 @@ end | |
| 229 244 |  | 
| 230 245 | 
             
            ### Waiters
         | 
| 231 246 |  | 
| 232 | 
            -
            Waiters are very important part of this gem (actually, waiters are part of SitePrism gem, but they are used widely here). When we do some action and that action causes a few HTTP interactions we have to wait for a result of them | 
| 247 | 
            +
            Waiters are very important part of this gem (actually, waiters are part of SitePrism gem, but they are used widely here). When we do some action and that action causes a few HTTP interactions we have to wait for a result of them before expecting something on a page. The good approach is to wait for some visibility or invisibility of an element. For example, you have a list of products when you click on a button to show details of some product, you may wait until loading indicator which may be shown on a details page of a product disappears. Capybara already waits for an element to appear, but it hasn't any possibility to wait for invisibility of an element, SitePrism has this capability and it is very useful.
         | 
| 233 248 |  | 
| 234 249 | 
             
            There is reason why you should use them when you use SitePrism.Vcr. If you specify a waiter while describing SitePrism elements or applying VCR cassettes, SitePrism.Vcr will know when the inserted cassettes should be ejected from Vcr to avoid a situation when some unexpected cassette is applied.
         | 
| 235 250 |  | 
| @@ -292,6 +307,36 @@ end | |
| 292 307 |  | 
| 293 308 | 
             
            The same thing can be defined for a default waiter.
         | 
| 294 309 |  | 
| 310 | 
            +
            In case you need to change only options defined for a default waiter, but you don't need to change a waiter, you can use `waiter_options` helper method:
         | 
| 311 | 
            +
             | 
| 312 | 
            +
            ```ruby
         | 
| 313 | 
            +
            @products_page.car_details_link.click_and_apply_vcr do
         | 
| 314 | 
            +
              waiter_options(eject_cassettes: false)
         | 
| 315 | 
            +
            end
         | 
| 316 | 
            +
            ```
         | 
| 317 | 
            +
             | 
| 318 | 
            +
            ### Applying VCR cassettes on any event
         | 
| 319 | 
            +
             | 
| 320 | 
            +
            There may be a situation when you need to apply cassettes for some custom event rather than for a click event. It may be a change event for a select box or a drag-and-drop event for a list or a blur event for an input element. SitePrism.Vcr gem provides a way to archive such goal:
         | 
| 321 | 
            +
             | 
| 322 | 
            +
            ```ruby
         | 
| 323 | 
            +
            @products_page.cars_dropdown.shift_event{
         | 
| 324 | 
            +
              set 'Ford'
         | 
| 325 | 
            +
            }.apply_vcr # uses default fixtures defined for this element
         | 
| 326 | 
            +
            ```
         | 
| 327 | 
            +
             | 
| 328 | 
            +
            or if you need to use another cassettes:
         | 
| 329 | 
            +
             | 
| 330 | 
            +
            ```ruby
         | 
| 331 | 
            +
            @products_page.cars_dropdown.shift_event{
         | 
| 332 | 
            +
              set 'Ford'
         | 
| 333 | 
            +
            }.apply_vcr do
         | 
| 334 | 
            +
              fixtures ['cars/ford/prices']
         | 
| 335 | 
            +
            end
         | 
| 336 | 
            +
            ```
         | 
| 337 | 
            +
             | 
| 338 | 
            +
            The block which is passed to `shift_event` method is executed in a context of an element, it means any method of [Capybara::Node::Element](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element) object can be used there. Similar to `click_and_apply_vcr` method, you can override cassettes, add new cassettes, use `path` helper method while applying cassettes and `home_path` helper method specified while defining a SitePrism element.
         | 
| 339 | 
            +
             | 
| 295 340 | 
             
            ### Linking and applying VCR cassettes with SitePrism pages
         | 
| 296 341 |  | 
| 297 342 | 
             
            External HTTP interactions may be done on page loading as well. This gem supports capability to apply Vcr cassettes on page loading. To define default cassettes you have to use `vcr_options_for_load` class method:
         | 
| @@ -306,7 +351,7 @@ end | |
| 306 351 |  | 
| 307 352 | 
             
            Everything described above about defining cassettes for SitePrism elements is true for defining cassettes for pages.
         | 
| 308 353 |  | 
| 309 | 
            -
            Applying cassettes is almost the same as  | 
| 354 | 
            +
            Applying cassettes is almost the same as you saw for a click event:
         | 
| 310 355 |  | 
| 311 356 | 
             
            ```ruby
         | 
| 312 357 | 
             
            page.load_and_apply_vcr do
         | 
| @@ -332,18 +377,6 @@ In this case, SitePrism will alter an url and it will look like: | |
| 332 377 | 
             
            http://localhost/cats/tom
         | 
| 333 378 | 
             
            ```
         | 
| 334 379 |  | 
| 335 | 
            -
            There may be situation when we need to apply fixtures for page loading when an user clicks on a link (an user moves from one page to another one). In this case you can use `apply_vcr` method of a page object:
         | 
| 336 | 
            -
             | 
| 337 | 
            -
            ```ruby
         | 
| 338 | 
            -
            @cars = CarsPage.new
         | 
| 339 | 
            -
             | 
| 340 | 
            -
            @cars.apply_vcr(-> { page.find('#cars').click }) do
         | 
| 341 | 
            -
              fixtures ['cars']
         | 
| 342 | 
            -
            end
         | 
| 343 | 
            -
            ```
         | 
| 344 | 
            -
             | 
| 345 | 
            -
            The first argument passed to this method should be a proc object which will do an action. As you can see while applying fixtures without actual loading a page you can use everything what is described for `load_and_apply_vcr` method.
         | 
| 346 | 
            -
             | 
| 347 380 | 
             
            ### Using Vcr options for cassettes
         | 
| 348 381 |  | 
| 349 382 | 
             
            Vcr provides number of options which can be used for cassettes. For example, you may [pass ERB into cassettes](https://relishapp.com/vcr/vcr/v/2-5-0/docs/cassettes/dynamic-erb-cassettes). This gem doesn't bother you use any options for Vcr cassettes. If you want to do so, you have to use a hash instead of a cassette name:
         | 
| @@ -368,6 +401,10 @@ It works with any kind of helper methods where you list names of cassettes, even | |
| 368 401 | 
             
            end
         | 
| 369 402 | 
             
            ```
         | 
| 370 403 |  | 
| 404 | 
            +
            ## Examples
         | 
| 405 | 
            +
             | 
| 406 | 
            +
            The simple example of using this gem you can find [here](https://github.com/dnesteryuk/site_prism.vcr_example)
         | 
| 407 | 
            +
             | 
| 371 408 | 
             
            ## Contributing
         | 
| 372 409 |  | 
| 373 410 | 
             
            1. Fork it
         | 
    
        data/TODO.md
    CHANGED
    
    | @@ -1,37 +1,30 @@ | |
| 1 1 | 
             
            # TODO
         | 
| 2 2 |  | 
| 3 | 
            -
            ## Release 0. | 
| 4 | 
            -
             | 
| 5 | 
            -
            1.  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
            ``` | 
| 20 | 
            -
             | 
| 21 | 
            -
              fixtures ['cars']
         | 
| 22 | 
            -
            end
         | 
| 23 | 
            -
            ```
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            into
         | 
| 3 | 
            +
            ## Release 0.1.1
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            1. Change integration tests to use real data.
         | 
| 6 | 
            +
            2. Think how to avoid monkey patching to add stuffs to SitePrism
         | 
| 7 | 
            +
            3. SPV::Applier#apply_vcr should be refactored, it is too complex
         | 
| 8 | 
            +
            4. Think about renaming current integration tests on acceptance tests and create new integration tests which will test integration between classes without involving a browser. It will solve a lot of issues with shared tests to check the same things for pages and elements. In acceptance tests we will test very basic stuffs.
         | 
| 9 | 
            +
            5. We should freeze an instance of SPV::Fixtures to make sure it is not mutable, otherwise, there may be situation when default fixtures will be corrupted.
         | 
| 10 | 
            +
            6. We should disable double defining actions in the adjusting block:
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              ```ruby
         | 
| 13 | 
            +
                self.some_link.click_and_apply_vcr do
         | 
| 14 | 
            +
                  fixtures ['test', 'test2']
         | 
| 15 | 
            +
                  union
         | 
| 16 | 
            +
                  fixtures ['test3']
         | 
| 17 | 
            +
                  replace
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              ```
         | 
| 20 | 
            +
            It will lead to mess.
         | 
| 26 21 |  | 
| 27 | 
            -
             | 
| 28 | 
            -
            @cars.shift_event{ page.find('#cars').click }.apply_vcr do
         | 
| 29 | 
            -
              fixtures ['cars']
         | 
| 30 | 
            -
            end
         | 
| 31 | 
            -
            ```
         | 
| 22 | 
            +
            ## Release 0.2.0
         | 
| 32 23 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 24 | 
            +
            1. Pages and elements should inherit fixtures defined for their parents
         | 
| 25 | 
            +
            2. When we eject fixtures from Vcr we should eject only fixtures inserted into Vcr by one specific fixtures manager (See SPV#eject)
         | 
| 26 | 
            +
            3. Make this gem working on JRuby (since we eject all VCR cassettes, it may be not thread safe)
         | 
| 27 | 
            +
            4. Think about creating set of fixtures which can be exchanged by a name of set. It will be very helpful when you have to exchange a set of fixtures.
         | 
| 35 28 |  | 
| 36 29 | 
             
            ## Should be implemented?
         | 
| 37 30 |  | 
| @@ -54,18 +47,13 @@ end | |
| 54 47 |  | 
| 55 48 | 
             
              will use previously defined fixtures
         | 
| 56 49 |  | 
| 57 | 
            -
            2. There should be possibility to change default fixtures:
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                ```ruby
         | 
| 60 | 
            -
                self.confirm_btn.vcr do
         | 
| 61 | 
            -
                  path 'products', ['tomato', 'fruit/apple']
         | 
| 62 | 
            -
                  path 'goods', 'cars'
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                  force_replace
         | 
| 65 | 
            -
                end
         | 
| 66 | 
            -
                ```
         | 
| 67 50 |  | 
| 68 51 | 
             
            ## Things to think over
         | 
| 69 52 |  | 
| 70 53 | 
             
            1. Should we add the integration tests for page load to make sure 2 HTTP requests will be handled properly?
         | 
| 71 54 | 
             
            2. Should we add own integration tests to test the path helper method?
         | 
| 55 | 
            +
            3. Should we add a test for testing to HTTP requests on page load?
         | 
| 56 | 
            +
            4. Should be Options class immutable?
         | 
| 57 | 
            +
            5. May be it makes sense to separately keep path from the name of a fixture? See SPV::Fixture class
         | 
| 58 | 
            +
             | 
| 59 | 
            +
             | 
| @@ -2,6 +2,8 @@ module SPV | |
| 2 2 | 
             
              # This class manages defining default fixtures
         | 
| 3 3 | 
             
              # and applying them on an event.
         | 
| 4 4 | 
             
              class Applier
         | 
| 5 | 
            +
                class EventError < StandardError; end
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
                def initialize(node, &block)
         | 
| 6 8 | 
             
                  @node, @options = node, Options.new
         | 
| 7 9 | 
             
                  adjuster = DSL::InitialAdjuster.new(@options)
         | 
| @@ -10,11 +12,17 @@ module SPV | |
| 10 12 | 
             
                    adjuster.instance_eval &block
         | 
| 11 13 | 
             
                  end
         | 
| 12 14 |  | 
| 13 | 
            -
                  @fixtures = adjuster. | 
| 15 | 
            +
                  @fixtures = adjuster.prepare_fixtures
         | 
| 14 16 |  | 
| 15 17 | 
             
                  @fixtures_manager = Fixtures::Manager.new(@options)
         | 
| 16 18 | 
             
                end
         | 
| 17 19 |  | 
| 20 | 
            +
                def shift_event(&block)
         | 
| 21 | 
            +
                  @event_action = block
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  self
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 18 26 | 
             
                # Applies fixtures to be used for stubbing HTTP interactions
         | 
| 19 27 | 
             
                # caused by an event (click on an element or page loading).
         | 
| 20 28 | 
             
                #
         | 
| @@ -26,7 +34,13 @@ module SPV | |
| 26 34 | 
             
                #  and @see SPV::DSL::Adjuster)
         | 
| 27 35 | 
             
                #
         | 
| 28 36 | 
             
                # @return [void]
         | 
| 29 | 
            -
                def  | 
| 37 | 
            +
                def apply_vcr(&block)
         | 
| 38 | 
            +
                  if @event_action.nil?
         | 
| 39 | 
            +
                    raise EventError.new(
         | 
| 40 | 
            +
                      'Event is not shifted, before applying Vcr you have to shift event with "shift_event" method'
         | 
| 41 | 
            +
                    )
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 30 44 | 
             
                  options = @options.clone_options
         | 
| 31 45 |  | 
| 32 46 | 
             
                  adjuster = DSL::Adjuster.new(
         | 
| @@ -34,13 +48,13 @@ module SPV | |
| 34 48 | 
             
                    @fixtures
         | 
| 35 49 | 
             
                  )
         | 
| 36 50 |  | 
| 37 | 
            -
                  if  | 
| 38 | 
            -
                    adjuster.instance_eval & | 
| 51 | 
            +
                  if block_given?
         | 
| 52 | 
            +
                    adjuster.instance_eval &block
         | 
| 39 53 | 
             
                  end
         | 
| 40 54 |  | 
| 41 | 
            -
                  @fixtures_manager.inject(adjuster. | 
| 55 | 
            +
                  @fixtures_manager.inject(adjuster.prepare_fixtures)
         | 
| 42 56 |  | 
| 43 | 
            -
                   | 
| 57 | 
            +
                  @event_action.call
         | 
| 44 58 |  | 
| 45 59 | 
             
                  @waiter = Waiter.new(
         | 
| 46 60 | 
             
                    @node,
         | 
| @@ -7,26 +7,45 @@ module SPV | |
| 7 7 | 
             
                    super options
         | 
| 8 8 |  | 
| 9 9 | 
             
                    @options, @fixtures = options, fixtures
         | 
| 10 | 
            +
                    @action = :replace
         | 
| 10 11 | 
             
                  end
         | 
| 11 12 |  | 
| 12 | 
            -
                  #  | 
| 13 | 
            -
                  #  | 
| 13 | 
            +
                  # Defines the replace action as an action which
         | 
| 14 | 
            +
                  # will be performed over cassettes while adjusting cassettes.
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  # Example:
         | 
| 17 | 
            +
                  #   @page.details_link.click_and_apply_vcr do
         | 
| 18 | 
            +
                  #     fixtures ['no_found']
         | 
| 19 | 
            +
                  #     replace
         | 
| 20 | 
            +
                  #   end
         | 
| 21 | 
            +
                  #
         | 
| 22 | 
            +
                  # In this case 'no_found' cassette will be used instead
         | 
| 23 | 
            +
                  # of default cassettes defined for 'details_link'.
         | 
| 14 24 | 
             
                  #
         | 
| 15 25 | 
             
                  # @return [void]
         | 
| 16 26 | 
             
                  #
         | 
| 17 27 | 
             
                  # @api public
         | 
| 18 28 | 
             
                  def replace
         | 
| 19 | 
            -
                     | 
| 29 | 
            +
                    @action = :replace
         | 
| 20 30 | 
             
                  end
         | 
| 21 31 |  | 
| 22 | 
            -
                  #  | 
| 23 | 
            -
                  #  | 
| 32 | 
            +
                  # Defines the union action as an action which
         | 
| 33 | 
            +
                  # will be performed over cassettes while adjusting cassettes.
         | 
| 34 | 
            +
                  #
         | 
| 35 | 
            +
                  # Example:
         | 
| 36 | 
            +
                  #   @page.details_link.click_and_apply_vcr do
         | 
| 37 | 
            +
                  #     fixtures ['no_found']
         | 
| 38 | 
            +
                  #     union
         | 
| 39 | 
            +
                  #   end
         | 
| 40 | 
            +
                  #
         | 
| 41 | 
            +
                  # In this case 'no_found' cassette will be used a long with
         | 
| 42 | 
            +
                  # default cassettes.
         | 
| 24 43 | 
             
                  #
         | 
| 25 44 | 
             
                  # @return [void]
         | 
| 26 45 | 
             
                  #
         | 
| 27 46 | 
             
                  # @api public
         | 
| 28 47 | 
             
                  def union
         | 
| 29 | 
            -
                     | 
| 48 | 
            +
                    @action = :union
         | 
| 30 49 | 
             
                  end
         | 
| 31 50 |  | 
| 32 51 | 
             
                  # Exchanges certain default fixtures with another fixtures.
         | 
| @@ -57,26 +76,28 @@ module SPV | |
| 57 76 | 
             
                    )
         | 
| 58 77 | 
             
                  end
         | 
| 59 78 |  | 
| 79 | 
            +
                  # Redefines default waiter options or if default waiter options is not defined,
         | 
| 80 | 
            +
                  # it defines new options for a waiter. This method doesn't redefine all default options,
         | 
| 81 | 
            +
                  # it redefines only options passed in a hash.
         | 
| 82 | 
            +
                  #
         | 
| 83 | 
            +
                  # @param options [Hash] Options for a waiter
         | 
| 84 | 
            +
                  #
         | 
| 85 | 
            +
                  # @return [void]
         | 
| 86 | 
            +
                  #
         | 
| 87 | 
            +
                  # @api public
         | 
| 88 | 
            +
                  def waiter_options(options)
         | 
| 89 | 
            +
                    @options.merge_waiter_options!(options)
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 60 92 | 
             
                  # Performs the replace action when no explicit action is defined
         | 
| 61 93 | 
             
                  # in a block for manipulating fixtures before applying them.
         | 
| 62 94 | 
             
                  #
         | 
| 63 95 | 
             
                  # @return [SPV::Fixtures] A set of prepared fixtures.
         | 
| 64 96 | 
             
                  #
         | 
| 65 97 | 
             
                  # @api public
         | 
| 66 | 
            -
                  def  | 
| 67 | 
            -
                     | 
| 68 | 
            -
                    # it should be performed manually, before allowing
         | 
| 69 | 
            -
                    # to get prepared fixtures.
         | 
| 70 | 
            -
                    replace unless @is_action_done # TODO: do something with this logic, it looks ugly
         | 
| 71 | 
            -
                    @fixtures
         | 
| 98 | 
            +
                  def prepare_fixtures
         | 
| 99 | 
            +
                    @fixtures.public_send(@action, @tmp_keeper.fixtures)
         | 
| 72 100 | 
             
                  end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                  private
         | 
| 75 | 
            -
                    def change_fixtures(action)
         | 
| 76 | 
            -
                      @fixtures = @fixtures.public_send(action, @tmp_keeper.fixtures)
         | 
| 77 | 
            -
                      @tmp_keeper.clean_fixtures
         | 
| 78 | 
            -
                      @is_action_done = true
         | 
| 79 | 
            -
                    end
         | 
| 80 101 | 
             
                end # class Adjuster
         | 
| 81 102 | 
             
              end # module DSL
         | 
| 82 103 | 
             
            end # module SPV
         | 
| @@ -1,18 +1,21 @@ | |
| 1 1 | 
             
            require 'delegate'
         | 
| 2 | 
            +
            require 'forwardable'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module SPV
         | 
| 4 5 | 
             
              # Extends a native Capybara element with new methods.
         | 
| 5 6 | 
             
              class Element < SimpleDelegator
         | 
| 7 | 
            +
                extend Forwardable
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def_delegator :@applier, :shift_event
         | 
| 10 | 
            +
             | 
| 6 11 | 
             
                def initialize(element, parent, &block)
         | 
| 7 12 | 
             
                  super element
         | 
| 8 13 |  | 
| 9 14 | 
             
                  @applier = Applier.new(parent, &block)
         | 
| 10 15 | 
             
                end
         | 
| 11 16 |  | 
| 12 | 
            -
                def click_and_apply_vcr(& | 
| 13 | 
            -
                   | 
| 14 | 
            -
                    click
         | 
| 15 | 
            -
                  end
         | 
| 17 | 
            +
                def click_and_apply_vcr(&block)
         | 
| 18 | 
            +
                  shift_event { click }.apply_vcr(&block)
         | 
| 16 19 | 
             
                end
         | 
| 17 20 | 
             
              end
         | 
| 18 | 
            -
            end
         | 
| 21 | 
            +
            end
         | 
| @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            # TODO: should be this class immutable?
         | 
| 2 1 | 
             
            module SPV
         | 
| 3 2 | 
             
              class Options
         | 
| 4 3 | 
             
                attr_accessor :waiter, :waiter_options, :home_path
         | 
| @@ -18,5 +17,17 @@ module SPV | |
| 18 17 | 
             
                def clone_options
         | 
| 19 18 | 
             
                  dup
         | 
| 20 19 | 
             
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def waiter_options
         | 
| 22 | 
            +
                  @waiter_options || {}
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                # Merges already defined waiter's options with a given hash.
         | 
| 26 | 
            +
                #
         | 
| 27 | 
            +
                # If waiter's options are not defined yet, it will define waiter options
         | 
| 28 | 
            +
                # with a given hash.
         | 
| 29 | 
            +
                def merge_waiter_options!(options)
         | 
| 30 | 
            +
                  self.waiter_options = self.waiter_options.merge(options)
         | 
| 31 | 
            +
                end
         | 
| 21 32 | 
             
              end
         | 
| 22 33 | 
             
            end
         | 
| @@ -2,6 +2,10 @@ module SitePrism::ElementContainer | |
| 2 2 | 
             
              def element_with_vcr(element_name, *args, &block)
         | 
| 3 3 | 
             
                element element_name, *args
         | 
| 4 4 |  | 
| 5 | 
            +
                link_vcr_with_element(element_name, &block)
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def link_vcr_with_element(element_name, &block)
         | 
| 5 9 | 
             
                origin_element_name = "origin_#{element_name}"
         | 
| 6 10 |  | 
| 7 11 | 
             
                alias_method origin_element_name, element_name
         | 
| @@ -1,41 +1,39 @@ | |
| 1 | 
            +
            require 'forwardable'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module SitePrism
         | 
| 2 4 | 
             
              class Page
         | 
| 3 | 
            -
                 | 
| 4 | 
            -
                def self.inherited(subclass)
         | 
| 5 | 
            -
                  # This code is required to allow subpages to inherit
         | 
| 6 | 
            -
                  # a defined adjuster block. Otherwise, that block should be
         | 
| 7 | 
            -
                  # duplicated in a subpage as well.
         | 
| 8 | 
            -
                  subclass.instance_variable_set(:@vcr_adjuster, @vcr_adjuster)
         | 
| 9 | 
            -
                end
         | 
| 5 | 
            +
                extend Forwardable
         | 
| 10 6 |  | 
| 11 | 
            -
                 | 
| 12 | 
            -
                  @vcr_adjuster = block
         | 
| 13 | 
            -
                end
         | 
| 7 | 
            +
                def_delegator :@applier, :shift_event
         | 
| 14 8 |  | 
| 15 | 
            -
                 | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 9 | 
            +
                class << self
         | 
| 10 | 
            +
                  def inherited(subclass)
         | 
| 11 | 
            +
                    # This code is required to allow subpages to inherit
         | 
| 12 | 
            +
                    # a defined adjuster block. Otherwise, that block should be
         | 
| 13 | 
            +
                    # duplicated in a subpage as well.
         | 
| 14 | 
            +
                    subclass.instance_variable_set(:@vcr_adjuster, @vcr_adjuster)
         | 
| 15 | 
            +
                  end
         | 
| 18 16 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                    &self.class.vcr_adjuster
         | 
| 23 | 
            -
                  )
         | 
| 17 | 
            +
                  def vcr_options_for_load(&block)
         | 
| 18 | 
            +
                    @vcr_adjuster = block
         | 
| 19 | 
            +
                  end
         | 
| 24 20 |  | 
| 25 | 
            -
                   | 
| 26 | 
            -
                     | 
| 27 | 
            -
                  ) do
         | 
| 28 | 
            -
                    action_block.call
         | 
| 21 | 
            +
                  def vcr_adjuster
         | 
| 22 | 
            +
                    @vcr_adjuster
         | 
| 29 23 | 
             
                  end
         | 
| 30 24 | 
             
                end
         | 
| 31 25 |  | 
| 32 | 
            -
                def  | 
| 33 | 
            -
                   | 
| 26 | 
            +
                def initialize(*args)
         | 
| 27 | 
            +
                  super
         | 
| 34 28 |  | 
| 35 | 
            -
                   | 
| 36 | 
            -
                     | 
| 37 | 
            -
                    & | 
| 29 | 
            +
                  @applier = SPV::Applier.new(
         | 
| 30 | 
            +
                    self,
         | 
| 31 | 
            +
                    &self.class.vcr_adjuster
         | 
| 38 32 | 
             
                  )
         | 
| 39 33 | 
             
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def load_and_apply_vcr(*args, &block)
         | 
| 36 | 
            +
                  shift_event { load(*args) }.apply_vcr(&block)
         | 
| 37 | 
            +
                end
         | 
| 40 38 | 
             
              end
         | 
| 41 39 | 
             
            end
         |