cypress-on-rails 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f9cbd99f7da9dce7af96793994e292e74e5c5a1
4
- data.tar.gz: f16a4b910fbc00b5878a71817968c5e01a2a24be
3
+ metadata.gz: 307be16313426be599e503b2612ab3f33c8d4b54
4
+ data.tar.gz: 81a10e2d6563f57cc3e2a5cb71d0547d2366b278
5
5
  SHA512:
6
- metadata.gz: 6b2d320c20555076caa3740d6e08eac654c8d60e83ef5754d1d1b9d284fb271747f51652bc0c302cac50a30f5fcf12d2ea50929d5a81d79f08ac721d3767d943
7
- data.tar.gz: 24bcaf7c815bcc5abd4bd05bb726ea566eacf7b8d4d26f4f2025a6aef26bb1b6865a618becabaeab6eccf34e9e7aedcb5b718fce3bc4ed36b3f94f0da7187433
6
+ metadata.gz: baa22d4846debaec324dc1641410a27e523665fea8bcf70624d165955809ec03054acd81564cb3075f6ff6c4ed1b29014fe23746f6bfa0a6f5ab8a0167d2979e
7
+ data.tar.gz: 2fe3bb98ea96886a22d509a9881127cb10faa505b172734e41993063ebf5d6e9ee128a3bad2ee6884f3dc7e9585ef423ca0019ff5b3568f26805ed99801b0251
@@ -0,0 +1,11 @@
1
+ ## 0.1.5 (2017-11-01)
2
+
3
+ ### Added
4
+ * `cy.rails` command for executing raw ruby on the backend
5
+ * `cy.setupRails` command for resetting application state
6
+ * `cypress:install` generator now adds a `beforeEach` call to `cy.setupRails`
7
+ * `cypress:install` generator configures the `cache_classes` setting in `config/environments/test.rb`
8
+ * configuration option to include further modules in your runcontext
9
+
10
+ ## 0.1.2 (2017-10-31)
11
+ * First release.
data/README.md CHANGED
@@ -1 +1,107 @@
1
- # cypress-on-rails
1
+ # cypress-on-rails
2
+
3
+ Proof-of-Concept gem for using [cypress.io](http://github.com/cypress-io/) in Rails applications. It provides the following features:
4
+ * run ruby code in your application context before executing a test
5
+ * database cleaning before test run (using database_cleaner)
6
+ * ability to use RSpec Mocks for your Rails code
7
+
8
+ ## Getting started
9
+
10
+ Add this to your Gemfile:
11
+ ```
12
+ group :test do
13
+ gem 'cypress-on-rails'
14
+ end
15
+ ```
16
+
17
+ The generate the boilerplate code using:
18
+ ```
19
+ rails g cypress:install
20
+ ```
21
+
22
+ Finally add the `cypress` package using yarn:
23
+ ```
24
+ yarn add --dev cypress
25
+ ```
26
+
27
+ If you are not using RSpec and/or database_cleaner look at `spec/cypress/cypress_helper.rb`.
28
+
29
+ ## Usage
30
+
31
+ This gem provides the `cypress` command. When called without any arguments ie. `bundle exec cypress`, it will start the cypress.io UI. While running the UI you can edit both your application and test code and see the effects on the next test run. When run as `bundle exec cypress run` it runs headless for CI testing.
32
+
33
+ The generator adds the following files/directory to your application:
34
+ * `spec/cypress/cypress_helper.rb` contains your configuration
35
+ * `spec/cypress/integrations/` contains your tests
36
+ * `spec/cypress/scenarios/` contains your scenario definitions
37
+ * `spec/cypress/support/setup.js` contains support code
38
+
39
+ When writing End-to-End tests, you will probably want to prepare your database to a known state. Maybe using a gem like factory_girl. This gem implements two methods to achieve this goal:
40
+
41
+ ### Using embedded ruby
42
+ You can embed ruby code in your test file. This code will then be executed in the context of your application. For example:
43
+
44
+ // spec/cypress/integrations/simple_spec.js
45
+ describe('My First Test', function() {
46
+ it('visit root', function() {
47
+ // This calls to the backend to prepare the application state
48
+ cy.rails(`
49
+ Profile.create name: "Cypress Hill"
50
+ `)
51
+
52
+ // The application unter test is available at SERVER_PORT
53
+ cy.visit('http://localhost:'+Cypress.env("SERVER_PORT"))
54
+
55
+ cy.contains("Cypress Hill")
56
+ })
57
+ })
58
+
59
+ Use the (`) backtick string syntax to allow multiline strings.
60
+
61
+ ### Using scenarios
62
+
63
+ Scenarios are named `before` blocks that you can reference in your test.
64
+
65
+ You define a scenario in the `spec/cypress/scenarios` directory:
66
+ ```
67
+ # spec/cypress/scenarios/basic.rb
68
+ scenario :basic do
69
+ Profile.create name: "Cypress Hill"
70
+ end
71
+ ```
72
+
73
+ Then reference the scenario in your test:
74
+ ```
75
+ // spec/cypress/integrations/simple_spec.js
76
+ describe('My First Test', function() {
77
+ it('visit root', function() {
78
+ // This calls to the backend to prepare the application state
79
+ cy.setupScenario('basic')
80
+
81
+ // The application unter test is available at SERVER_PORT
82
+ cy.visit('http://localhost:'+Cypress.env("SERVER_PORT"))
83
+
84
+ cy.contains("Cypress Hill")
85
+ })
86
+ })
87
+ ```
88
+
89
+ The `setupScenario` call does the following things:
90
+ * clears the database using database_cleaner (can be disabled)
91
+ * calls the optional `before` block from `spec/cypress/cypress_helper.rb`
92
+ * calls the scenario block associated with the name given
93
+
94
+ In the scenario you also have access to RSpec mocking functions. So you could do something like:
95
+ ```
96
+ scenario :basic do
97
+ allow(ExternalService).to receive(:retrieve).and_return("result")
98
+ end
99
+ ```
100
+
101
+ An example application is available at https://github.com/konvenit/cypress-on-rails-example
102
+
103
+ # Limitations
104
+ This code is very much at the proof-of-concept stage. The following limitations are known:
105
+ * It requires yarn for the javascript dependency management
106
+ * Only tested on Rails 5.1
107
+ * Only works with RSpec and database_cleaner
@@ -3,11 +3,12 @@ require 'active_support/dependencies/autoload'
3
3
  module Cypress
4
4
  extend ActiveSupport::Autoload
5
5
 
6
- autoload :Server, 'cypress/server'
7
- autoload :CallbackServer, 'cypress/callback_server'
8
- autoload :Runner, 'cypress/runner'
9
- autoload :ScenarioBank, 'cypress/scenario_bank'
10
- autoload :Configuration, 'cypress/configuration'
6
+ autoload :Server, 'cypress/server'
7
+ autoload :CallbackServer, 'cypress/callback_server'
8
+ autoload :Runner, 'cypress/runner'
9
+ autoload :ScenarioBank, 'cypress/scenario_bank'
10
+ autoload :ScenarioContext, 'cypress/scenario_context'
11
+ autoload :Configuration, 'cypress/configuration'
11
12
 
12
13
  def self.configuration
13
14
  @configuration ||= Configuration.new
@@ -1,11 +1,22 @@
1
+ require 'webrick'
2
+ require 'json'
3
+
1
4
  module Cypress
2
5
  class CallbackServer
3
6
  attr_reader :port
4
7
  def initialize(owner)
5
8
  @port = 9293
6
9
  @webrick = WEBrick::HTTPServer.new(:Port => port)
7
- @webrick.mount_proc '/' do |req, res|
8
- owner.run_command JSON.parse(req.body)
10
+ @webrick.mount_proc '/setup' do |req, res|
11
+ owner.run_command :setup
12
+ res.body = ''
13
+ end
14
+ @webrick.mount_proc '/eval' do |req, res|
15
+ owner.run_command :eval, JSON.parse(req.body)
16
+ res.body = ''
17
+ end
18
+ @webrick.mount_proc '/scenario' do |req, res|
19
+ owner.run_command :scenario, JSON.parse(req.body)
9
20
  res.body = ''
10
21
  end
11
22
  end
@@ -8,6 +8,10 @@ module Cypress
8
8
  @before = proc {}
9
9
  end
10
10
 
11
+ def include(mod)
12
+ ScenarioContext.send :include, mod
13
+ end
14
+
11
15
  def before(&block)
12
16
  if block_given?
13
17
  @before = block
@@ -4,13 +4,6 @@ module Cypress
4
4
  @scenarios = {}
5
5
  end
6
6
 
7
- def boot
8
- if Cypress.configuration.test_framework == :rspec
9
- require 'rspec/rails'
10
- extend RSpec::Mocks::ExampleMethods
11
- end
12
- end
13
-
14
7
  def load
15
8
  Dir['./spec/cypress/scenarios/**/*.rb'].each do |f|
16
9
  instance_eval(File.read(f), f)
@@ -0,0 +1,23 @@
1
+ module Cypress
2
+ class ScenarioContext
3
+ def initialize(configuration)
4
+ if configuration.test_framework == :rspec
5
+ setup_rspec
6
+ end
7
+ end
8
+
9
+ def execute(block_or_code)
10
+ if block_or_code.is_a? Proc
11
+ instance_eval &block_or_code
12
+ else
13
+ instance_eval block_or_code
14
+ end
15
+ end
16
+
17
+ private
18
+ def setup_rspec
19
+ require 'rspec/rails'
20
+ extend RSpec::Mocks::ExampleMethods
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,3 @@
1
- require 'webrick'
2
- require 'json'
3
-
4
1
  module Cypress
5
2
  class Server
6
3
  def initialize(args)
@@ -19,9 +16,7 @@ module Cypress
19
16
  end
20
17
 
21
18
  def run
22
- load_cypress_helper
23
19
  server_port = boot_rails
24
- @scenario_bank.boot
25
20
 
26
21
  @callback_thread = Thread.new { @callback_server.start }
27
22
  @runner_thread = Thread.new { @runner.run server_port }
@@ -30,15 +25,9 @@ module Cypress
30
25
  @callback_server.shutdown
31
26
  end
32
27
 
33
- def run_command(command)
34
- @scenario_bank.load
35
-
36
- if command['scenario'] and (block = @scenario_bank[command['scenario']])
37
- reset_rspec if configuration.test_framework == :rspec
38
- call_database_cleaner if configuration.db_resetter == :database_cleaner
39
- configuration.before.call
40
-
41
- block.call
28
+ def run_command(command, options={})
29
+ if respond_to?("run_command_#{command}", true)
30
+ send "run_command_#{command}", options
42
31
  end
43
32
  end
44
33
 
@@ -48,17 +37,18 @@ module Cypress
48
37
  end
49
38
 
50
39
  def boot_rails
51
- ENV['RAILS_ENV'] ||= 'test'
52
- require './config/environment'
40
+ configuration.disable_class_caching if mode == 'open'
41
+ require "./spec/cypress/cypress_helper"
53
42
  require 'capybara/rails'
54
43
 
55
44
  Capybara.current_driver = :selenium # oh, the irony....
56
45
  Capybara.current_session.server.port
57
46
  end
58
47
 
59
- def load_cypress_helper
60
- require "./spec/cypress/cypress_helper"
61
- configuration.disable_class_caching if mode == 'open'
48
+ def run_command_setup(options={})
49
+ reset_rspec if configuration.test_framework == :rspec
50
+ call_database_cleaner if configuration.db_resetter == :database_cleaner
51
+ new_context.execute configuration.before
62
52
  end
63
53
 
64
54
  def reset_rspec
@@ -71,5 +61,22 @@ module Cypress
71
61
  DatabaseCleaner.strategy = :truncation
72
62
  DatabaseCleaner.clean
73
63
  end
64
+
65
+ def run_command_scenario(options={})
66
+ run_command_setup
67
+
68
+ @scenario_bank.load
69
+ if block = @scenario_bank[options['scenario']]
70
+ new_context.execute block
71
+ end
72
+ end
73
+
74
+ def run_command_eval(options={})
75
+ new_context.execute options['code']
76
+ end
77
+
78
+ def new_context
79
+ ScenarioContext.new(configuration)
80
+ end
74
81
  end
75
82
  end
@@ -1,3 +1,3 @@
1
1
  module Cypress
2
- VERSION = "0.1.2".freeze
2
+ VERSION = "0.1.5".freeze
3
3
  end
@@ -6,7 +6,16 @@ module Cypress
6
6
  empty_directory "spec/cypress/scenarios"
7
7
  empty_directory "spec/cypress/support"
8
8
 
9
+ replace = [
10
+ "# when running the cypress UI, allow reloading of classes",
11
+ "config.cache_classes = (defined?(Cypress) ? Cypress.configuration.cache_classes : true)"
12
+ ]
13
+ gsub_file 'config/environments/test.rb', 'config.cache_classes = true', replace.join("\n")
14
+
9
15
  create_file "spec/cypress/cypress_helper.rb", <<-FILE
16
+ ENV['RAILS_ENV'] ||= 'test'
17
+ require File.expand_path('../../../config/environment', __FILE__)
18
+
10
19
  Cypress.configure do |c|
11
20
  # change this to nil, if you are not using RSpec Mocks
12
21
  c.test_framework = :rspec
@@ -18,6 +27,9 @@ Cypress.configure do |c|
18
27
  # this is called when you call cy.setupScenario
19
28
  # use it to reset your application state
20
29
  end
30
+
31
+ # add a module to your run context
32
+ # c.include MyModule
21
33
  end
22
34
  FILE
23
35
 
@@ -42,11 +54,23 @@ end
42
54
  FILE
43
55
 
44
56
  create_file "spec/cypress/support/setup.js", <<-FILE
45
- // dont remove this command
57
+ // cypress-on-rails: dont remove these command
58
+ Cypress.Commands.add('setupRails', function () {
59
+ cy.request('POST', Cypress.env("CALLBACK") + "/setup")
60
+ });
61
+
46
62
  Cypress.Commands.add('setupScenario', function(name) {
47
63
  Cypress.log({ message: name })
48
- cy.request('POST', Cypress.env("CALLBACK"), JSON.stringify({ scenario: name }))
64
+ cy.request('POST', Cypress.env("CALLBACK")+"/scenario", JSON.stringify({ scenario: name }))
49
65
  });
66
+
67
+ Cypress.Commands.add('rails', function(code) {
68
+ cy.request('POST', Cypress.env("CALLBACK") + "/eval", JSON.stringify({ code: code }))
69
+ })
70
+ // cypress-on-rails: end
71
+
72
+ // The next setup is optional, but if you remove it you will have to manually reset the database
73
+ beforeEach(() => { cy.setupRails() });
50
74
  FILE
51
75
  end
52
76
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cypress-on-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - miceportal team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-31 00:00:00.000000000 Z
11
+ date: 2017-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -60,6 +60,7 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - CHANGELOG.md
63
64
  - Gemfile
64
65
  - Gemfile.lock
65
66
  - README.md
@@ -73,6 +74,7 @@ files:
73
74
  - lib/cypress/railtie.rb
74
75
  - lib/cypress/runner.rb
75
76
  - lib/cypress/scenario_bank.rb
77
+ - lib/cypress/scenario_context.rb
76
78
  - lib/cypress/server.rb
77
79
  - lib/cypress/version.rb
78
80
  - lib/generators/install_generator.rb