system_tester 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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +63 -0
- data/Rakefile +36 -0
- data/app/controllers/system_tester/application_controller.rb +15 -0
- data/app/controllers/system_tester/features_controller.rb +46 -0
- data/app/controllers/system_tester/scenario_steps_controller.rb +42 -0
- data/app/controllers/system_tester/scenarios_controller.rb +60 -0
- data/app/controllers/system_tester/step_types_controller.rb +13 -0
- data/app/controllers/system_tester/steps_controller.rb +53 -0
- data/app/jobs/system_tester/application_job.rb +4 -0
- data/app/models/concerns/system_tester/title_validatable.rb +10 -0
- data/app/models/system_tester/action.rb +19 -0
- data/app/models/system_tester/application_record.rb +6 -0
- data/app/models/system_tester/assert_selector.rb +26 -0
- data/app/models/system_tester/assert_text.rb +21 -0
- data/app/models/system_tester/assertion.rb +19 -0
- data/app/models/system_tester/click_on.rb +21 -0
- data/app/models/system_tester/feature.rb +34 -0
- data/app/models/system_tester/fill_in.rb +26 -0
- data/app/models/system_tester/scenario.rb +33 -0
- data/app/models/system_tester/scenario_step.rb +7 -0
- data/app/models/system_tester/step.rb +72 -0
- data/app/models/system_tester/visit.rb +48 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20170513131150_create_system_tester_features.rb +9 -0
- data/db/migrate/20170513213953_create_system_tester_scenarios.rb +10 -0
- data/db/migrate/20170513214255_create_system_tester_steps.rb +12 -0
- data/db/migrate/20170513214722_create_system_tester_scenario_steps.rb +11 -0
- data/db/schema.rb +22 -0
- data/lib/system_tester.rb +7 -0
- data/lib/system_tester/engine.rb +18 -0
- data/lib/system_tester/version.rb +3 -0
- data/lib/tasks/system_tester_tasks.rake +5 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5862dcbf455b9400583a3a11b2f067419eeb1e1a
|
4
|
+
data.tar.gz: c3ebf5bbc31937114ac15166e1f2eb347f6e5577
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a1a61db164dfa2e7ba2d87bffa48b92bd9964e5118cc2a92b843b4df55bab7964a63e58a113b66c63ab4671ed5b3fbfff70993da1de738225ec5a064d0dff49
|
7
|
+
data.tar.gz: 6d606dfdf8706b614a7e3a31718580e18008c4fc4eb76288f99fc718e64937aeb028549538e9a9c76fee754ac1857dda321ac0fb0c204b7418578771944eb6f7
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Richard LaFranchi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# System Tester
|
2
|
+
A development tool for creating and managing system tests in Ruby on Rails >= 5.1 applications
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
This gem is used only in development and is a mountable rails engine that creates JSON endpoints for a chrome extension.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'system_tester', group: :development
|
12
|
+
```
|
13
|
+
|
14
|
+
Add the system_tester db to `config/database.yml`
|
15
|
+
```yml
|
16
|
+
# you may want to consider a shared MySQL/Postgres database
|
17
|
+
# if you have a team that needs shared access
|
18
|
+
system_tester:
|
19
|
+
<<: *default
|
20
|
+
database: db/system_tester.sqlite3
|
21
|
+
```
|
22
|
+
|
23
|
+
And then install and run the migrations:
|
24
|
+
```bash
|
25
|
+
$ bundle install
|
26
|
+
$ RAILS_ENV=system_tester rails db:migrate
|
27
|
+
```
|
28
|
+
|
29
|
+
Mount the engine in config/routes.rb:
|
30
|
+
```ruby
|
31
|
+
Rails.application.routes.draw do
|
32
|
+
# ... other routes
|
33
|
+
|
34
|
+
# Mount in development environment only
|
35
|
+
if Rails.env.devolpment?
|
36
|
+
mount SystemTester::Engine => "/system_tester"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Start your dev server and you are good to go.
|
42
|
+
|
43
|
+
## Chrome extension
|
44
|
+
The chrome extension provides a Devtools tab and acts as a client to this gem.
|
45
|
+
|
46
|
+
IN DEVELOPMENT - to request access feel free to dm on twitter @ralafranchi.
|
47
|
+
|
48
|
+
## Design
|
49
|
+
System Tester is designed to work with a chrome extension, but could potentially be used for other applications as well.
|
50
|
+
Run `rails routes` to see what endpoints are provided. The following design was set in place for the easy of reusing
|
51
|
+
testing steps:
|
52
|
+
|
53
|
+
* Features - the top level: one test script for a feature
|
54
|
+
* Scenarios - 1:M assocation from Feature to Scenario. A Scenario is one test method.
|
55
|
+
* Steps - Basically a line of code that can be an action or an assertion. STI is used to provide different step types.
|
56
|
+
* ScenarioSteps - M:M assocation for Steps and Scenarios which also as a position attribute to allow for reordering.
|
57
|
+
* Stairs - TODO - an ordered group of steps that can be reused.
|
58
|
+
|
59
|
+
## License
|
60
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
61
|
+
|
62
|
+
## TODOS
|
63
|
+
* File management and hooks to create the scripts. To get the code for a feature you can call `to_s` on it.
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'SystemTester'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task default: :test
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class ApplicationController < ActionController::API
|
3
|
+
# protect_from_forgery with: :exception
|
4
|
+
# before_action :set_headers
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def set_headers
|
9
|
+
headers['Access-Control-Allow-Origin'] = 'http://localhost:8080'
|
10
|
+
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
|
11
|
+
headers['Access-Control-Request-Method'] = '*'
|
12
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_dependency "system_tester/application_controller"
|
2
|
+
|
3
|
+
module SystemTester
|
4
|
+
class FeaturesController < ApplicationController
|
5
|
+
def index
|
6
|
+
render json: Feature.all.to_json(feature_json_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
feature = Feature.new(feature_params)
|
11
|
+
if feature.save
|
12
|
+
render json: feature.to_json(feature_json_options)
|
13
|
+
else
|
14
|
+
render json: { errors: feature.errors }, status: :unprocessable_entity
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def update
|
19
|
+
feature = Feature.find(params[:id])
|
20
|
+
if feature.update(feature_params)
|
21
|
+
render json: feature.to_json(feature_json_options)
|
22
|
+
else
|
23
|
+
render json: { errors: feature.errors }, status: :unprocessable_entity
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy
|
28
|
+
Feature.find(params[:id]).destroy!
|
29
|
+
render head: :ok
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def feature_params
|
35
|
+
params.require(:feature).permit(:title)
|
36
|
+
end
|
37
|
+
|
38
|
+
def feature_json_options
|
39
|
+
{
|
40
|
+
methods: [:to_s],
|
41
|
+
include: :scenarios
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_dependency "system_tester/application_controller"
|
2
|
+
|
3
|
+
module SystemTester
|
4
|
+
class ScenarioStepsController < ApplicationController
|
5
|
+
|
6
|
+
def create
|
7
|
+
scenario_step = ScenarioStep.new(scenario_step_params)
|
8
|
+
if scenario_step.save
|
9
|
+
render json: scenario_step.to_json(scenario_step_json_options)
|
10
|
+
else
|
11
|
+
render json: { errors: scenario_step.errors }, status: :unprocessable_entity
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
scenario_step = ScenarioStep.find(params[:id])
|
17
|
+
if scenario_step.update(scenario_step_params)
|
18
|
+
render json: scenario_step.to_json(scenario_step_json_options)
|
19
|
+
else
|
20
|
+
render json: { errors: scenario_step.errors }, status: :unprocessable_entity
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
ScenarioStep.find(params[:id]).destroy!
|
26
|
+
render head: :ok
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def scenario_step_params
|
32
|
+
params.require(:scenario_step).permit(:position, :system_tester_step_id, :system_tester_scenario_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def scenario_step_json_options
|
36
|
+
{
|
37
|
+
include: :step
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_dependency "system_tester/application_controller"
|
2
|
+
|
3
|
+
module SystemTester
|
4
|
+
class ScenariosController < ApplicationController
|
5
|
+
def index
|
6
|
+
render json: Scenario.all.to_json(scenario_json_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
scenario = Scenario.find(params[:id])
|
11
|
+
render json: scenario.to_json(scenario_json_options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
scenario = Scenario.new(scenario_params)
|
16
|
+
if scenario.save
|
17
|
+
render json: scenario.to_json(scenario_json_options)
|
18
|
+
else
|
19
|
+
render json: { errors: scenario.errors }, status: :unprocessable_entity
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def update
|
24
|
+
scenario = Scenario.find(params[:id])
|
25
|
+
if scenario.update(scenario_params)
|
26
|
+
render json: scenario.to_json(scenario_json_options)
|
27
|
+
else
|
28
|
+
render json: { errors: scenario.errors }, status: :unprocessable_entity
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
Scenario.find(params[:id]).destroy!
|
34
|
+
render head: :ok
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def scenario_params
|
40
|
+
params.require(:scenario).permit(:title, :system_tester_feature_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def scenario_json_options
|
44
|
+
{
|
45
|
+
include: {
|
46
|
+
scenario_steps: {
|
47
|
+
include: {
|
48
|
+
step: {
|
49
|
+
methods: [:friendly_type, :parent_type, :bg_css, :text_css, :icon]
|
50
|
+
}
|
51
|
+
}
|
52
|
+
},
|
53
|
+
feature: {}
|
54
|
+
},
|
55
|
+
methods: [:to_s]
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_dependency "system_tester/application_controller"
|
2
|
+
|
3
|
+
module SystemTester
|
4
|
+
class StepsController < ApplicationController
|
5
|
+
def index
|
6
|
+
render json: Step.all.to_json(step_json_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
render json: Step.find(params[:id]).to_json(step_json_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
render json: Step.new(step_params).to_json(step_json_options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
step = Step.new(step_params)
|
19
|
+
if step.save
|
20
|
+
render json: step.to_json(step_json_options)
|
21
|
+
else
|
22
|
+
render json: { errors: step.errors }, status: :unprocessable_entity
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
step = Step.find(params[:id])
|
28
|
+
if step.update(step_params)
|
29
|
+
render json: step.to_json(step_json_options)
|
30
|
+
else
|
31
|
+
render json: { errors: step.errors }, status: :unprocessable_entity
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
Step.find(params[:id]).destroy!
|
37
|
+
render head: :ok
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def step_params
|
43
|
+
params.require(:step).permit(:title, :type, :arg_one, :arg_two)
|
44
|
+
end
|
45
|
+
|
46
|
+
def step_json_options
|
47
|
+
{
|
48
|
+
methods: [:type, :friendly_type, :parent_type, :to_s, :bg_css, :text_css, :icon],
|
49
|
+
include: :scenarios
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Action < Step
|
3
|
+
def to_s
|
4
|
+
"#{INDENT}# Action: #{title}\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def bg_css
|
8
|
+
"orange"
|
9
|
+
end
|
10
|
+
|
11
|
+
def icon
|
12
|
+
"input"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
%w(click_on fill_in visit).each do |dep|
|
18
|
+
require_dependency "system_tester/#{dep}"
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class AssertSelector < Assertion
|
3
|
+
def to_s
|
4
|
+
"#{super}#{INDENT}assert_selector \"#{arg_one}\", text: \"#{arg_two}\"\n\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.friendly_type
|
8
|
+
"Selector"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.args
|
12
|
+
[
|
13
|
+
{
|
14
|
+
name: 'arg_one',
|
15
|
+
label: 'Selector',
|
16
|
+
type: 'text'
|
17
|
+
},
|
18
|
+
{
|
19
|
+
name: 'arg_two',
|
20
|
+
lable: 'Text',
|
21
|
+
type: 'text'
|
22
|
+
}
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class AssertText < Assertion
|
3
|
+
def to_s
|
4
|
+
"#{super}#{INDENT}assert_text \"#{arg_one}\"\n\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.friendly_type
|
8
|
+
"Text"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.args
|
12
|
+
[
|
13
|
+
{
|
14
|
+
name: 'arg_one',
|
15
|
+
label: 'Text',
|
16
|
+
type: 'text'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Assertion < Step
|
3
|
+
def to_s
|
4
|
+
"#{INDENT}# Assertion: #{title}\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def bg_css
|
8
|
+
"green"
|
9
|
+
end
|
10
|
+
|
11
|
+
def icon
|
12
|
+
"done"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
%w(assert_text assert_selector).each do |dep|
|
18
|
+
require_dependency "system_tester/#{dep}"
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class ClickOn < Action
|
3
|
+
def to_s
|
4
|
+
"#{super}#{INDENT}click_on \"#{arg_one}\"\n\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.friendly_type
|
8
|
+
"Click"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.args
|
12
|
+
[
|
13
|
+
{
|
14
|
+
name: 'arg_one',
|
15
|
+
label: 'Element',
|
16
|
+
type: 'text'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Feature < ApplicationRecord
|
3
|
+
include SystemTester::TitleValidatable
|
4
|
+
validates_uniqueness_of :title
|
5
|
+
|
6
|
+
has_many :scenarios, foreign_key: "system_tester_feature_id", class_name: 'SystemTester::Scenario', dependent: :destroy
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
str = ""
|
10
|
+
str << open
|
11
|
+
str << scenarios.map(&:to_s).join("")
|
12
|
+
str << close
|
13
|
+
str
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def open
|
19
|
+
str = ""
|
20
|
+
str << "require 'application_system_test_case'\n\n"
|
21
|
+
str << "module SystemTester\n"
|
22
|
+
str << " class #{stripped_title.camelize}Test < ApplicationSystemTestCase\n"
|
23
|
+
str
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
" end\nend\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
def stripped_title
|
31
|
+
title.gsub(/\s+/,"")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class FillIn < Action
|
3
|
+
def to_s
|
4
|
+
"#{super}#{INDENT}fill_in \"#{arg_one}\", with: \"#{arg_two}\"\n\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.friendly_type
|
8
|
+
"Fill"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.args
|
12
|
+
[
|
13
|
+
{
|
14
|
+
name: 'arg_one',
|
15
|
+
label: 'Input Label',
|
16
|
+
type: 'text'
|
17
|
+
},
|
18
|
+
{
|
19
|
+
name: 'arg_two',
|
20
|
+
label: 'Text',
|
21
|
+
type: 'text'
|
22
|
+
}
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Scenario < ApplicationRecord
|
3
|
+
include TitleValidatable
|
4
|
+
validates_uniqueness_of :title, scope: :system_tester_feature_id
|
5
|
+
|
6
|
+
INDENT = " " * 4
|
7
|
+
belongs_to :feature, class_name: "SystemTester::Feature", foreign_key: "system_tester_feature_id"
|
8
|
+
has_many :scenario_steps,
|
9
|
+
-> { order 'position asc' },
|
10
|
+
class_name: "SystemTester::ScenarioStep",
|
11
|
+
foreign_key: "system_tester_scenario_id",
|
12
|
+
dependent: :destroy
|
13
|
+
has_many :steps, -> { order 'position asc' }, through: :scenario_steps
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
str = ""
|
17
|
+
str << open
|
18
|
+
str << steps.map(&:to_s).join("")
|
19
|
+
str << close
|
20
|
+
str
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def open
|
26
|
+
"#{INDENT}test \"#{title}\" do\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
def close
|
30
|
+
"#{INDENT}end\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class ScenarioStep < ApplicationRecord
|
3
|
+
belongs_to :step, class_name: "SystemTester::Step", foreign_key: "system_tester_step_id"
|
4
|
+
belongs_to :scenario, class_name: "SystemTester::Scenario", foreign_key: "system_tester_scenario_id"
|
5
|
+
acts_as_list scope: :system_tester_scenario_id
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Step < ApplicationRecord
|
3
|
+
include TitleValidatable
|
4
|
+
validates_uniqueness_of :title, scope: [:type, :arg_one, :arg_two]
|
5
|
+
|
6
|
+
INDENT = " " * 6
|
7
|
+
has_many :scenario_steps,
|
8
|
+
class_name: "SystemTester::ScenarioStep",
|
9
|
+
foreign_key: "system_tester_step_id",
|
10
|
+
dependent: :destroy
|
11
|
+
has_many :scenarios, through: :scenario_steps
|
12
|
+
|
13
|
+
def self.friendly_type
|
14
|
+
name.demodulize
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.parent_type
|
18
|
+
ancestors.fourth.name.demodulize
|
19
|
+
end
|
20
|
+
|
21
|
+
def friendly_type
|
22
|
+
self.class.friendly_type
|
23
|
+
end
|
24
|
+
|
25
|
+
def parent_type
|
26
|
+
self.class.parent_type
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.args
|
30
|
+
[
|
31
|
+
{
|
32
|
+
name: 'arg_one',
|
33
|
+
label: 'One',
|
34
|
+
type: 'text'
|
35
|
+
},
|
36
|
+
{
|
37
|
+
name: 'arg_two',
|
38
|
+
label: 'Two',
|
39
|
+
type: 'text'
|
40
|
+
}
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.leafs
|
45
|
+
(descendants - direct_descendants).map do |desc|
|
46
|
+
{
|
47
|
+
name: desc.to_s,
|
48
|
+
friendly: desc.friendly_type,
|
49
|
+
parent: desc.parent_type,
|
50
|
+
args: desc.args
|
51
|
+
}
|
52
|
+
end.sort_by { |step_type| [step_type[:parent_type], step_type[:friendly]] }
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parent_types
|
56
|
+
direct_descendants.map do |desc|
|
57
|
+
{
|
58
|
+
name: desc.to_s,
|
59
|
+
friendly: desc.friendly_type
|
60
|
+
}
|
61
|
+
end.sort_by { |step_type| step_type[:friendly] }
|
62
|
+
end
|
63
|
+
|
64
|
+
def bg_css
|
65
|
+
"teal"
|
66
|
+
end
|
67
|
+
|
68
|
+
def text_css
|
69
|
+
"white-text"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Visit < Action
|
3
|
+
@@engines = {}
|
4
|
+
|
5
|
+
def to_s
|
6
|
+
"#{super}#{INDENT}visit \"#{arg_one}\"\n\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.args
|
10
|
+
[
|
11
|
+
{
|
12
|
+
name: "arg_one",
|
13
|
+
label: "Path or Url",
|
14
|
+
type: "autocomplete",
|
15
|
+
options: collect_routes(Rails.application.routes.routes)
|
16
|
+
}
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Snatched from action_dispatch/routing/inspector
|
23
|
+
def self.collect_routes(routes)
|
24
|
+
routes.collect do |route|
|
25
|
+
ActionDispatch::Routing::RouteWrapper.new(route)
|
26
|
+
end.reject do |route|
|
27
|
+
route.internal? || route.reqs.starts_with?("system_tester", "SystemTester") || route.verb != "GET"
|
28
|
+
end.collect do |route|
|
29
|
+
collect_engine_routes(route)
|
30
|
+
{
|
31
|
+
name: "#{route.name}_path",
|
32
|
+
value: route.path
|
33
|
+
}
|
34
|
+
end.concat(@@engines.values)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.collect_engine_routes(route)
|
38
|
+
name = route.endpoint
|
39
|
+
return unless route.engine?
|
40
|
+
return if @@engines[name]
|
41
|
+
|
42
|
+
routes = route.rack_app.routes
|
43
|
+
if routes.is_a?(ActionDispatch::Routing::RouteSet)
|
44
|
+
@@engines[name] = collect_routes(routes.routes)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
SystemTester::Engine.routes.draw do
|
2
|
+
resources :features, only: [:index, :create, :update, :destroy]
|
3
|
+
resources :scenarios, only: [:index, :show, :create, :update, :destroy]
|
4
|
+
resources :steps, only: [:index, :show, :new, :create, :update, :destroy]
|
5
|
+
resources :scenario_steps, only: [:create, :update, :destroy]
|
6
|
+
resources :step_types, only: [:index] do
|
7
|
+
collection do
|
8
|
+
get :parents
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateSystemTesterScenarioSteps < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
if Rails.env.system_tester?
|
4
|
+
create_table :system_tester_scenario_steps do |t|
|
5
|
+
t.integer :position
|
6
|
+
t.references :system_tester_step, foreign_key: true
|
7
|
+
t.references :system_tester_scenario, foreign_key: true, index: {name: "index_st_st_scenario_id"}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 20170624013811) do
|
14
|
+
|
15
|
+
create_table "examples", force: :cascade do |t|
|
16
|
+
t.string "title"
|
17
|
+
t.text "comment"
|
18
|
+
t.datetime "created_at", null: false
|
19
|
+
t.datetime "updated_at", null: false
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SystemTester
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace SystemTester
|
4
|
+
config.generators.api_only = true
|
5
|
+
|
6
|
+
initializer :override_db_dir do |app|
|
7
|
+
if Rails.env.system_tester?
|
8
|
+
app.config.paths["db"] = config.paths['db'].expanded
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
config.to_prepare do
|
13
|
+
Dir.glob(SystemTester::Engine.root.join("app", "models" , "**", "*.rb")).each do |dep|
|
14
|
+
require_dependency dep
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: system_tester
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Richard LaFranchi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: acts_as_list
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: System Tester aims to symplify QA for Rails applications by providing
|
56
|
+
a development tool for creating and managing system tests
|
57
|
+
email:
|
58
|
+
- rlafranchi@icloud.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- app/controllers/system_tester/application_controller.rb
|
67
|
+
- app/controllers/system_tester/features_controller.rb
|
68
|
+
- app/controllers/system_tester/scenario_steps_controller.rb
|
69
|
+
- app/controllers/system_tester/scenarios_controller.rb
|
70
|
+
- app/controllers/system_tester/step_types_controller.rb
|
71
|
+
- app/controllers/system_tester/steps_controller.rb
|
72
|
+
- app/jobs/system_tester/application_job.rb
|
73
|
+
- app/models/concerns/system_tester/title_validatable.rb
|
74
|
+
- app/models/system_tester/action.rb
|
75
|
+
- app/models/system_tester/application_record.rb
|
76
|
+
- app/models/system_tester/assert_selector.rb
|
77
|
+
- app/models/system_tester/assert_text.rb
|
78
|
+
- app/models/system_tester/assertion.rb
|
79
|
+
- app/models/system_tester/click_on.rb
|
80
|
+
- app/models/system_tester/feature.rb
|
81
|
+
- app/models/system_tester/fill_in.rb
|
82
|
+
- app/models/system_tester/scenario.rb
|
83
|
+
- app/models/system_tester/scenario_step.rb
|
84
|
+
- app/models/system_tester/step.rb
|
85
|
+
- app/models/system_tester/visit.rb
|
86
|
+
- config/routes.rb
|
87
|
+
- db/migrate/20170513131150_create_system_tester_features.rb
|
88
|
+
- db/migrate/20170513213953_create_system_tester_scenarios.rb
|
89
|
+
- db/migrate/20170513214255_create_system_tester_steps.rb
|
90
|
+
- db/migrate/20170513214722_create_system_tester_scenario_steps.rb
|
91
|
+
- db/schema.rb
|
92
|
+
- lib/system_tester.rb
|
93
|
+
- lib/system_tester/engine.rb
|
94
|
+
- lib/system_tester/version.rb
|
95
|
+
- lib/tasks/system_tester_tasks.rake
|
96
|
+
homepage: http://github.com/rlafranchi/system_tester
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.6.12
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: 'System Tester: Rails Sysyem Test Management'
|
120
|
+
test_files: []
|