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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +107 -1
- data/lib/cypress.rb +6 -5
- data/lib/cypress/callback_server.rb +13 -2
- data/lib/cypress/configuration.rb +4 -0
- data/lib/cypress/scenario_bank.rb +0 -7
- data/lib/cypress/scenario_context.rb +23 -0
- data/lib/cypress/server.rb +26 -19
- data/lib/cypress/version.rb +1 -1
- data/lib/generators/install_generator.rb +26 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 307be16313426be599e503b2612ab3f33c8d4b54
|
4
|
+
data.tar.gz: 81a10e2d6563f57cc3e2a5cb71d0547d2366b278
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baa22d4846debaec324dc1641410a27e523665fea8bcf70624d165955809ec03054acd81564cb3075f6ff6c4ed1b29014fe23746f6bfa0a6f5ab8a0167d2979e
|
7
|
+
data.tar.gz: 2fe3bb98ea96886a22d509a9881127cb10faa505b172734e41993063ebf5d6e9ee128a3bad2ee6884f3dc7e9585ef423ca0019ff5b3568f26805ed99801b0251
|
data/CHANGELOG.md
ADDED
@@ -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
|
data/lib/cypress.rb
CHANGED
@@ -3,11 +3,12 @@ require 'active_support/dependencies/autoload'
|
|
3
3
|
module Cypress
|
4
4
|
extend ActiveSupport::Autoload
|
5
5
|
|
6
|
-
autoload :Server,
|
7
|
-
autoload :CallbackServer,
|
8
|
-
autoload :Runner,
|
9
|
-
autoload :ScenarioBank,
|
10
|
-
autoload :
|
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
|
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
|
@@ -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
|
data/lib/cypress/server.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
52
|
-
require
|
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
|
60
|
-
|
61
|
-
|
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
|
data/lib/cypress/version.rb
CHANGED
@@ -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
|
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.
|
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-
|
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
|