wrapybara 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ module Wrapybara
2
+ class TextArea
3
+ include Element
4
+ include FillableField
5
+
6
+ def initialize(identifier, scope = default_scope, how = default_how)
7
+ @identifier = identifier
8
+ @how = how
9
+ @scope = scope
10
+ xpath = XPath::HTML.send(:locate_field, XPath.descendant(:textarea), identifier)
11
+ @element = get_element(xpath, scope)
12
+ end
13
+
14
+ def should_exist
15
+ super "Expected a text area #{self.element_identifier} to exist"
16
+ end
17
+
18
+ def should_not_exist
19
+ super "Did not expect a text area #{self.element_identifier}' to exist"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Wrapybara
2
+ class TextField
3
+ include Element
4
+ include FillableField
5
+
6
+ def initialize(identifier, scope = default_scope, how = default_how)
7
+ @identifier = identifier
8
+ @how = how
9
+ @scope = scope
10
+ xpath = XPath::HTML.send(:locate_field, XPath.descendant(:input)[XPath.attr(:type).equals('text')], identifier)
11
+ @element = get_element(xpath, scope)
12
+ end
13
+
14
+ def should_exist
15
+ super "Expected a text field #{self.element_identifier} to exist"
16
+ end
17
+
18
+ def should_not_exist
19
+ super "Did not expect a text field #{self.element_identifier}' to exist"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+ /*
2
+ This script facilitates tracking whether or not an element has focus. It is not an ideal solution,
3
+ but it does work across browsers and test environments. The need for such a solution was prompted
4
+ by HtmlUnit not supporting document.activeElement, which all major browsers now support. HtmlUnit
5
+ being the underlying technology used by Akephalos (in Cucumber via Capybara), this was a problem.
6
+
7
+ Focus Tracking can be used by calling FocusTracking.initialize once the dom is loaded and then by
8
+ calling $(element_id).has_focus().
9
+
10
+ This script is currently dependent on Prototype, but could be easily adapted for any JavaScript library.
11
+ */
12
+
13
+ var FocusTracking = {};
14
+
15
+ FocusTracking.attribute = 'has-focus';
16
+ FocusTracking.auto_focus_class_name = 'auto-focus';
17
+
18
+ FocusTracking.focusable_elements = function ()
19
+ {
20
+ return $$('input[type=text], input[type=password], input[type=submit], input[type=button], input[type=checkbox], input[type=radio], textarea, button, select');
21
+ }
22
+
23
+ FocusTracking.initialize = function ()
24
+ {
25
+ var elements = FocusTracking.focusable_elements();
26
+ elements.each(
27
+ function (element)
28
+ {
29
+ if (element.readAttribute(FocusTracking.attribute) == null)
30
+ {
31
+ // if the element already has the focus tracking pieces, leave it alone...only initialize it if
32
+ // it isn't there so we don't miss saving some changes.
33
+ Object.extend(element, FocusTracking.Element);
34
+ element.writeAttribute(FocusTracking.attribute, 'false');
35
+ element.observe('focus', element.got_focus);
36
+ element.observe('blur', element.lost_focus);
37
+ }
38
+ }
39
+ );
40
+ }
41
+
42
+ FocusTracking.auto_focus = function (class_name)
43
+ {
44
+ class_name = class_name == undefined || class_name == null ? FocusTracking.auto_focus_class_name : class_name;
45
+ var elements = $$('.' + class_name);
46
+ if (elements.length > 0)
47
+ {
48
+ element = elements.first();
49
+ element.activate();
50
+ }
51
+ }
52
+
53
+ FocusTracking.Element = {};
54
+
55
+ FocusTracking.Element.has_focus = function ()
56
+ {
57
+ return this.readAttribute(FocusTracking.attribute) == 'true';
58
+ }
59
+
60
+ FocusTracking.Element.got_focus = function ()
61
+ {
62
+ this.writeAttribute(FocusTracking.attribute, 'true');
63
+ }
64
+
65
+ FocusTracking.Element.lost_focus = function ()
66
+ {
67
+ this.writeAttribute(FocusTracking.attribute, 'false');
68
+ }
@@ -0,0 +1,45 @@
1
+ # This module is, admittedly, something of a hack. In order to reliably (across browsers and testing libraries) test for
2
+ # an element having focus, I resorted to adding some JavaScript event handling to read/write an attribute on focus/blur.
3
+ # Not pretty, but HtmlUnit, which Akephalos uses, did not recognize document.activeElement, so I had to roll my own
4
+ # solution. To make it easier for you to use this module, the corresponding JavaScript is included in focus_tracking.js.
5
+ # See it for usage notes.
6
+
7
+ # To use Wrapybara's focus handling capabilities, require wrapybara/ext/focus_handling in some file that gets loaded (I use
8
+ # support/extras.rb so I don't pollute env.rb) and then optionally set Wrapybara.focus_attribute to whatever the element
9
+ # attribute will be. As you can see below, Wrapybara checks the value of the attribute against what you say it should be
10
+ # when the element has focus.
11
+
12
+ module Wrapybara
13
+ def self.focus_attribute=(attribute)
14
+ @focus_attribute = attribute
15
+ end
16
+
17
+ def self.focus_attribute
18
+ @focus_attribute || 'has-focus'
19
+ end
20
+
21
+ def self.focus_value=(value)
22
+ @focus_value = value
23
+ end
24
+
25
+ def self.focus_value
26
+ @focus_value || 'true'
27
+ end
28
+
29
+ module Element
30
+ def focused?
31
+ self.should_exist
32
+ element[Wrapybara.focus_attribute] == Wrapybara.focus_value
33
+ end
34
+
35
+ def should_be_focused
36
+ message = "Expected element #{self.element_identifier} to be focused"
37
+ raise UnmetExpectation, message unless self.focused?
38
+ end
39
+
40
+ def should_not_be_focused
41
+ message = "Did not expect element #{self.element_identifier} to be focused"
42
+ raise UnmetExpectation, message if self.focused?
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,57 @@
1
+ # add this directory to the load path if it's not already included
2
+ this_dir = File.expand_path(File.dirname(__FILE__))
3
+ $: << this_dir unless $:.include?(this_dir)
4
+
5
+ module Wrapybara
6
+ class UnmetExpectation < Exception; end
7
+
8
+ def host
9
+ Capybara.app_host
10
+ end
11
+
12
+ def current_path
13
+ Capybara.current_path
14
+ end
15
+
16
+ def current_url
17
+ Capybara.current_url
18
+ end
19
+
20
+ def current_path_is?(path)
21
+ path = path.gsub('/', '\/').gsub('?', '\?')
22
+ (current_url || current_path) =~ /#{path}/
23
+ end
24
+
25
+ def current_path_should_be(path)
26
+ raise UnmetExpectation, "Expected the current path to be '#{path}'" unless current_path_is?(path)
27
+ end
28
+
29
+ def current_path_should_not_be(path)
30
+ raise UnmetExpectation, "Did not expect the current path to be '#{path}'" if current_path_is?(path)
31
+ end
32
+ end
33
+
34
+ require 'xpath'
35
+ require 'element'
36
+ require 'elements/attribute'
37
+ require 'elements/button'
38
+ require 'elements/checkbox'
39
+ require 'elements/content'
40
+ require 'elements/form'
41
+ require 'elements/image'
42
+ require 'elements/label'
43
+ require 'elements/link'
44
+ require 'elements/file_field'
45
+ require 'elements/fillable_field'
46
+ require 'elements/option'
47
+ require 'elements/password_field'
48
+ require 'elements/radio_button'
49
+ require 'elements/select'
50
+ require 'elements/table'
51
+ require 'elements/table_body'
52
+ require 'elements/table_cell'
53
+ require 'elements/table_head'
54
+ require 'elements/text_area'
55
+ require 'elements/text_field'
56
+
57
+ World(Wrapybara)
@@ -0,0 +1,139 @@
1
+ Given /^(?:I )?debug$/ do
2
+ require 'ruby-debug'
3
+ debugger
4
+ puts "\n\nDEBUGGER\n\n"
5
+ end
6
+
7
+ Given /^(?:I )?reload(?: the page)?$/ do
8
+ visit current_path
9
+ end
10
+
11
+ Given /^(?:I )?display "([^"]+)"$/ do |something|
12
+ puts "\n\n#{something}\n\n"
13
+ end
14
+
15
+ Given /^(?:I )?wait(?: (?:for )?(\d+) seconds)?$/ do |seconds|
16
+ seconds ||= '2'
17
+ sleep(seconds.to_i)
18
+ end
19
+
20
+ Given /^there (should|should not) be a[n]? (.+) (labeled|identified by|for|titled) "([^"]+)"(?: (?:in|within) "([^"]+)")?$/ do |expectation, element, how, identifier, scope|
21
+ element.gsub!(' ', '_')
22
+ expectation.gsub!(' ', '_')
23
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).send("#{expectation}_exist")
24
+ end
25
+
26
+ Given /^the table (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) have column[s]?(?: "([^"]+)")?$/ do |how, identifier, scope, expectation, column, table|
27
+ columns = column ? [column] : (table.hashes.collect { |row| row['label'] || '' })
28
+ Wrapybara::Table.new(identifier, scope, how).send("#{expectation}_have_columns", columns)
29
+ end
30
+
31
+ Given /^the select (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) have option[s]?(?: "([^"]+)")?(?: (selected))?$/ do |how, identifier, scope, expectation, option, selected, table|
32
+ options = option ? [option] : (table.hashes.collect { |row| row['label'] || '' })
33
+ expectation.gsub!(' ', '_')
34
+ if selected
35
+ options.each do |option|
36
+ Wrapybara::Select.new(identifier, scope, how).option(option).send("#{expectation}_be_selected")
37
+ end
38
+ else
39
+ Wrapybara::Select.new(identifier, scope, how).send("#{expectation}_have_options", options)
40
+ end
41
+ end
42
+
43
+ # In this step, the label capture must use an * to accept empty strings, ie, selecting the blank option typically at the top of the options
44
+ Given /^(?:I )?(choose|select|deselect) "([^"]*)" from the select (labeled|identified by) "([^"]+)"?(?: (?:in|within) "([^"]+)")?$/ do |action, option, how, identifier, scope|
45
+ Wrapybara::Select.new(identifier, scope, how).send(action.to_sym, option)
46
+ end
47
+
48
+ Given /^the select (labeled|identified by) "([^"]+)"?(?: (?:in|within) "([^"]+)")? (should|should not) have "([^"]*)" selected$/ do |how, identifier, scope, expectation, option|
49
+ expectation.gsub!(' ', '_')
50
+ Wrapybara::Select.new(identifier, scope, how).option(option).send("#{expectation}_be_selected")
51
+ end
52
+
53
+ Given /^the (.+) (labeled|identified by|titled) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) be (.+)$/ do |element, how, identifier, scope, expectation, state|
54
+ element.gsub!(' ', '_')
55
+ expectation.gsub!(' ', '_')
56
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).send("#{expectation}_be_#{state}")
57
+ end
58
+
59
+ Given /^the (.+) (labeled|identified by|titled) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) have attribute "([^"]+)" with value "([^"]+)"$/ do |element, how, identifier, scope, expectation, attribute, value|
60
+ element.gsub!(' ', '_')
61
+ expectation.gsub!(' ', '_')
62
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).send("#{expectation}_have_attribute", attribute, value)
63
+ end
64
+
65
+ Given /^(?:I )?(check|uncheck) the (checkbox|radio button) (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")?$/ do |action, element, how, identifier, scope|
66
+ element.gsub!(' ', '_')
67
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).send(action)
68
+ end
69
+
70
+ # In this step, the label capture must use an * to accept empty strings, so we can clear the field
71
+ Given /^(?:I )?fill in the (text field|password field|text area) (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? with "([^"]*)"$/ do |element, how, identifier, scope, content|
72
+ content ||= ''
73
+ element.gsub!(' ', '_')
74
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).fill_in(content)
75
+ end
76
+
77
+ Given /^(?:I )?click the (button|link) (labeled|identified by|titled) "([^"]+)"(?: (?:in|within) "([^"]+)")?$/ do |element, how, identifier, scope|
78
+ "Wrapybara::#{element.capitalize}".constantize.new(identifier, scope, how).click
79
+ end
80
+
81
+ # for finding unlabeled links
82
+ Given /^there (should|should not) be a link to "([^"]+)"(?: (?:in|within) "([^"]+)")?$/ do |expectation, destination, scope|
83
+ expectation.gsub!(' ', '_')
84
+ Wrapybara::Link.new(destination, scope, 'to').send("#{expectation}_exist")
85
+ end
86
+
87
+ Given /^there (should|should not) be a link to the "([^"]+)" page(?: (?:in|within) "([^"]+)")?$/ do |expectation, destination, scope|
88
+ expectation.gsub!(' ', '_')
89
+ destination = path_to(destination)
90
+ Wrapybara::Link.new(destination, scope, 'to').send("#{expectation}_exist")
91
+ end
92
+
93
+ # for clicking unlabeled links
94
+ Given /^(?:I )?click the link to the "([^"]+)" page(?: (?:in|within) "([^"]+)")?$/ do |destination, scope|
95
+ destination = path_to(destination)
96
+ Wrapybara::Link.new(destination, scope, 'to').click
97
+ end
98
+
99
+ # for clicking table column headers (as in sortable columns)
100
+ Given /^(?:I )?click column "([^"]+)" of the table (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")?$/ do |column, how, table, scope|
101
+ Wrapybara::Table.new(table, scope, how).click_column(column)
102
+ end
103
+
104
+ # content
105
+ Given /^(?:I )?(should|should not) see "([^"]+)"(?: within "([^"]+)")?$/ do |expectation, content, scope|
106
+ expectation.gsub!(' ', '_')
107
+ Wrapybara::Content.new(content, scope).send("#{expectation}_exist")
108
+ end
109
+
110
+ Given /^"([^"]+)"(?: within "([^"]+)")? (should|should not) be visible$/ do |content, scope, expectation|
111
+ expectation.gsub!(' ', '_')
112
+ Wrapybara::Content.new(content, scope).send("#{expectation}_be_visible")
113
+ end
114
+
115
+ # for clicking things like headers that have expandable detail below them
116
+ Given /^I click the text "([^"]+)"(?: within "([^"]+)")?$/ do |content, scope|
117
+ Wrapybara::Content.new(content, scope).click
118
+ end
119
+
120
+ # fillable fields (text field, password field, text area)
121
+ Given /^the (.+) (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) have content "([^"]+)"$/ do |element, how, identifier, scope, expectation, content|
122
+ element.gsub!(' ', '_')
123
+ expectation.gsub!(' ', '_')
124
+ "Wrapybara::#{element.camelize}".constantize.new(identifier, scope, how).send("#{expectation}_have_content", content)
125
+ end
126
+
127
+ # table content
128
+ Given /^(head|body)?\s?row (\d+) column (\d+) of the table (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) have content "([^"]+)"$/ do |element, row, column, how, identifier, scope, expectation, content|
129
+ element ||= 'body'
130
+ expectation.gsub!(' ', '_')
131
+ Wrapybara::Table.new(identifier, scope, how).send(element).cell(row, column).send("#{expectation}_have_content", content)
132
+ end
133
+
134
+ # other elements in table cells
135
+ Given /^(head|body)?\s?row (\d+) column (\d+) of the table (labeled|identified by) "([^"]+)"(?: (?:in|within) "([^"]+)")? (should|should not) contain a[n]? (.+) (labeled|identified by) "([^"]+)"$/ do |element, row, column, how, identifier, scope, expectation, child_element, child_how, child_identifier|
136
+ element ||= 'body'
137
+ expectation.gsub!(' ', '_')
138
+ Wrapybara::Table.new(identifier, scope, how).send(element).cell(row, column).send("#{expectation}_contain", child_element, child_identifier, child_how)
139
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wrapybara
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Phillip Koebbe
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-05-20 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Wrapybara creates objects that are based on Capybara.
22
+ email: phillipkoebbe@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE.txt
29
+ - README.rdoc
30
+ files:
31
+ - lib/wrapybara.rb
32
+ - lib/wrapybara/element.rb
33
+ - lib/wrapybara/elements/attribute.rb
34
+ - lib/wrapybara/elements/button.rb
35
+ - lib/wrapybara/elements/checkbox.rb
36
+ - lib/wrapybara/elements/content.rb
37
+ - lib/wrapybara/elements/file_field.rb
38
+ - lib/wrapybara/elements/fillable_field.rb
39
+ - lib/wrapybara/elements/form.rb
40
+ - lib/wrapybara/elements/image.rb
41
+ - lib/wrapybara/elements/label.rb
42
+ - lib/wrapybara/elements/link.rb
43
+ - lib/wrapybara/elements/option.rb
44
+ - lib/wrapybara/elements/password_field.rb
45
+ - lib/wrapybara/elements/radio_button.rb
46
+ - lib/wrapybara/elements/select.rb
47
+ - lib/wrapybara/elements/table.rb
48
+ - lib/wrapybara/elements/table_body.rb
49
+ - lib/wrapybara/elements/table_cell.rb
50
+ - lib/wrapybara/elements/table_head.rb
51
+ - lib/wrapybara/elements/text_area.rb
52
+ - lib/wrapybara/elements/text_field.rb
53
+ - lib/wrapybara/ext/focus_tracking.js
54
+ - lib/wrapybara/ext/focus_tracking.rb
55
+ - lib/wrapybara/methods.rb
56
+ - lib/wrapybara/steps.rb
57
+ - LICENSE.txt
58
+ - README.rdoc
59
+ has_rdoc: true
60
+ homepage: http://github.com/phillipkoebbe/wrapybara
61
+ licenses:
62
+ - MIT
63
+ post_install_message:
64
+ rdoc_options: []
65
+
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.7
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: An object wrapper around Capybara.
91
+ test_files: []
92
+