cypress-on-rails 0.1.2 → 0.1.5

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 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