kameleon 0.0.8 → 0.0.9
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/lib/kameleon.rb +16 -1
- data/lib/kameleon/dsl/act.rb +24 -12
- data/lib/kameleon/dsl/see.rb +15 -4
- data/lib/kameleon/session/capybara.rb +2 -25
- data/lib/kameleon/session/server.rb +21 -0
- data/lib/kameleon/session/session_pool.rb +45 -0
- data/lib/kameleon/user/abstract.rb +21 -24
- data/lib/kameleon/user/guest.rb +1 -3
- data/lib/kameleon/utils/configuration.rb +15 -0
- data/lib/kameleon/utils/helpers.rb +11 -0
- data/lib/patch/capybara_selenium_driver.rb +7 -0
- data/spec/sample_rack_app/hey.rb +13 -6
- data/spec/spec_helper.rb +26 -1
- data/spec/unit/act/click_spec.rb +1 -1
- data/spec/unit/act/fill_in/attach_file_spec.rb +14 -5
- data/spec/unit/act/fill_in/checkbox_spec.rb +1 -1
- data/spec/unit/act/fill_in/date_ranges_spec.rb +1 -1
- data/spec/unit/act/fill_in/multiple_select_spec.rb +1 -1
- data/spec/unit/act/fill_in/radio_button_spec.rb +1 -1
- data/spec/unit/act/fill_in/select_spec.rb +1 -1
- data/spec/unit/act/fill_in/text_area_spec.rb +1 -1
- data/spec/unit/act/fill_in/text_input_spec.rb +1 -1
- data/spec/unit/act/on_hover_spec.rb +1 -1
- data/spec/unit/dsl/not_see/form_elements/fields/empty_spec.rb +1 -1
- data/spec/unit/dsl/not_see/form_elements/fields/readonly_spec.rb +1 -1
- data/spec/unit/dsl/not_see/form_elements/fields_spec.rb +1 -1
- data/spec/unit/dsl/not_see/form_elements/textareas_spec.rb +1 -1
- data/spec/unit/dsl/not_see/form_elements/texts_spec.rb +1 -1
- data/spec/unit/dsl/not_see/in_scopes_spec.rb +3 -1
- data/spec/unit/dsl/not_see/special_elements/buttons_spec.rb +1 -1
- data/spec/unit/dsl/not_see/special_elements/error_message_for_spec.rb +1 -1
- data/spec/unit/dsl/not_see/special_elements/images_spec.rb +1 -1
- data/spec/unit/dsl/not_see/special_elements/links_spec.rb +1 -1
- data/spec/unit/dsl/not_see/special_elements/ordered_texts_spec.rb +3 -3
- data/spec/unit/dsl/not_see/special_selectors_spec.rb +9 -5
- data/spec/unit/dsl/not_see/texts_spec.rb +1 -1
- data/spec/unit/dsl/see/counted_elements_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/checkboxes_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/fields/disabled_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/fields/empty_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/fields/readonly_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/fields_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/multiple_selects_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/radio_buttons_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/selects_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/textareas_spec.rb +1 -1
- data/spec/unit/dsl/see/form_elements/texts_spec.rb +1 -1
- data/spec/unit/dsl/see/in_scopes_spec.rb +4 -2
- data/spec/unit/dsl/see/special_elements/buttons_spec.rb +1 -1
- data/spec/unit/dsl/see/special_elements/error_message_for_spec.rb +1 -1
- data/spec/unit/dsl/see/special_elements/images_spec.rb +1 -1
- data/spec/unit/dsl/see/special_elements/links_spec.rb +1 -1
- data/spec/unit/dsl/see/special_elements/ordered_texts_spec.rb +3 -3
- data/spec/unit/dsl/see/special_selectors_spec.rb +10 -6
- data/spec/unit/dsl/see/texts_spec.rb +1 -1
- data/spec/unit/guest_spec.rb +8 -4
- data/spec/unit/user_base_spec.rb +6 -8
- metadata +29 -23
data/lib/kameleon.rb
CHANGED
@@ -1,7 +1,22 @@
|
|
1
|
+
require 'kameleon/utils/configuration'
|
2
|
+
require 'kameleon/utils/helpers'
|
3
|
+
|
1
4
|
require 'kameleon/session/capybara'
|
5
|
+
require 'kameleon/session/server'
|
6
|
+
require 'kameleon/session/session_pool'
|
2
7
|
require 'kameleon/dsl/see'
|
3
8
|
require 'kameleon/dsl/act'
|
4
9
|
|
5
10
|
require 'kameleon/user/abstract'
|
6
11
|
require 'kameleon/user/base'
|
7
|
-
require 'kameleon/user/guest'
|
12
|
+
require 'kameleon/user/guest'
|
13
|
+
|
14
|
+
|
15
|
+
module Kameleon
|
16
|
+
extend Utils::Configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
# Set up default configuration for Kameleon
|
20
|
+
Kameleon.configure do |config|
|
21
|
+
config.default_file_path = 'spec/dummy'
|
22
|
+
end
|
data/lib/kameleon/dsl/act.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Kameleon
|
2
2
|
module Dsl
|
3
3
|
module Act
|
4
|
+
include Kameleon::Utils
|
4
5
|
|
5
6
|
def click(*links)
|
6
7
|
links.each do |link|
|
@@ -37,7 +38,7 @@ module Kameleon
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def fill_in(locators)
|
40
|
-
fill(locators)
|
41
|
+
fill(locators) if can_fill?(locators)
|
41
42
|
end
|
42
43
|
|
43
44
|
private
|
@@ -69,27 +70,38 @@ module Kameleon
|
|
69
70
|
|
70
71
|
def can_fill?(locators)
|
71
72
|
locators.values.each do |loc|
|
72
|
-
|
73
|
-
one_or_all(
|
74
|
-
return false if unmodifiable?(
|
73
|
+
selectors = loc.respond_to?(:values) ? loc.values : loc
|
74
|
+
one_or_all(selectors).each do |selector|
|
75
|
+
return false if unmodifiable?(selector)
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
80
|
+
def unmodifiable?(locator)
|
81
|
+
field = session.find_field(locator)
|
82
|
+
case session.driver
|
83
|
+
when Capybara::Selenium::Driver
|
84
|
+
# In driver field attributes - disabled and readonly may be:
|
85
|
+
# 1) string - false or true
|
86
|
+
# 2) nil value
|
87
|
+
return eval(field[:disabled].to_s) || eval(field[:readonly].to_s)
|
88
|
+
when Capybara::RackTest::Driver
|
89
|
+
# In rack field attributes - disabled and readonly may be:
|
90
|
+
# 1) nil value
|
91
|
+
# 2) string - disabled or readonly
|
92
|
+
return field[:disabled] || field[:readonly]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
79
96
|
def get_full_test_asset_path(file_path)
|
80
97
|
if File.file?(file_path)
|
81
98
|
file_path
|
82
|
-
elsif File.file?(
|
83
|
-
|
99
|
+
elsif File.file?(Helpers.default_path_for_file(file_path))
|
100
|
+
Helpers.default_path_for_file(file_path)
|
84
101
|
else
|
85
|
-
raise "Sorry but we didn't found that file in: #{file_path}, neither #{
|
102
|
+
raise "Sorry but we didn't found that file in: #{file_path}, neither #{Helpers.default_path_for_file(file_path)}"
|
86
103
|
end
|
87
104
|
end
|
88
|
-
|
89
|
-
def unmodifiable?(locator)
|
90
|
-
field = session.find_field(locator)
|
91
|
-
field[:readonly] || field[:disabled]
|
92
|
-
end
|
93
105
|
end
|
94
106
|
end
|
95
107
|
end
|
data/lib/kameleon/dsl/see.rb
CHANGED
@@ -27,7 +27,12 @@ module Kameleon
|
|
27
27
|
when :disabled, :readonly
|
28
28
|
one_or_all(locator).each do |selector|
|
29
29
|
see :field => selector
|
30
|
-
session.
|
30
|
+
case session.driver
|
31
|
+
when Capybara::Selenium::Driver
|
32
|
+
session.find_field(selector)[value].should == 'true'
|
33
|
+
when Capybara::RackTest::Driver
|
34
|
+
session.find_field(selector)[value].should ==(value.to_s)
|
35
|
+
end
|
31
36
|
end
|
32
37
|
when :empty
|
33
38
|
one_or_all(locator).each do |selector|
|
@@ -63,13 +68,14 @@ module Kameleon
|
|
63
68
|
one_or_all(locator).each { |text| session.should rspec_world.have_link(text) }
|
64
69
|
end
|
65
70
|
when :ordered
|
71
|
+
#! we should extend this beyond simply text match (allow to pass full xpath)
|
66
72
|
nodes = session.all(:xpath, locator.collect { |n| "//node()[text()= \"#{n}\"]" }.join(' | '))
|
67
73
|
nodes.map(&:text).should == locator
|
68
74
|
else
|
69
75
|
raise("User can not see #{value} - you need to teach him how")
|
70
76
|
end
|
71
77
|
when 'Fixnum'
|
72
|
-
session.should ::Capybara::RSpecMatchers::HaveMatcher.new(*(get_selector(locator) << {
|
78
|
+
session.should ::Capybara::RSpecMatchers::HaveMatcher.new(*(get_selector(locator) << {:count => value}))
|
73
79
|
else
|
74
80
|
session.should rspec_world.have_field(locator, :with => value)
|
75
81
|
end
|
@@ -122,7 +128,12 @@ module Kameleon
|
|
122
128
|
when :readonly
|
123
129
|
one_or_all(locators).each do |selector|
|
124
130
|
see :field => selector
|
125
|
-
session.
|
131
|
+
case session.driver
|
132
|
+
when Capybara::Selenium::Driver
|
133
|
+
session.find_field(selector)[value].should == 'false'
|
134
|
+
when Capybara::RackTest::Driver
|
135
|
+
session.find_field(selector)[value].should rspec_world.be_nil
|
136
|
+
end
|
126
137
|
end
|
127
138
|
when :empty
|
128
139
|
one_or_all(locators).each do |locator|
|
@@ -141,4 +152,4 @@ module Kameleon
|
|
141
152
|
end
|
142
153
|
end
|
143
154
|
end
|
144
|
-
end
|
155
|
+
end
|
@@ -1,13 +1,10 @@
|
|
1
1
|
module Kameleon
|
2
2
|
module Session
|
3
3
|
module Capybara
|
4
|
-
|
5
|
-
attr_accessor :session_name
|
6
4
|
attr_accessor :driver_name
|
7
5
|
|
8
6
|
def set_session
|
9
|
-
@session =
|
10
|
-
current_session
|
7
|
+
@session = ::SessionPool.session(current_driver)
|
11
8
|
end
|
12
9
|
|
13
10
|
def refresh_page
|
@@ -23,26 +20,6 @@ module Kameleon
|
|
23
20
|
|
24
21
|
private
|
25
22
|
|
26
|
-
def find_or_create_session
|
27
|
-
find_session ||
|
28
|
-
create_session
|
29
|
-
end
|
30
|
-
|
31
|
-
#! in future we should print notice when selected drive is different then session that have been chosen
|
32
|
-
def find_session
|
33
|
-
session_pool[session_name]
|
34
|
-
end
|
35
|
-
|
36
|
-
def create_session
|
37
|
-
::Capybara::Session.new(current_driver, ::Capybara.app).tap do |session|
|
38
|
-
session_pool[session_name] = session
|
39
|
-
end if session_name
|
40
|
-
end
|
41
|
-
|
42
|
-
def session_pool
|
43
|
-
::Capybara.send(:session_pool)
|
44
|
-
end
|
45
|
-
|
46
23
|
def current_session
|
47
24
|
::Capybara.current_session
|
48
25
|
end
|
@@ -51,6 +28,6 @@ module Kameleon
|
|
51
28
|
driver_name ||
|
52
29
|
::Capybara.current_driver
|
53
30
|
end
|
54
|
-
|
31
|
+
end
|
55
32
|
end
|
56
33
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module Kameleon
|
3
|
+
module Session
|
4
|
+
class Server
|
5
|
+
include ::Singleton
|
6
|
+
class << self
|
7
|
+
def server(app)
|
8
|
+
@server ||= start_new_server(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def start_new_server(app)
|
14
|
+
rack_server = ::Capybara::Server.new(app)
|
15
|
+
rack_server.boot
|
16
|
+
rack_server
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
class SessionPool
|
3
|
+
include Singleton
|
4
|
+
class << self
|
5
|
+
attr_writer :nice
|
6
|
+
def session(driver)
|
7
|
+
take_idle(driver) || create(driver)
|
8
|
+
end
|
9
|
+
|
10
|
+
def release_all
|
11
|
+
idle.concat(busy)
|
12
|
+
busy.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def idle
|
18
|
+
@idle ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def busy
|
22
|
+
@busy ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def take_idle(driver)
|
26
|
+
if session = find_idle(driver)
|
27
|
+
session.reset!
|
28
|
+
session.tap do |s|
|
29
|
+
idle.delete(s)
|
30
|
+
busy.push(s)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_idle(driver)
|
36
|
+
idle.detect { |session| session.mode == driver }
|
37
|
+
end
|
38
|
+
|
39
|
+
def create(driver)
|
40
|
+
::Capybara::Session.new(driver, ::Capybara.app).tap do |session|
|
41
|
+
busy.push(session)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -18,21 +18,24 @@ module Kameleon
|
|
18
18
|
def within(*args)
|
19
19
|
new_scope = if args.size == 1 && Capybara::Node::Base === args.first
|
20
20
|
args.first
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
elsif args.last == :select_multiple
|
22
|
+
case driver
|
23
|
+
when Capybara::Selenium::Driver
|
24
|
+
raise "So far Unsupported in this driver"
|
25
|
+
when Capybara::RackTest::Driver
|
26
|
+
node = find(*args)
|
27
|
+
native = Nokogiri::HTML.parse(html).xpath(args[1])
|
28
|
+
base = Capybara::RackTest::Node.new(driver, native)
|
29
|
+
::Capybara::Node::Element.new(self,
|
30
|
+
base,
|
31
|
+
node.parent,
|
32
|
+
node.instance_variable_get(:@selector))
|
32
33
|
end
|
34
|
+
else
|
35
|
+
find(*args)
|
33
36
|
end
|
34
37
|
begin
|
35
|
-
scopes.push(new_scope)
|
38
|
+
scopes.push(*new_scope)
|
36
39
|
yield
|
37
40
|
ensure
|
38
41
|
scopes.pop
|
@@ -102,25 +105,24 @@ module Kameleon
|
|
102
105
|
if (selector.is_a?(Array) && selector.size == 1)
|
103
106
|
selector = selector.first
|
104
107
|
end
|
105
|
-
case selector
|
106
|
-
when
|
108
|
+
case selector
|
109
|
+
when Hash
|
107
110
|
selector.each_pair do |key, value|
|
108
111
|
case key
|
109
112
|
when :row
|
110
113
|
return [:xpath, "//tr[*='#{value}'][1]"]
|
111
114
|
when :column
|
112
|
-
position =
|
113
|
-
|
114
|
-
return [:xpath, "//table//th[#{position + 1}] | //table//td[#{position + 1}]", :select_multiple]
|
115
|
+
position = session.all(:xpath, "//table//th").index { |n| n.text =~ /#{value}/ }
|
116
|
+
return [:xpath, ".//table//th[#{position + 1}] | .//table//td[#{position + 1}]", :select_multiple]
|
115
117
|
else
|
116
118
|
raise "not supported selectors"
|
117
119
|
end
|
118
120
|
end
|
119
|
-
when
|
121
|
+
when Symbol
|
120
122
|
page_areas[selector].is_a?(Array) ?
|
121
123
|
page_areas[selector] :
|
122
124
|
[Capybara.default_selector, page_areas[selector]]
|
123
|
-
when
|
125
|
+
when Array
|
124
126
|
selector
|
125
127
|
else
|
126
128
|
[Capybara.default_selector, selector]
|
@@ -131,11 +133,6 @@ module Kameleon
|
|
131
133
|
page_areas[:main]
|
132
134
|
end
|
133
135
|
|
134
|
-
#! rails dependency
|
135
|
-
def default_files_path
|
136
|
-
::Rails.root.join('spec')
|
137
|
-
end
|
138
|
-
|
139
136
|
def one_or_all(elements)
|
140
137
|
elements.is_a?(Array) ? elements : [elements]
|
141
138
|
end
|
data/lib/kameleon/user/guest.rb
CHANGED
data/spec/sample_rack_app/hey.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
class Hey
|
2
|
-
def initialize(filename = 'default')
|
3
|
-
@body = get_body(filename)
|
4
|
-
end
|
5
|
-
|
6
2
|
def call(env)
|
7
|
-
[
|
3
|
+
if env["PATH_INFO"] == "/"
|
4
|
+
[200, {"Content-Type" => "text"}, ['welcome on homepage']]
|
5
|
+
else
|
6
|
+
[200, {"Content-Type" => "text/html"}, [get_body(env['PATH_INFO'])]]
|
7
|
+
end
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def get_body(filename)
|
13
|
-
File.open(
|
13
|
+
file = File.open(file_path(filename))
|
14
|
+
body = file.read
|
15
|
+
file.close
|
16
|
+
body
|
14
17
|
rescue
|
15
18
|
filename
|
16
19
|
end
|
20
|
+
|
21
|
+
def file_path(filename)
|
22
|
+
File.dirname(__FILE__) + "/../dummy/#{filename}"
|
23
|
+
end
|
17
24
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,15 +2,40 @@ require 'kameleon'
|
|
2
2
|
require 'capybara/dsl'
|
3
3
|
require 'capybara/rspec/matchers'
|
4
4
|
|
5
|
+
require 'capybara/selenium/driver'
|
6
|
+
# one server on all sessions for selenium
|
7
|
+
# require 'patch/capybara_selenium_driver'
|
8
|
+
require 'headless'
|
9
|
+
|
5
10
|
Dir["#{File.expand_path("../", __FILE__)}/support/**/*.rb"].each { |f| require f }
|
6
11
|
|
7
12
|
require 'sample_rack_app/hey'
|
8
13
|
|
9
14
|
RSpec.configure do |config|
|
15
|
+
config.before(:suite) do
|
16
|
+
@headless = Headless.new(:display => '100')
|
17
|
+
@headless.start
|
18
|
+
end
|
19
|
+
|
10
20
|
config.before(:all) do
|
11
21
|
DeferredGarbageCollection.start
|
12
22
|
end
|
23
|
+
|
24
|
+
config.after(:each) do
|
25
|
+
::SessionPool.release_all
|
26
|
+
end
|
27
|
+
|
13
28
|
config.after(:all) do
|
14
29
|
DeferredGarbageCollection.reconsider
|
15
30
|
end
|
16
|
-
|
31
|
+
|
32
|
+
config.after(:suite) do
|
33
|
+
@headless.stop if defined?(@headless)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Capybara.app = Hey.new
|
38
|
+
|
39
|
+
Capybara.configure do |c|
|
40
|
+
c.default_driver= (ENV['CAPYBARA_DEFAULT_DRIVER']||:rack_test).to_sym
|
41
|
+
end
|