symbiont 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +16 -5
- data/HISTORY.md +6 -0
- data/README.md +23 -1
- data/Rakefile +1 -0
- data/lib/symbiont/enclosers.rb +26 -0
- data/lib/symbiont/factory.rb +33 -0
- data/lib/symbiont/generators.rb +106 -4
- data/lib/symbiont/logger.rb +5 -0
- data/lib/symbiont/platform_watir/platform_object.rb +114 -13
- data/lib/symbiont/platforms.rb +1 -5
- data/lib/symbiont/version.rb +1 -1
- data/lib/symbiont/web_objects/_common.rb +13 -2
- data/lib/symbiont.rb +10 -5
- data/spec/spec_helper.rb +8 -9
- data/spec/symbiont/enclosers_spec.rb +16 -0
- data/spec/symbiont/factory_spec.rb +35 -0
- data/spec/symbiont/generators/button_generators_spec.rb +37 -18
- data/spec/symbiont/generators/link_generators_spec.rb +27 -16
- data/spec/symbiont/generators/text_field_generators_spec.rb +29 -23
- data/spec/symbiont/generators_spec.rb +27 -17
- data/spec/symbiont/platform_object_spec.rb +1 -9
- data/spec/symbiont/symbiont_spec.rb +2 -2
- data/spec/symbiont/web_object_spec.rb +17 -0
- data/symbiont.gemspec +20 -22
- data/test/symbiont_test.rb +158 -0
- metadata +16 -25
- data/lib/symbiont/platform_selenium/platform_object.rb +0 -71
- data/lib/symbiont/platform_selenium.rb +0 -9
- data/test/base.rb +0 -17
- data/test/symbiont_selenium.rb +0 -35
- data/test/symbiont_watir.rb +0 -35
data/.gitignore
CHANGED
@@ -1,10 +1,21 @@
|
|
1
|
-
.bundle/*
|
2
|
-
output/*
|
3
|
-
.idea/*
|
4
|
-
pkg/*
|
5
1
|
*.gem
|
2
|
+
*.rbc
|
6
3
|
*.swo
|
7
4
|
*.swp
|
5
|
+
.bundle
|
6
|
+
.config
|
7
|
+
.yardoc
|
8
8
|
.DS_Store
|
9
9
|
Gemfile.lock
|
10
|
-
|
10
|
+
InstalledFiles
|
11
|
+
_yardoc
|
12
|
+
coverage
|
13
|
+
output/
|
14
|
+
doc/
|
15
|
+
lib/bundler/man
|
16
|
+
pkg
|
17
|
+
rdoc
|
18
|
+
spec/reports
|
19
|
+
test/tmp
|
20
|
+
test/version_tmp
|
21
|
+
tmp
|
data/HISTORY.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
Change Log and History
|
2
2
|
======================
|
3
3
|
|
4
|
+
Version 0.0.3 / 2012-04-11
|
5
|
+
--------------------------
|
6
|
+
|
7
|
+
Symbiont went in a different direction, which is excluding Selenium and focusing on Watir. Watir is simply a cleaner API that makes for a more consistent implementation. The focus here was on getting the basis for the generators and enclosers in place. The idea of page and activity definitions that serve as action contexts was also put in place.
|
8
|
+
|
9
|
+
|
4
10
|
Version 0.0.2 / 2012-03-15
|
5
11
|
--------------------------
|
6
12
|
|
data/README.md
CHANGED
@@ -8,6 +8,20 @@ The Symbiont gem is designed to provide an open framework for running automated
|
|
8
8
|
|
9
9
|
Right now the best information on the purpose of this project and how it works can be found on [my Symbiont-tagged blog posts](http://testerstories.com/?cat=16).
|
10
10
|
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'symbiont'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install symbiont
|
11
25
|
|
12
26
|
Meaning
|
13
27
|
-------
|
@@ -18,8 +32,16 @@ Symbiotic relationships include associations in which one organism lives on anot
|
|
18
32
|
|
19
33
|
So, with that bit of context, think of this gem as a facultative, endosymbiotic organism that lives within your test logic, giving it strength and sustenance.
|
20
34
|
|
35
|
+
Contributing
|
36
|
+
------------
|
37
|
+
|
38
|
+
1. Fork it
|
39
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
41
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
42
|
+
5. Create new Pull Request
|
21
43
|
|
22
44
|
Copyright
|
23
45
|
---------
|
24
46
|
|
25
|
-
See the LICENSE file for details.
|
47
|
+
See the LICENSE file for details.
|
data/Rakefile
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Symbiont
|
2
|
+
module Enclosers
|
3
|
+
|
4
|
+
# Used to identify a web object as existing within an enclosing object
|
5
|
+
# like a frame or an iframe. It is possible to nest by passing in parent
|
6
|
+
# enclosers as the second parameter.
|
7
|
+
#
|
8
|
+
# @param [String] locator how an encloser will be referenced; the
|
9
|
+
# only valid locators here are :id, :index, and :name
|
10
|
+
# @param encloser a parent encloser that is passed from a previous call
|
11
|
+
# @param [optional] block that contains calls to web objects within the
|
12
|
+
# encloser
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# within_frame(id: "loginSection") do |encloser|
|
16
|
+
# text_field :username, id: "userName", frame: encloser
|
17
|
+
# button :login, id: "btnSubmit", frame: encloser
|
18
|
+
# end
|
19
|
+
def within_frame(locator, encloser=nil, &block)
|
20
|
+
encloser = [] if encloser.nil?
|
21
|
+
encloser << locator
|
22
|
+
block.call(encloser)
|
23
|
+
end
|
24
|
+
|
25
|
+
end # module: Enclosers
|
26
|
+
end # module: Symbiont
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Symbiont
|
2
|
+
module Factory
|
3
|
+
|
4
|
+
# Creates a definition context for actions.
|
5
|
+
#
|
6
|
+
# @param [Class] definition The name of a definition class
|
7
|
+
# @param [optional] block Logic to execute within the context of the
|
8
|
+
# definition
|
9
|
+
# @return [Object] instance of the definition
|
10
|
+
def on(definition, &block)
|
11
|
+
@active = definition.new(@browser)
|
12
|
+
block.call @active if block
|
13
|
+
@active
|
14
|
+
end
|
15
|
+
|
16
|
+
# Creates a definition context for actions and establishes the
|
17
|
+
# context for display.
|
18
|
+
#
|
19
|
+
# @param [Class] definition The name of a definition class
|
20
|
+
# @param [optional] block Logic to execute within the context of the
|
21
|
+
# definition
|
22
|
+
# @return [Object] instance of the definition
|
23
|
+
def on_view(definition, &block)
|
24
|
+
@active = definition.new(@browser, true)
|
25
|
+
block.call @active if block
|
26
|
+
@active
|
27
|
+
end
|
28
|
+
|
29
|
+
alias :during :on
|
30
|
+
alias :start_activity :on_view
|
31
|
+
|
32
|
+
end # module: Factory
|
33
|
+
end # module: Symbiont
|
data/lib/symbiont/generators.rb
CHANGED
@@ -28,10 +28,49 @@ module Symbiont
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
# This method allows for a title_is() method in definitions. The idea
|
32
|
+
# is that you can specify the title of a page. This title can then be
|
33
|
+
# checked on. Note that the assumption here is that the title will
|
34
|
+
# be static. The argument to the method can, however, be a
|
35
|
+
# regular expression.
|
36
|
+
#
|
37
|
+
# @param [String] title the literal string of the expected title
|
38
|
+
# @param [Regexp] title the pattern string of the expected title
|
39
|
+
# @return [Nil]
|
40
|
+
# @raise exception if the title found does not match the title expected
|
41
|
+
def title_is(title)
|
42
|
+
define_method('has_title?') do
|
43
|
+
valid_title = title =~ @browser.title if title.kind_of?(Regexp)
|
44
|
+
valid_title = title == @browser.title if title.kind_of?(String)
|
45
|
+
raise "Expected title: '#{title}'; Actual title: '#{@browser.title}'" unless valid_title
|
46
|
+
valid_title
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# This method allows for a look_for() method in definitions. The idea
|
51
|
+
# is that you can specify an object that should appear on a given page
|
52
|
+
# when that page appears.
|
53
|
+
#
|
54
|
+
# @param [Symbol] widget the friendly name of the object declaration
|
55
|
+
# @param [optional, Integer] timeout the time to wait for the object to appear
|
56
|
+
# @return [Boolean] true if object was found
|
57
|
+
def look_for(widget, timeout=5)
|
58
|
+
define_method('has_object?') do
|
59
|
+
if self.respond_to? "#{widget}_object"
|
60
|
+
self.send("#{widget}_object").when_actionable(timeout)
|
61
|
+
else
|
62
|
+
puts "The #{widget} object was not declared and could not be checked."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
31
67
|
# Definition method for links. Methods for the following actions will
|
32
68
|
# be created:
|
33
69
|
# * reference a link (identifier_object, identifier_link)
|
70
|
+
# * check text of link (identifier_text)
|
34
71
|
# * click a link (identifier)
|
72
|
+
# * check for existence (identifier?, identifier_exists?)
|
73
|
+
# * check for visibility (identifier_?, identifier_visible?)
|
35
74
|
# @param [Symbol] identifier the friendly name of the web object
|
36
75
|
# @param [optional, Hash] locator the key/values that identify the object
|
37
76
|
# @return [Object] instance of Symbiont::WebObjects::Link
|
@@ -41,16 +80,36 @@ module Symbiont
|
|
41
80
|
end
|
42
81
|
|
43
82
|
alias_method "#{identifier}_link".to_sym, "#{identifier}_object".to_sym
|
44
|
-
|
83
|
+
|
84
|
+
define_method("#{identifier}_text") do
|
85
|
+
@platform.get_link_text_for(locator.clone)
|
86
|
+
end
|
87
|
+
|
45
88
|
define_method(identifier) do
|
46
89
|
@platform.click_link_for(locator.clone)
|
47
90
|
end
|
91
|
+
|
92
|
+
define_method("#{identifier}_exists?") do
|
93
|
+
@platform.check_link_for_existence(locator.clone)
|
94
|
+
end
|
95
|
+
|
96
|
+
alias_method "#{identifier}?".to_sym, "#{identifier}_exists?".to_sym
|
97
|
+
|
98
|
+
define_method("#{identifier}_visible?") do
|
99
|
+
@platform.check_link_for_visibility(locator.clone)
|
100
|
+
end
|
101
|
+
|
102
|
+
alias_method "#{identifier}_?".to_sym, "#{identifier}_visible?".to_sym
|
48
103
|
end
|
49
104
|
|
50
105
|
# Definition method for buttons. Methods for the following actions will
|
51
106
|
# be created:
|
52
107
|
# * reference a button (identifier_object, identifier_button)
|
108
|
+
# * get text from button (identifier_text)
|
53
109
|
# * click a button (identifier)
|
110
|
+
# * check for existence (identifier?, identifier_exists?)
|
111
|
+
# * check for visibility (identifier_?, identifier_visible?)
|
112
|
+
# * check for enabled (identifier!, identifier_enabled?)
|
54
113
|
# @param [Symbol] identifier the friendly name of the web object
|
55
114
|
# @param [optional, Hash] locator the key/values that identify the object
|
56
115
|
# @return [Object] instance of Symbiont::WebObjects::Button
|
@@ -60,17 +119,42 @@ module Symbiont
|
|
60
119
|
end
|
61
120
|
|
62
121
|
alias_method "#{identifier}_button".to_sym, "#{identifier}_object".to_sym
|
63
|
-
|
122
|
+
|
123
|
+
define_method("#{identifier}_text") do
|
124
|
+
@platform.get_button_text_for(locator.clone)
|
125
|
+
end
|
126
|
+
|
64
127
|
define_method(identifier) do
|
65
128
|
@platform.click_button_for(locator.clone)
|
66
129
|
end
|
130
|
+
|
131
|
+
define_method("#{identifier}_exists?") do
|
132
|
+
@platform.check_button_for_existence(locator.clone)
|
133
|
+
end
|
134
|
+
|
135
|
+
alias_method "#{identifier}?".to_sym, "#{identifier}_exists?".to_sym
|
136
|
+
|
137
|
+
define_method("#{identifier}_visible?") do
|
138
|
+
@platform.check_button_for_visibility(locator.clone)
|
139
|
+
end
|
140
|
+
|
141
|
+
alias_method "#{identifier}_?".to_sym, "#{identifier}_visible?".to_sym
|
142
|
+
|
143
|
+
define_method("#{identifier}_enabled?") do
|
144
|
+
@platform.check_button_for_enabled(locator.clone)
|
145
|
+
end
|
146
|
+
|
147
|
+
alias_method "#{identifier}!".to_sym, "#{identifier}_enabled?".to_sym
|
67
148
|
end
|
68
149
|
|
69
150
|
# Definition method for text fields. Methods for the following actions
|
70
151
|
# will be created:
|
71
|
-
# * reference a text field (identifier_object,
|
152
|
+
# * reference a text field (identifier_object, identifier_text_field)
|
72
153
|
# * get text from a text field (identifier)
|
73
154
|
# * set text in a text field (identifier=)
|
155
|
+
# * check for existence (identifier?, identifier_exists?)
|
156
|
+
# * check for visibility (identifier_?, identifier_visible?)
|
157
|
+
# * check for enabled (identifier!, identifier_enabled?)
|
74
158
|
# @param [Symbol] identifier the friendly name of the web object
|
75
159
|
# @param [optional, Hash] locator the key/values that identify the object
|
76
160
|
# @return [Object] instance of Symbiont::WebObjects::TextField
|
@@ -88,7 +172,25 @@ module Symbiont
|
|
88
172
|
define_method("#{identifier}=") do |value|
|
89
173
|
@platform.set_text_field_value_for(locator.clone, value)
|
90
174
|
end
|
175
|
+
|
176
|
+
define_method("#{identifier}_exists?") do
|
177
|
+
@platform.check_text_field_for_existence(locator.clone)
|
178
|
+
end
|
179
|
+
|
180
|
+
alias_method "#{identifier}?".to_sym, "#{identifier}_exists?".to_sym
|
181
|
+
|
182
|
+
define_method("#{identifier}_visible?") do
|
183
|
+
@platform.check_text_field_for_visibility(locator.clone)
|
184
|
+
end
|
185
|
+
|
186
|
+
alias_method "#{identifier}_?".to_sym, "#{identifier}_visible?".to_sym
|
187
|
+
|
188
|
+
define_method("#{identifier}_enabled?") do
|
189
|
+
@platform.check_text_field_for_enabled(locator.clone)
|
190
|
+
end
|
191
|
+
|
192
|
+
alias_method "#{identifier}!".to_sym, "#{identifier}_enabled?".to_sym
|
91
193
|
end
|
92
194
|
|
93
195
|
end # module: Generators
|
94
|
-
end # module: Symbiont
|
196
|
+
end # module: Symbiont
|
@@ -13,53 +13,154 @@ module Symbiont
|
|
13
13
|
def visit(url)
|
14
14
|
@browser.goto(url)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# Platform method to return a link object.
|
18
18
|
# Link objects are of type: Symbiont::WebObjects::Link
|
19
19
|
# @see Symbiont::Generators#link
|
20
20
|
def get_link_for(locator)
|
21
|
-
|
22
|
-
|
21
|
+
reference_web_object("link(locator)", WebObjects::Link, locator)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Platform method to get text of link object.
|
25
|
+
# @see Symbiont::Generators#link
|
26
|
+
def get_link_text_for(locator)
|
27
|
+
access_web_object("link(locator).text", locator)
|
23
28
|
end
|
24
29
|
|
25
30
|
# Platform method to click a link object.
|
26
31
|
# @see Symbiont::Generators#link
|
27
32
|
def click_link_for(locator)
|
28
|
-
|
33
|
+
access_web_object("link(locator).click", locator)
|
29
34
|
end
|
30
35
|
|
36
|
+
# Platform method to check if link object exists.
|
37
|
+
# @see Symbiont::Generators#link
|
38
|
+
def check_link_for_existence(locator)
|
39
|
+
access_web_object("link(locator).exists?", locator)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Platform method to check if link object is visible.
|
43
|
+
# @see Symbiont::Generators#link
|
44
|
+
def check_link_for_visibility(locator)
|
45
|
+
access_web_object("link(locator).visible?", locator)
|
46
|
+
end
|
47
|
+
|
31
48
|
# Platform method to return a button object.
|
32
49
|
# Button objects are of type: Symbiont::WebObjects::Button
|
33
50
|
# @see Symbiont::Generators#button
|
34
51
|
def get_button_for(locator)
|
35
|
-
|
36
|
-
WebObjects::Button.new()
|
52
|
+
reference_web_object("button(locator)", WebObjects::Button, locator)
|
37
53
|
end
|
38
|
-
|
54
|
+
|
55
|
+
# Platform method to get text of button object.
|
56
|
+
# @see Symbiont::Generators#button
|
57
|
+
def get_button_text_for(locator)
|
58
|
+
access_web_object("button(locator).text", locator)
|
59
|
+
end
|
60
|
+
|
39
61
|
# Platform method to click a button object.
|
40
62
|
# @see Symbiont::Generators#button
|
41
63
|
def click_button_for(locator)
|
42
|
-
|
64
|
+
access_web_object("button(locator).click", locator)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Platform method to check if button object exists.
|
68
|
+
# @see Symbiont::Generators#button
|
69
|
+
def check_button_for_existence(locator)
|
70
|
+
access_web_object("button(locator).exists?", locator)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Platform method to check if button object is visible.
|
74
|
+
# @see Symbiont::Generators#button
|
75
|
+
def check_button_for_visibility(locator)
|
76
|
+
access_web_object("button(locator).visible?", locator)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Platform method to check if button object is enabled.
|
80
|
+
# @see Symbiont::Generators#button
|
81
|
+
def check_button_for_enabled(locator)
|
82
|
+
access_web_object("button(locator).enabled?", locator)
|
43
83
|
end
|
44
84
|
|
45
85
|
# Platform method to return a text field object.
|
46
86
|
# Text field objects are of type: Symbiont::WebObjects::TextField
|
47
87
|
# @see Symbiont::Generators#text_field
|
48
88
|
def get_text_field_for(locator)
|
49
|
-
|
50
|
-
WebObjects::TextField.new()
|
89
|
+
reference_web_object("text_field(locator)", WebObjects::TextField, locator)
|
51
90
|
end
|
52
91
|
|
53
92
|
# Platform method to retrieve text from a text field object.
|
54
93
|
# @see Symbiont::Generators#text_field
|
55
94
|
def get_text_field_value_for(locator)
|
56
|
-
|
95
|
+
access_web_object("text_field(locator).value", locator)
|
57
96
|
end
|
58
97
|
|
59
98
|
# Platform method to enter text into a text field object.
|
60
99
|
# @see Symbiont::Generators#text_field
|
61
100
|
def set_text_field_value_for(locator, value)
|
62
|
-
|
101
|
+
access_web_object("text_field(locator).set(value)", locator, value)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Platform method to check if text field object exists.
|
105
|
+
# @see Symbiont::Generators#text_field
|
106
|
+
def check_text_field_for_existence(locator)
|
107
|
+
access_web_object("text_field(locator).exists?", locator)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Platform method to check if text field object is visible.
|
111
|
+
# @see Symbiont::Generators#text_field
|
112
|
+
def check_text_field_for_visibility(locator)
|
113
|
+
access_web_object("text_field(locator).visible?", locator)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Platform method to check if text field object is enabled.
|
117
|
+
# @see Symbiont::Generators#text_field
|
118
|
+
def check_text_field_for_enabled(locator)
|
119
|
+
access_web_object("text_field(locator).enabled?", locator)
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# This method is called by any platform methods that require getting
|
125
|
+
# an object reference.
|
126
|
+
#
|
127
|
+
# @param [String] action the driver logic to be sent to the browser
|
128
|
+
# @param [Object] object_type the type of web object that will receive the action
|
129
|
+
# @param [Hash] locator the specific web object selector, mainly for parsing
|
130
|
+
# @return [Object] the web object identified by the action
|
131
|
+
def reference_web_object(action, object_type, locator)
|
132
|
+
enclosers = locator.delete(:frame)
|
133
|
+
web_object = @browser.instance_eval "#{enclosed_by(enclosers)}#{action}"
|
134
|
+
object_type.new(web_object)
|
135
|
+
end
|
136
|
+
|
137
|
+
# This method is called by any platform methods that require accessing
|
138
|
+
# a web object with the intent of manipulating it or getting information
|
139
|
+
# from it.
|
140
|
+
#
|
141
|
+
# @param [String] action the driver logic to be sent to the browser
|
142
|
+
# @param [Hash] locator the specific web object selector, mainly for parsing
|
143
|
+
# @param [String] value any specific information that must be sent to the
|
144
|
+
# web object
|
145
|
+
# @return [Any] the information or object returned by the action
|
146
|
+
def access_web_object(action, locator, value=nil)
|
147
|
+
enclosers = locator.delete(:frame)
|
148
|
+
@browser.instance_eval "#{enclosed_by(enclosers)}#{action}"
|
149
|
+
end
|
150
|
+
|
151
|
+
# This method is used to wrap a web object locator within the locator for an
|
152
|
+
# enclosing web object. Currently the only enclosing objects this makes sense
|
153
|
+
# for are iframes and frames.
|
154
|
+
#
|
155
|
+
# @param [Hash] enclosers locator information for enclosing web objects
|
156
|
+
# @return [Hash] driver-specific frame selector
|
157
|
+
def enclosed_by(enclosers)
|
158
|
+
return if enclosers.nil?
|
159
|
+
|
160
|
+
key = enclosers[0].keys.first
|
161
|
+
value = enclosers[0].values.first
|
162
|
+
|
163
|
+
encloser_locator = "frame(:#{key} => '#{value}')."
|
63
164
|
end
|
64
165
|
end # class: PlatformObject
|
65
166
|
|
@@ -67,4 +168,4 @@ module Symbiont
|
|
67
168
|
end # module: Platforms
|
68
169
|
end # module: Symbiont
|
69
170
|
|
70
|
-
Dir["#{File.dirname(__FILE__)}/../web_objects/**/*.rb"].sort.each { |file| require file }
|
171
|
+
Dir["#{File.dirname(__FILE__)}/../web_objects/**/*.rb"].sort.each { |file| require file }
|
data/lib/symbiont/platforms.rb
CHANGED
@@ -2,16 +2,13 @@ module Symbiont
|
|
2
2
|
module Platforms
|
3
3
|
|
4
4
|
require 'watir-webdriver'
|
5
|
-
require 'selenium-webdriver'
|
6
5
|
|
7
6
|
# This module determines what execution platform Symbiont will use.
|
8
7
|
# The decision is based on the browser that has been established for
|
9
|
-
# the execution profile
|
8
|
+
# the execution profile.
|
10
9
|
def get_platform_for(browser)
|
11
10
|
if browser.is_a?(Watir::Browser)
|
12
11
|
return @platform = Symbiont::Platforms::WatirWebDriver::PlatformObject.new(@browser)
|
13
|
-
elsif browser.is_a?(Selenium::WebDriver::Driver)
|
14
|
-
return @platform = Symbiont::Platforms::SeleniumWebDriver::PlatformObject.new(@browser)
|
15
12
|
else
|
16
13
|
raise "Unable to create a platform object for #{browser}"
|
17
14
|
end
|
@@ -21,4 +18,3 @@ module Symbiont
|
|
21
18
|
end # module: Symbiont
|
22
19
|
|
23
20
|
require_relative 'platform_watir'
|
24
|
-
require_relative 'platform_selenium'
|
data/lib/symbiont/version.rb
CHANGED
@@ -2,8 +2,19 @@ module Symbiont
|
|
2
2
|
module WebObjects
|
3
3
|
|
4
4
|
class WebObject
|
5
|
-
|
5
|
+
def initialize(web_object)
|
6
|
+
@web_object = web_object
|
7
|
+
end
|
8
|
+
|
9
|
+
def text
|
10
|
+
@web_object.text
|
11
|
+
end
|
12
|
+
|
13
|
+
def when_actionable(timeout)
|
14
|
+
@web_object.wait_until_present(timeout)
|
15
|
+
self
|
16
|
+
end
|
6
17
|
end # class: WebObject
|
7
18
|
|
8
19
|
end # module: WebObjects
|
9
|
-
end # module: Symbiont
|
20
|
+
end # module: Symbiont
|
data/lib/symbiont.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'symbiont/version'
|
2
|
+
require 'symbiont/logger'
|
2
3
|
require 'symbiont/platforms'
|
3
4
|
require 'symbiont/generators'
|
5
|
+
require 'symbiont/enclosers'
|
4
6
|
|
5
7
|
module Symbiont
|
6
8
|
include Platforms
|
7
|
-
|
9
|
+
|
8
10
|
# Used to make a platform object accessible. Will hold object
|
9
11
|
# references like these:
|
10
12
|
# <Symbiont::Platforms::WatirWebDriver::PlatformObject:0x2cbe8a0>
|
11
|
-
# <Symbiont::Platforms::SeleniumWebDriver::PlatformObject:0x2cb9608>
|
12
13
|
attr_reader :platform
|
13
14
|
|
14
15
|
def self.version
|
@@ -21,8 +22,9 @@ module Symbiont
|
|
21
22
|
# available as class methods. Those methods will be available only in
|
22
23
|
# the context of the class (definition) that included Symbiont.
|
23
24
|
def self.included(caller)
|
24
|
-
|
25
|
+
Symbiont::trace("#{caller.class} #{caller} attached the Symbiont")
|
25
26
|
caller.extend Symbiont::Generators
|
27
|
+
caller.extend Symbiont::Enclosers
|
26
28
|
end
|
27
29
|
|
28
30
|
# The initialize method will be invoked when a page definition includes
|
@@ -32,10 +34,13 @@ module Symbiont
|
|
32
34
|
# (2) A platform object is created for that browser.
|
33
35
|
#
|
34
36
|
# @param [Object] browser a browser instance with a tool driver
|
35
|
-
|
36
|
-
|
37
|
+
# @param [boolean] visit if true, a definition will be navigated to
|
38
|
+
def initialize(browser, visit=nil)
|
39
|
+
Symbiont::trace("Symbiont attached to browser: #{browser}")
|
37
40
|
@browser = browser
|
38
41
|
establish_platform_object_for(browser)
|
42
|
+
view if visit && respond_to?(:view)
|
43
|
+
start if visit && respond_to?(:start)
|
39
44
|
end
|
40
45
|
|
41
46
|
private
|
data/spec/spec_helper.rb
CHANGED
@@ -16,22 +16,21 @@ class DefinitionTest
|
|
16
16
|
|
17
17
|
url_is "http://localhost:4567"
|
18
18
|
begin_at "http://localhost:4567"
|
19
|
-
|
19
|
+
|
20
|
+
title_is "Title of Page"
|
21
|
+
look_for :testPage
|
22
|
+
|
20
23
|
link :reset_password, id: "resetPassword"
|
21
24
|
button :submit, id: "btnSubmit"
|
22
25
|
text_field :login_name, id: "loginName"
|
26
|
+
|
27
|
+
within_frame(id: "frame") do |frame|
|
28
|
+
text_field :framedLoginName, id: "framedLoginName", frame: frame
|
29
|
+
end
|
23
30
|
end
|
24
31
|
|
25
32
|
def mock_browser_for_watir
|
26
33
|
watir_browser = double('watir')
|
27
34
|
watir_browser.stub(:is_a?).with(Watir::Browser).and_return(true)
|
28
|
-
watir_browser.stub(:is_a?).with(Selenium::WebDriver::Driver).and_return(false)
|
29
35
|
watir_browser
|
30
36
|
end
|
31
|
-
|
32
|
-
def mock_browser_for_selenium
|
33
|
-
selenium_browser = double('selenium')
|
34
|
-
selenium_browser.stub(:is_a?).with(Watir::Browser).and_return(false)
|
35
|
-
selenium_browser.stub(:is_a?).with(Selenium::WebDriver::Driver).and_return(true)
|
36
|
-
selenium_browser
|
37
|
-
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Symbiont::Enclosers do
|
4
|
+
let(:watir_browser) { mock_browser_for_watir }
|
5
|
+
let(:watir_definition) { DefinitionTest.new(watir_browser) }
|
6
|
+
|
7
|
+
context "a definition using watir-webdriver" do
|
8
|
+
it "should allow frames to act as a context" do
|
9
|
+
watir_browser.should_receive(:frame).with(id: "frame").and_return(watir_browser)
|
10
|
+
watir_browser.should_receive(:text_field).and_return(watir_browser)
|
11
|
+
web_object = watir_definition.framedLoginName_text_field
|
12
|
+
web_object.should_not be_nil
|
13
|
+
web_object.should be_instance_of Symbiont::WebObjects::TextField
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'symbiont/factory'
|
3
|
+
|
4
|
+
class TestFactory
|
5
|
+
include Symbiont::Factory
|
6
|
+
|
7
|
+
attr_accessor :browser
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Symbiont::Factory do
|
11
|
+
before(:each) do
|
12
|
+
@factory = TestFactory.new
|
13
|
+
@factory.browser = mock_browser_for_watir
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should create a new definition object" do
|
17
|
+
@factory.on DefinitionTest do |page|
|
18
|
+
page.should be_instance_of DefinitionTest
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create a new definition object and view it" do
|
23
|
+
@factory.browser.should_receive(:goto).twice
|
24
|
+
@factory.on_view DefinitionTest do |page|
|
25
|
+
page.should be_instance_of DefinitionTest
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set a reference to be used outside the factory" do
|
30
|
+
active = @factory.on DefinitionTest
|
31
|
+
current = @factory.instance_variable_get "@active"
|
32
|
+
current.should === active
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|