Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cypress js plugin and vcr integration #103

Merged
merged 6 commits into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- run: gem uninstall -v '>= 2' -ax bundler || true
- run: gem install bundler -v '< 2'
- name: Run interaction tests
run: ./spec/integrations/rails_3_2/test.sh
run: ./specs_e2e/rails_3_2/test.sh

rails_4_2:
runs-on: ubuntu-latest
Expand All @@ -39,7 +39,7 @@ jobs:
- run: gem uninstall -v '>= 2' -ax bundler || true
- run: gem install bundler -v '< 2'
- name: Run interaction tests
run: ./spec/integrations/rails_4_2/test.sh
run: ./specs_e2e/rails_4_2/test.sh

rails_5_2:
runs-on: ubuntu-latest
Expand All @@ -54,4 +54,4 @@ jobs:
- name: Run tests
run: bundle exec rake
- name: Run interaction tests
run: ./spec/integrations/rails_5_2/test.sh
run: ./specs_e2e/rails_5_2/test.sh
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ spec/examples.txt
spec/test.log
pkg/*.gem
vendor/bundle
.vscode
.vscode
node_modules
package-lock.json
yarn.lock
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## []

### Changed
* Add support for matching npm package and VCR

## [1.12.1]
[Compare]: https://github.com/shakacode/cypress-on-rails/compare/v1.12.0...v1.12.1

Expand Down
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,68 @@ describe('My First Test', function() {
})
```

## Expermintal Features (matching npm package)

Please test and give feedback

add the npm package:

```
yarn add cypress-on-rails --dev
```

### for VCR

#### setup

Add you VCR configuration to your `cypress_helper.rb`

```ruby
require 'vcr'
VCR.configure do |config|
config.hook_into :webmock
end
```

Add to you `cypress/support/index.js`

```js
import 'cypress-on-rails/support/index'
```

Add to you `clean.rb`

```ruby
VCR.eject_cassette # make sure we no cassettes inserted before the next test starts
```

#### usage

You have `vcr_insert_cassette` and `vcr_eject_cassette` available. https://www.rubydoc.info/github/vcr/vcr/VCR:insert_cassette


```js
describe('My First Test', function() {
beforeEach(() => { cy.app('load_seed') })

it('visit root', function() {
cy.app('clean') // have a look at cypress/app_commands/clean.rb

cy.vcr_insert_cassette('cats', { record: "new_episodes" })
cy.visit('/using_vcr/index')

cy.get('a').contains('Cats').click()
cy.contains('Wikipedia has a recording of a cat meowing, because why not?')

cy.vcr_eject_cassette();

cy.vcr_insert_cassette('cats')
cy.visit('/using_vcr/record_cats')
cy.contains('Wikipedia has a recording of a cat meowing, because why not?')
})
})
```

## Usage with other rack applications

Add CypressOnRails to your config.ru
Expand Down
1 change: 1 addition & 0 deletions cypress-on-rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rspec'
s.add_development_dependency 'railties', '>= 3.2'
s.add_development_dependency 'factory_bot'
s.add_development_dependency 'vcr'
s.metadata = {
"bug_tracker_uri" => "https://github.com/shakacode/cypress-on-rails/issues",
"changelog_uri" => "https://github.com/shakacode/cypress-on-rails/blob/master/CHANGELOG.md",
Expand Down
15 changes: 5 additions & 10 deletions lib/cypress_on_rails/middleware.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
require 'json'
require 'rack'
require 'cypress_on_rails/configuration'
require 'cypress_on_rails/middleware_config'
require 'cypress_on_rails/command_executor'

module CypressOnRails
# Middleware to handle cypress commands and eval
class Middleware
include MiddlewareConfig

def initialize(app, command_executor = CommandExecutor, file = ::File)
@app = app
@command_executor = command_executor
Expand All @@ -23,14 +25,6 @@ def call(env)

private

def configuration
CypressOnRails.configuration
end

def logger
configuration.logger
end

Command = Struct.new(:name, :options, :cypress_folder) do
# @return [Array<Cypress::Middleware::Command>]
def self.from_body(body, configuration)
Expand Down Expand Up @@ -71,7 +65,8 @@ def handle_command(req)
[500, {'Content-Type' => 'application/json'}, [output]]
end
else
[404, {}, ["could not find command file: #{missing_command.file_path}"]]
output = {"message" => "could not find command file: #{missing_command.file_path}"}.to_json
[404, {'Content-Type' => 'application/json'}, [output]]
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/cypress_on_rails/middleware_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'json'
require 'rack'
require 'cypress_on_rails/configuration'

module CypressOnRails
module MiddlewareConfig
protected

def configuration
CypressOnRails.configuration
end

def logger
configuration.logger
end
end
end
4 changes: 3 additions & 1 deletion lib/cypress_on_rails/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
require 'rails/railtie'
require 'cypress_on_rails/configuration'
require 'cypress_on_rails/middleware'

module CypressOnRails
class Railtie < Rails::Railtie
initializer :setup_cypress_middleware, after: :load_config_initializers do |app|
if CypressOnRails.configuration.use_middleware?
require 'cypress_on_rails/middleware'
app.middleware.use Middleware
require 'cypress_on_rails/vcr_middleware'
app.middleware.use VCRMiddleware
end
end
end
Expand Down
60 changes: 60 additions & 0 deletions lib/cypress_on_rails/vcr_middleware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'json'
require 'rack'
require 'cypress_on_rails/middleware_config'

module CypressOnRails
# Middleware to handle vcr
class VCRMiddleware
include MiddlewareConfig

def initialize(app, vcr = nil)
@app = app
@vcr = vcr
end

def call(env)
request = Rack::Request.new(env)
if request.path.start_with?('/__cypress__/vcr/insert')
configuration.tagged_logged { handle_insert(request) }
elsif request.path.start_with?('/__cypress__/vcr/eject')
configuration.tagged_logged { handle_eject }
else
@app.call(env)
end
end

private

def handle_insert(req)
body = JSON.parse(req.body.read)
logger.info "vcr insert cassette: #{body}"
cassette_name = body[0]
options = (body[1] || {}).symbolize_keys
options[:record] = options[:record].to_sym if options[:record]
options[:match_requests_on] = options[:match_requests_on].map(&:to_sym) if options[:match_requests_on]
options[:serialize_with] = options[:serialize_with].to_sym if options[:serialize_with]
options[:persist_with] = options[:persist_with].to_sym if options[:persist_with]
vcr.insert_cassette(cassette_name, options)
[201, {'Content-Type' => 'application/json'}, [{'message': 'OK'}.to_json]]
rescue LoadError, ArgumentError => e
[501, {'Content-Type' => 'application/json'}, [{'message': e.message}.to_json]]
end

def handle_eject
logger.info "vcr eject cassette"
vcr.eject_cassette
[201, {'Content-Type' => 'application/json'}, [{'message': 'OK'}.to_json]]
rescue LoadError, ArgumentError => e
[501, {'Content-Type' => 'application/json'}, [{'message': e.message}.to_json]]
end

def vcr
return @vcr if @vcr
require 'vcr'
VCR.configure do |config|
config.cassette_library_dir = "#{configuration.cypress_folder}/fixtures/vcr_cassettes"
end
@vcr = VCR
end
end
end
43 changes: 21 additions & 22 deletions lib/generators/cypress_on_rails/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,37 @@ class InstallGenerator < Rails::Generators::Base
class_option :install_cypress, type: :boolean, default: true
class_option :install_cypress_with, type: :string, default: 'yarn'
class_option :install_cypress_examples, type: :boolean, default: false
class_option :experimental, type: :boolean, default: false
source_root File.expand_path('../templates', __FILE__)

def install_cypress
if !Dir.exists?(options.cypress_folder) || Dir["#{options.cypress_folder}/*"].empty?
directories = options.cypress_folder.split('/')
directories.pop
install_dir = "#{Dir.pwd}/#{directories.join('/')}"
command = nil
if options.install_cypress
if options.install_cypress_with == 'yarn'
command = "yarn --cwd=#{install_dir} add cypress --dev"
elsif options.install_cypress_with == 'npm'
command = "cd #{install_dir}; npm install cypress --save-dev"
end
if command
say command
fail 'failed to install cypress' unless system(command)
end
directories = options.cypress_folder.split('/')
directories.pop
install_dir = "#{Dir.pwd}/#{directories.join('/')}"
command = nil
if options.install_cypress
if options.install_cypress_with == 'yarn'
command = "yarn --cwd=#{install_dir} add cypress --dev"
elsif options.install_cypress_with == 'npm'
command = "cd #{install_dir}; npm install cypress --save-dev"
end
if options.install_cypress_examples
directory 'spec/cypress/integration/examples', "#{options.cypress_folder}/integration/examples"
directory 'spec/cypress/fixtures', "#{options.cypress_folder}/fixtures"
if command
say command
fail 'failed to install cypress' unless system(command)
end
copy_file "spec/cypress/support/index.js", "#{options.cypress_folder}/support/index.js"
copy_file "spec/cypress/support/commands.js", "#{options.cypress_folder}/support/commands.js"
copy_file "spec/cypress.json", "#{options.cypress_folder}/../cypress.json"
end
if options.install_cypress_examples
directory 'spec/cypress/integration/examples', "#{options.cypress_folder}/integration/examples"
directory 'spec/cypress/fixtures', "#{options.cypress_folder}/fixtures"
end
template "spec/cypress/support/index.js.erb", "#{options.cypress_folder}/support/index.js"
copy_file "spec/cypress/support/commands.js", "#{options.cypress_folder}/support/commands.js"
copy_file "spec/cypress.json", "#{options.cypress_folder}/../cypress.json"
end

def add_initial_files
template "config/initializers/cypress_on_rails.rb.erb", "config/initializers/cypress_on_rails.rb"
copy_file "spec/cypress/cypress_helper.rb", "#{options.cypress_folder}/cypress_helper.rb"
template "spec/cypress/cypress_helper.rb.erb", "#{options.cypress_folder}/cypress_helper.rb"
copy_file "spec/cypress/support/on-rails.js", "#{options.cypress_folder}/support/on-rails.js"
directory 'spec/cypress/app_commands', "#{options.cypress_folder}/app_commands"
directory 'spec/cypress/integration/rails_examples', "#{options.cypress_folder}/integration/rails_examples"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@

CypressOnRails::SmartFactoryWrapper.reload

if defined?(VCR)
VCR.eject_cassette # make sure we any cassettes inserted before the next test starts
end

Rails.logger.info "APPCLEANED" # used by log_fail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@
Rails.root.join('spec', 'factories', '**', '*.rb')
]
)

<% unless options.experimental %># <% end %>require 'vcr'
<% unless options.experimental %># <% end %>VCR.configure do |config|
<% unless options.experimental %># <% end %> config.hook_into :webmock
<% unless options.experimental %># <% end %>end
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
describe('Rails Other examples', function() {
it('Inserting a cassette', function() {
cy.app('clean') // have a look at cypress/app_commands/clean.rb

cy.vcr_insert_cassette('cats', { record: "new_episodes" })
cy.visit('/using_vcr/index')

cy.get('a').contains('Cats').click()
cy.contains('Wikipedia has a recording of a cat meowing, because why not?')

cy.vcr_eject_cassette();

cy.vcr_insert_cassette('cats')
cy.visit('/using_vcr/record_cats')
cy.contains('Wikipedia has a recording of a cat meowing, because why not?')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// ***********************************************************

// Import commands.js using ES2015 syntax:
<% unless options.experimental %>// <% end %>import 'cypress-on-rails/support/index'
import './commands'
import './on-rails'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Cypress.Commands.add('appCommands', function (body) {
}).then((response) => {
log.end();
if (response.status !== 201) {
expect(response.body.message).to.be.empty
expect(response.body.message).to.equal('')
expect(response.status).to.be.equal(201)
}
return response.body
Expand Down
1 change: 1 addition & 0 deletions plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
4 changes: 4 additions & 0 deletions plugin/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// export a function
module.exports = (on, config) => {
// configure plugins here
}
Loading