gamera 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: