gamera 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.
@@ -0,0 +1,231 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2015, The Gamera Development Team. See the COPYRIGHT file at
6
+ # the top-level directory of this distribution and at
7
+ # http://github.com/gamera-team/gamera/COPYRIGHT.
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ # of this software and associated documentation files (the "Software"), to deal
11
+ # in the Software without restriction, including without limitation the rights
12
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ # copies of the Software, and to permit persons to whom the Software is
14
+ # furnished to do so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in
17
+ # all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ # THE SOFTWARE.
26
+ #++
27
+
28
+ require 'capybara'
29
+
30
+ module Gamera
31
+ module PageSections
32
+ # This class represents a table on a web page. For example, if you had
33
+ # a page like
34
+ #
35
+ # <html>
36
+ # <body>
37
+ # <p>Example table</p>
38
+ # <table>
39
+ # <tr>
40
+ # <th>Item</th>
41
+ # <th>Wholesale Cost</th>
42
+ # <th>Retail Cost</th>
43
+ # <th></th>
44
+ # <th></th>
45
+ # </tr>
46
+ # <tr>
47
+ # <td>Red Hat</td>
48
+ # <td>2.00</td>
49
+ # <td>15.00</td>
50
+ # <td><a href="/item/12/edit">Edit</a></td>
51
+ # <td><a href="/item/12/delete">Delete</a></td>
52
+ # </tr>
53
+ # <tr>
54
+ # <td>Skull cap</td>
55
+ # <td>2.00</td>
56
+ # <td>27.00</td>
57
+ # <td><a href="/item/1/edit">Edit</a></td>
58
+ # <td><a href="/item/1/delete">Delete</a></td>
59
+ # </tr>
60
+ # </table>
61
+ # </body>
62
+ # </html>
63
+ #
64
+ # you could include this in a page object class like so:
65
+ #
66
+ # class HatPage < Gamera::Page
67
+ # include Forwardable
68
+ # include Gamera::PageSections
69
+ #
70
+ # attr_reader :registration_form, :table
71
+ #
72
+ # def initialize
73
+ # super(path_join(BASE_URL, '/hat'), %r{hat})
74
+ #
75
+ # headers = ['Item', 'Wholesale Cost', 'Retail Cost']
76
+ # @registration_form = Table.new(headers: headers, row_name:hat,
77
+ # name_column: 'Item')
78
+ # def_delegators :hat_table,
79
+ # :hat, :hats,
80
+ # :has_hat?, :has_hats?,
81
+ # :edit_hat, :delete_hat
82
+ # end
83
+ # end
84
+ #
85
+ class Table < DelegateClass(Capybara::Node::Element)
86
+ include Capybara::DSL
87
+
88
+ # @param headers [Array] An array of the strings from the tables header row
89
+ # @param row_name [String] A label that can be used to create more readable versions of general row methods
90
+ # @param plural_row_name [String] Plural form of [row_name]
91
+ # @param name_column [String] The column heading for the column which contains each row's name
92
+ # @param row_css [String] The CSS selector which is used to find individual rows in the table
93
+ # @param row_class [Class] The class which will represent a table row
94
+ # @param row_editor [Class] A class which defines the edit behavior for a row
95
+ # @param row_deleter [Class] A class which defines the edit behavior for a row
96
+ def initialize(headers:,
97
+ row_name:,
98
+ plural_row_name: nil,
99
+ name_column: 'Name',
100
+ row_css: 'tr + tr', # all tr's except the first one (which is almost always a table header)
101
+ row_class: TableRow,
102
+ row_editor: RowEditor.new,
103
+ row_deleter: RowDeleter.new
104
+ )
105
+ @row_css = row_css
106
+ @headers = headers
107
+ @row_class = row_class
108
+ @row_editor = row_editor
109
+ @row_deleter = row_deleter
110
+ @row_name = row_name
111
+ @plural_row_name = plural_row_name
112
+ @name_column = name_column.downcase.gsub(' ', '_').gsub(/[^a-z0-9_]+/, '')
113
+
114
+ add_custom_function_names
115
+ end
116
+
117
+ # Retrieves an array of rows from the table
118
+ #
119
+ # @return [Array] An array of row_class objects
120
+ def rows
121
+ has_rows?
122
+ all(row_css).map { |r| row_class.new(r, headers) }
123
+ end
124
+
125
+ # Finds and returns a row from the table
126
+ #
127
+ # @param name [String] [RegExp] The name to look for in the table's specified name column.
128
+ # @return [row_class] A row_class object that has the matching name or nil
129
+ def row_named(name)
130
+ if name.is_a? String
131
+ rows.detect { |r| r.send(name_column) == name } if has_row?(name)
132
+ elsif name.is_a? Regexp
133
+ rows.detect { |r| name.match r.send(name_column) } if has_row?(name)
134
+ end
135
+ end
136
+
137
+ # Checks for the existence of a row with the given name
138
+ #
139
+ # @param name [String] The name to look for in the table's specified name column.
140
+ # @return [Boolean] True if a row with the specified name is found, false
141
+ # otherwise
142
+ def has_row?(name)
143
+ page.has_selector?(row_css, text: name)
144
+ end
145
+
146
+ # Checks to see if the table has any rows
147
+ #
148
+ # @return [Boolean] True if the row selector is found, false otherwise
149
+ def has_rows?
150
+ has_selector?(row_css)
151
+ end
152
+
153
+ # Delete all of the rows from the table
154
+ def delete_all_rows
155
+ while has_rows?
156
+ r = rows.first.send(name_column)
157
+ delete_row(r)
158
+ has_row?(r)
159
+ end
160
+ end
161
+
162
+ # Start the delete process for the row matching the specified name
163
+ def delete_row(name)
164
+ row_deleter.delete(row_named(name))
165
+ end
166
+
167
+ # Start the edit process for the row matching the specified name
168
+ def edit_row(name)
169
+ row_editor.edit(row_named(name))
170
+ end
171
+
172
+ private
173
+
174
+ attr_reader :headers, :row_css, :row_name, :name_column, :row_class,
175
+ :row_editor, :row_deleter
176
+
177
+ def add_custom_function_names
178
+ row_name = @row_name # The attr_reader wasn't working here
179
+ plural_row_name = @plural_row_name
180
+ rows_name = plural_row_name ? plural_row_name.to_sym : "#{row_name}s".to_sym
181
+ has_row_name = "has_#{row_name}?".to_sym
182
+ has_rows_name = plural_row_name ? "has_#{plural_row_name}?".to_sym : "has_#{row_name}s?".to_sym
183
+ delete_all_rows_name = plural_row_name ? "delete_all_#{plural_row_name}".to_sym : "delete_all_#{row_name}s".to_sym
184
+ delete_row_name = "delete_#{row_name}".to_sym
185
+ edit_row_name = "edit_#{row_name}".to_sym
186
+
187
+ self.class.instance_eval do
188
+ alias_method rows_name, :rows
189
+ alias_method has_row_name, :has_row?
190
+ alias_method has_rows_name, :has_rows?
191
+ alias_method delete_all_rows_name, :delete_all_rows
192
+ alias_method delete_row_name, :delete_row
193
+ alias_method edit_row_name, :edit_row
194
+ alias_method row_name, :row_named
195
+ end
196
+ end
197
+
198
+
199
+ end
200
+
201
+ # Default class used to represent a row in a table
202
+ class TableRow < DelegateClass(Capybara::Node::Element)
203
+ # @param row_css [String] The css selector for the row
204
+ # @param headers [Array] An array of the strings from the tables header row
205
+ def initialize(row_css, headers)
206
+ super(row_css)
207
+
208
+ headers.each_with_index do |header, i|
209
+ cell_name = header.downcase.gsub(' ', '_').gsub(/[^a-z0-9_]+/, '')
210
+ self.class.send(:define_method, cell_name) do
211
+ find("td:nth-child(#{i + 1})").text
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ # Wrapper class for row edit action
218
+ class RowEditor
219
+ def edit(table_row)
220
+ table_row.find_link('Edit').click
221
+ end
222
+ end
223
+
224
+ # Wrapper class for row delete action
225
+ class RowDeleter
226
+ def delete(table_row)
227
+ table_row.find_link('Delete').click
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,75 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2015, The Gamera Development Team. See the COPYRIGHT file at
6
+ # the top-level directory of this distribution and at
7
+ # http://github.com/gamera-team/gamera/COPYRIGHT.
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ # of this software and associated documentation files (the "Software"), to deal
11
+ # in the Software without restriction, including without limitation the rights
12
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ # copies of the Software, and to permit persons to whom the Software is
14
+ # furnished to do so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in
17
+ # all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ # THE SOFTWARE.
26
+ #++
27
+
28
+ require 'sequel'
29
+
30
+ module Gamera
31
+ module Utils
32
+ # Cleans a database by truncating the tables
33
+ #
34
+ # Usage:
35
+ #
36
+ # Gamera::Utils::DatabaseCleaner.new(connection).clean
37
+ #
38
+ # Or:
39
+ #
40
+ # Gamera::Utils::DatabaseCleaner.new(connection, tables).clean
41
+ #
42
+ # +connection+ is a Sequel database connection.
43
+ # +tables+ is an array of table names (string or symbol).
44
+ #
45
+ # If +tables+ is given, only the tables supplied
46
+ # will be truncated. If +tables+ is not given,
47
+ # all tables in the database will be truncated.
48
+ class DatabaseCleaner
49
+ def initialize(connection, tables = nil)
50
+ @db = connection
51
+ @tables = tables || all_table_names
52
+ end
53
+
54
+ # Removes all data from the initialized tables.
55
+ # If no tables were given, removes all data from
56
+ # all tables in the database.
57
+ #
58
+ # Cleans via truncation.
59
+ def clean
60
+ tables.each do |table|
61
+ db[table].truncate
62
+ end
63
+ nil
64
+ end
65
+
66
+ private
67
+
68
+ attr_reader :db, :tables
69
+
70
+ def all_table_names
71
+ db.tables
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,34 @@
1
+ $LOAD_PATH << '.'
2
+
3
+ require_relative '../spec/spec_helper'
4
+ require_relative '../spec/resources/simple_form/simple_form_page.rb'
5
+ require_relative '../spec/resources/simple_form/simple_form.rb'
6
+ require_relative '../spec/resources/simple_site/home_page.rb'
7
+ require_relative '../spec/resources/simple_site/redirect_page.rb'
8
+ require_relative '../spec/resources/simple_site/hit_counter_page.rb'
9
+ require_relative '../spec/resources/simple_site/simple_site.rb'
10
+
11
+ def simple_form_page
12
+ @simple_form_page ||= SimpleFormPage.new
13
+ end
14
+
15
+ def home_page
16
+ @home_page ||= HomePage.new
17
+ end
18
+
19
+ def hit_counter_page
20
+ @hit_counter_page ||= HitCounterPage.new
21
+ end
22
+
23
+ def redirect_page
24
+ @redirect_page ||= RedirectPage.new
25
+ end
26
+
27
+ def simple_site
28
+ set_app SimpleSite.new
29
+ end
30
+
31
+ def simple_form
32
+ set_app SimpleForm.new
33
+ end
34
+
metadata ADDED
@@ -0,0 +1,259 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gamera
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eric Dobbs
8
+ - Glen Aultman-Bettridge
9
+ - Jillian Rosile
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-06-11 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 3.1.0
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - "~>"
30
+ - !ruby/object:Gem::Version
31
+ version: '3.1'
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 3.1.0
35
+ - !ruby/object:Gem::Dependency
36
+ name: sinatra
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.4'
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.4.5
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: '1.4'
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.4.5
55
+ - !ruby/object:Gem::Dependency
56
+ name: selenium-webdriver
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.45'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 2.45.0
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '2.45'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 2.45.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: sqlite3
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.3'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 1.3.10
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.3'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 1.3.10
95
+ - !ruby/object:Gem::Dependency
96
+ name: capybara
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '2.4'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 2.4.4
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '2.4'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 2.4.4
115
+ - !ruby/object:Gem::Dependency
116
+ name: capybara-screenshot
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '1.0'
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 1.0.7
125
+ type: :runtime
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 1.0.7
135
+ - !ruby/object:Gem::Dependency
136
+ name: sequel
137
+ requirement: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: '4.20'
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 4.20.0
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '4.20'
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: 4.20.0
155
+ - !ruby/object:Gem::Dependency
156
+ name: byebug
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '5.0'
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 5.0.0
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '5.0'
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: 5.0.0
175
+ - !ruby/object:Gem::Dependency
176
+ name: yard
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '0.8'
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: 0.8.7.2
185
+ type: :development
186
+ prerelease: false
187
+ version_requirements: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - "~>"
190
+ - !ruby/object:Gem::Version
191
+ version: '0.8'
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: 0.8.7.2
195
+ - !ruby/object:Gem::Dependency
196
+ name: yardstick
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.9'
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: 0.9.9
205
+ type: :development
206
+ prerelease: false
207
+ version_requirements: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - "~>"
210
+ - !ruby/object:Gem::Version
211
+ version: '0.9'
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: 0.9.9
215
+ description: Provides a framework which let's you wrap any web page with a Ruby API.
216
+ email:
217
+ - eric@dobbse.net
218
+ - glenab@koansolutions.net
219
+ - jillian.rosile@gmail.com
220
+ executables: []
221
+ extensions: []
222
+ extra_rdoc_files: []
223
+ files:
224
+ - lib/gamera.rb
225
+ - lib/gamera/builder.rb
226
+ - lib/gamera/builders/sequel_fixture_builder.rb
227
+ - lib/gamera/exceptions.rb
228
+ - lib/gamera/general_proxy.rb
229
+ - lib/gamera/page.rb
230
+ - lib/gamera/page_sections/form.rb
231
+ - lib/gamera/page_sections/table.rb
232
+ - lib/gamera/utils/database_cleaner.rb
233
+ - lib/pry_setup.rb
234
+ homepage: http://gamera-team.github.io/gamera/
235
+ licenses:
236
+ - MIT
237
+ metadata: {}
238
+ post_install_message:
239
+ rdoc_options: []
240
+ require_paths:
241
+ - lib
242
+ required_ruby_version: !ruby/object:Gem::Requirement
243
+ requirements:
244
+ - - ">="
245
+ - !ruby/object:Gem::Version
246
+ version: '0'
247
+ required_rubygems_version: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - ">="
250
+ - !ruby/object:Gem::Version
251
+ version: '0'
252
+ requirements: []
253
+ rubyforge_project:
254
+ rubygems_version: 2.2.2
255
+ signing_key:
256
+ specification_version: 4
257
+ summary: PageObject pattern implementation based on Capybara
258
+ test_files: []
259
+ has_rdoc: