jury 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.
- data/bin/jury +4 -0
- data/lib/jury.rb +5 -0
- data/lib/jury/command_line_interface.rb +56 -0
- data/lib/jury/tchk.rb +26 -0
- data/template/config-example.rb +10 -0
- data/template/jury.rb +47 -0
- data/template/lib/helper.rb +20 -0
- data/template/lib/helpers/home_page_helper.rb +9 -0
- data/template/lib/page_object.rb +62 -0
- data/template/lib/path_to_helper_mapper.rb +76 -0
- data/template/url-mappings.yaml +1 -0
- metadata +62 -0
data/bin/jury
ADDED
data/lib/jury.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'jury/tchk'
|
3
|
+
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
$VALID_COMMANDS = %w[help init]
|
7
|
+
|
8
|
+
|
9
|
+
module Jury
|
10
|
+
class CommandLineInterface
|
11
|
+
include Jury::Tchk
|
12
|
+
|
13
|
+
def create_filesystem # CB(2), BB(4)
|
14
|
+
# PRECONDITION -- current_directory not inside/under template_directory
|
15
|
+
current_directory = Dir.pwd
|
16
|
+
template_directory = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'template'))
|
17
|
+
set_of_files = Dir.glob(File.join(template_directory, "*"))
|
18
|
+
FileUtils.cp_r set_of_files, current_directory
|
19
|
+
|
20
|
+
# The above copy will not create empty directories, it seems. Either that,
|
21
|
+
# or gem metadata refuses to accept that an empty template/spec directory
|
22
|
+
# holds value to me. To work around this problem, we will need to create
|
23
|
+
# this directory manually if it doesn't already exist.
|
24
|
+
spec_directory = File.join(current_directory, "spec")
|
25
|
+
FileUtils.mkdir(spec_directory) if !File.directory?(spec_directory)
|
26
|
+
end
|
27
|
+
|
28
|
+
def show_help_message # BB(3,1), BB(3,3)
|
29
|
+
puts <<EOM
|
30
|
+
USAGE: #{@argv[0]} <command> <...>
|
31
|
+
|
32
|
+
Commands supported includes:
|
33
|
+
init - initialize a new Jury instance.
|
34
|
+
help - show this message.
|
35
|
+
EOM
|
36
|
+
end
|
37
|
+
|
38
|
+
def main(argv) # US(3)
|
39
|
+
type_error if !is_array_of_T(argv, String, 1)
|
40
|
+
|
41
|
+
@argv = argv
|
42
|
+
if !argv[1].nil? then
|
43
|
+
command = argv[1].downcase
|
44
|
+
else
|
45
|
+
command = 'help'
|
46
|
+
end
|
47
|
+
|
48
|
+
case command
|
49
|
+
when 'init'
|
50
|
+
create_filesystem # BB(3,2)
|
51
|
+
else
|
52
|
+
show_help_message # BB(3,1) /\ BB(3,3)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/jury/tchk.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Jury
|
2
|
+
module Tchk
|
3
|
+
def type_error
|
4
|
+
raise Exception.new, "Type error"
|
5
|
+
end
|
6
|
+
|
7
|
+
def is_string(s)
|
8
|
+
return s.kind_of?(String)
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_array_of_T(ary, type = nil, minimum_length = 0)
|
12
|
+
is_an_array = ary.kind_of?(Array)
|
13
|
+
|
14
|
+
if !type.nil? then
|
15
|
+
type_error if !type.kind_of?(Class)
|
16
|
+
all_elements_of_type = ary.all? { |e| e.kind_of?(type) }
|
17
|
+
else
|
18
|
+
all_elements_of_type = true
|
19
|
+
end
|
20
|
+
|
21
|
+
minimum_length_met = ary.size >= minimum_length
|
22
|
+
|
23
|
+
return is_an_array && all_elements_of_type && minimum_length_met
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This setting determines the web app installation's first page. When in-
|
2
|
+
# stantiating HomePage.new, the browser will open this URL.
|
3
|
+
|
4
|
+
$home_page = "http://staging.example.com:3000"
|
5
|
+
|
6
|
+
# If you defined a User class for your web-app, and you needed a globally de-
|
7
|
+
# fined user, e.g., for an administrator account, you could define it like
|
8
|
+
# this.
|
9
|
+
#
|
10
|
+
# $admin_user = User.new(:email => "sysop", :password => "sysop-password")
|
data/template/jury.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Include Capybara DSL
|
2
|
+
|
3
|
+
require 'capybara/rspec'
|
4
|
+
include Capybara::DSL
|
5
|
+
|
6
|
+
# Support for multiple, concurrently-running Jury instances.
|
7
|
+
|
8
|
+
begin
|
9
|
+
e = ENV['CAPYBARA_PORT_OFFSET'].to_i
|
10
|
+
rescue
|
11
|
+
e = 0
|
12
|
+
end
|
13
|
+
Capybara.server_port = 8800 + e
|
14
|
+
|
15
|
+
# Include commonly used testing tools
|
16
|
+
|
17
|
+
require 'lib/page_object'
|
18
|
+
require 'lib/helper'
|
19
|
+
require 'lib/user'
|
20
|
+
require 'lib/credit_card'
|
21
|
+
|
22
|
+
# Make all the available helpers known to Jury.
|
23
|
+
|
24
|
+
Dir["lib/helpers/*_helper.rb"].each {|file| require file}
|
25
|
+
|
26
|
+
# Import all of our configuration settings.
|
27
|
+
|
28
|
+
unless ENV['JURY_CONFIG'] then
|
29
|
+
puts <<-EOH
|
30
|
+
|
31
|
+
You must define the JURY_CONFIG environment variable first. This environment
|
32
|
+
variable refers to a specific configuration file. For example, if you have a
|
33
|
+
configuration file named config-beta.rb inside your Jury project's directory,
|
34
|
+
then you can invoke your tests like so:
|
35
|
+
|
36
|
+
JURY_CONFIG=config-beta rspec -I. # ...etc...
|
37
|
+
|
38
|
+
Similarly, if you have a configuration located outside of the Jury project's
|
39
|
+
directory, you can invoke as follows:
|
40
|
+
|
41
|
+
JURY_CONFIG=/tmp/my_config.rb rspec -I. # ..etc..
|
42
|
+
|
43
|
+
EOH
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
require ENV['JURY_CONFIG']
|
47
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Responsibilities
|
2
|
+
#
|
3
|
+
# - Maintain state common to all Helper classes.
|
4
|
+
|
5
|
+
class Helper
|
6
|
+
def initialize(args={})
|
7
|
+
args.should be_kind_of(Hash)
|
8
|
+
|
9
|
+
@session = nil
|
10
|
+
if args[:session] then
|
11
|
+
@session = args[:session]
|
12
|
+
@session.should be_kind_of(Capybara::Session)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_home_page?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Responsibilities
|
2
|
+
# - Visit URL
|
3
|
+
# - Detect and handle redirects
|
4
|
+
# - Proxy undefined methods to the appropriate helper class
|
5
|
+
# - Return current session URL
|
6
|
+
|
7
|
+
require 'lib/path_to_helper_mapper'
|
8
|
+
|
9
|
+
class PageObject
|
10
|
+
attr_reader :session
|
11
|
+
|
12
|
+
def initialize(args)
|
13
|
+
@session = nil
|
14
|
+
@helper = nil
|
15
|
+
@pthm = PathToHelperMapper.new(args)
|
16
|
+
|
17
|
+
if args[:session] then
|
18
|
+
@session = args[:session]
|
19
|
+
@session.should be_kind_of(Capybara::Session)
|
20
|
+
end
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit(url)
|
26
|
+
url.should be_kind_of(String)
|
27
|
+
url.size.should > 0
|
28
|
+
|
29
|
+
@session.visit(url)
|
30
|
+
choose_helper
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def current_url_without_query_parameters
|
35
|
+
@session.current_url.split(/\?/).first
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(msg, *args, &blk)
|
39
|
+
results = @helper.send(msg, *args, &blk)
|
40
|
+
choose_helper
|
41
|
+
return results
|
42
|
+
end
|
43
|
+
|
44
|
+
def have_content?(text)
|
45
|
+
@session.have_content?(text)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def choose_helper
|
51
|
+
@helper = @pthm.helper_for_path(@session.current_path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Convenience class
|
57
|
+
class HomePage < PageObject
|
58
|
+
def initialize
|
59
|
+
super(:session => page, :map_filename => "url-mappings.yaml").visit($home_page)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Responsibilities:
|
2
|
+
# - Translate URL to helper object
|
3
|
+
# - Configure set of mappings used in aforementioned translation.
|
4
|
+
|
5
|
+
require 'rspec/expectations'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
include RSpec::Matchers
|
9
|
+
|
10
|
+
class String
|
11
|
+
def starts_with?(prefix)
|
12
|
+
self[0..prefix.size-1].eql?(prefix)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class PathToHelperMapper
|
17
|
+
def initialize(args={})
|
18
|
+
args.should be_kind_of(Hash)
|
19
|
+
|
20
|
+
@session = nil
|
21
|
+
if args[:session] then
|
22
|
+
@session = args[:session]
|
23
|
+
@session.should be_kind_of(Capybara::Session)
|
24
|
+
end
|
25
|
+
|
26
|
+
if args[:map_filename] then
|
27
|
+
map_filename = args[:map_filename]
|
28
|
+
map_filename.should be_kind_of(String)
|
29
|
+
map_filename.size.should > 0
|
30
|
+
mappings = File.open(map_filename, "r").read
|
31
|
+
end
|
32
|
+
|
33
|
+
if args[:map_file] then
|
34
|
+
map_file = args[:map_file]
|
35
|
+
map_file.should be_kind_of(File)
|
36
|
+
mappings = map_file.read
|
37
|
+
end
|
38
|
+
|
39
|
+
if args[:mappings] then
|
40
|
+
mappings = args[:mappings]
|
41
|
+
mappings.should be_kind_of(String)
|
42
|
+
end
|
43
|
+
|
44
|
+
mappings.should_not be_nil
|
45
|
+
|
46
|
+
@prefix_mapping = YAML.load(mappings)
|
47
|
+
@memo = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def helper_for_path(p)
|
51
|
+
p.should be_kind_of(String)
|
52
|
+
|
53
|
+
class_name = helper_class_for_path(p)
|
54
|
+
class_object = Kernel.const_get("Helpers").const_get(class_name)
|
55
|
+
@memo[class_object] = class_object.new(:session => @session) if @memo[class_object].nil?
|
56
|
+
return @memo[class_object]
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def helper_class_for_path(p)
|
62
|
+
# Normalize URL to eliminate special cases.
|
63
|
+
p = '/' if p.size == 0
|
64
|
+
|
65
|
+
# Find all helpers that could potentially service the URL we're on.
|
66
|
+
class_mapping = @prefix_mapping.select{|k,_| p.starts_with?(k)}
|
67
|
+
|
68
|
+
# Choose the most specific handler (based on URL longest-prefix match).
|
69
|
+
class_mapping = class_mapping.sort {|a,b| b.first.size <=> a.first.size}
|
70
|
+
|
71
|
+
# Return the helper's class name.
|
72
|
+
class_name = class_mapping.first[1]
|
73
|
+
class_name.should be_kind_of(String)
|
74
|
+
return class_name
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
"/": HomePageHelper
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jury
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Samuel A. Falvo II
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'A minimalist acceptance testing framework using page object pattern. It
|
15
|
+
|
16
|
+
greatly simplifies the task of constructing, using, and maintaining page
|
17
|
+
|
18
|
+
objects in a Ruby/Capybara/RSpec environment.
|
19
|
+
|
20
|
+
'
|
21
|
+
email: kc5tja@arrl.net
|
22
|
+
executables:
|
23
|
+
- jury
|
24
|
+
extensions: []
|
25
|
+
extra_rdoc_files: []
|
26
|
+
files:
|
27
|
+
- lib/jury.rb
|
28
|
+
- lib/jury/command_line_interface.rb
|
29
|
+
- lib/jury/tchk.rb
|
30
|
+
- bin/jury
|
31
|
+
- template/config-example.rb
|
32
|
+
- template/jury.rb
|
33
|
+
- template/lib/helper.rb
|
34
|
+
- template/lib/helpers/home_page_helper.rb
|
35
|
+
- template/lib/page_object.rb
|
36
|
+
- template/lib/path_to_helper_mapper.rb
|
37
|
+
- template/url-mappings.yaml
|
38
|
+
homepage: http://github.com/plumdistrict/jury
|
39
|
+
licenses: []
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.17
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: A minimalist acceptance testing framework using page object pattern.
|
62
|
+
test_files: []
|