insite 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/insite/component/component.rb +33 -26
- data/lib/insite/component/component_collection.rb +10 -10
- data/lib/insite/element/element.rb +12 -12
- data/lib/insite/element/element_collection.rb +14 -14
- data/lib/insite/element/generated/element_instance_methods.rb +0 -318
- data/lib/insite/examples/material_angular_io/components/overwritten_selector.rb +3 -0
- data/lib/insite/examples/material_angular_io/components/pluralized_name_test.rb +2 -0
- data/lib/insite/examples/material_angular_io_site.rb +12 -2
- data/lib/insite/insite.rb +93 -55
- data/lib/insite/methods/common_methods.rb +40 -6
- data/lib/insite/page/defined_page.rb +16 -50
- data/lib/insite/page/undefined_page.rb +3 -24
- data/lib/insite/version.rb +1 -1
- metadata +4 -2
@@ -5,10 +5,19 @@ end
|
|
5
5
|
|
6
6
|
# Require hand-crafted artisanal components.
|
7
7
|
%w(example_viewer mat_chip_list mat_chip mat_icon mat_form_field
|
8
|
-
mat_input mat_option mat_select_content mat_select no_selector
|
8
|
+
mat_input mat_option mat_select_content mat_select no_selector
|
9
|
+
overwritten_selector pluralized_name_test).each do |c|
|
9
10
|
require "insite/examples/material_angular_io/components/#{c}"
|
10
11
|
end
|
11
12
|
|
13
|
+
class OneVarTemplatePage < MaterialAngularIO::Page
|
14
|
+
set_url "/components/chips/overview/{var1}"
|
15
|
+
end
|
16
|
+
|
17
|
+
class TwoVarTemplatePage < MaterialAngularIO::Page
|
18
|
+
set_url "/components/chips/overview/{var1}/{var2}"
|
19
|
+
end
|
20
|
+
|
12
21
|
# Most of the pages for material.angular.io are auto-generated because
|
13
22
|
# their URLs match a pattern. But some custom page definitions are included
|
14
23
|
# below. This first overwrites the auto-generated page definition for
|
@@ -17,9 +26,10 @@ end
|
|
17
26
|
class ChipsOverviewPage < MaterialAngularIO::Page
|
18
27
|
set_url "/components/chips/overview"
|
19
28
|
|
20
|
-
no_selector :test_no_selector
|
21
29
|
no_selector :test_no_selector_with_args, tag_name: :div, index: 3
|
22
30
|
|
31
|
+
overwritten_selector :overwritten_selector
|
32
|
+
|
23
33
|
elements :mat_examples_collection, tag_name: 'example-viewer'
|
24
34
|
elements :modified_mat_examples_collection, tag_name: 'example-viewer' do
|
25
35
|
def test_method
|
data/lib/insite/insite.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'timeout'
|
2
|
+
require_relative 'methods/common_methods'
|
2
3
|
|
3
4
|
# Usage:
|
4
5
|
# require 'insite'
|
@@ -7,17 +8,20 @@ require 'timeout'
|
|
7
8
|
# include Insite
|
8
9
|
# end
|
9
10
|
module Insite
|
10
|
-
attr_reader :base_url, :unique_methods, :browser_type
|
11
|
+
attr_reader :base_url, :unique_methods, :browser_type, :site
|
11
12
|
attr_accessor :pages, :browser, :arguments, :most_recent_page
|
12
13
|
|
14
|
+
include CommonMethods
|
15
|
+
|
13
16
|
def self.class_to_tag(klass)
|
14
17
|
if klass.respond_to?(:collection) && klass.collection?
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
(
|
19
|
+
Watir.tag_to_class.key(klass) ||
|
20
|
+
Watir.tag_to_class.key(CLASS_MAP.key(klass)) ||
|
21
|
+
Watir.tag_to_class.key(CLASS_MAP.key(klass.collection_member_class))
|
22
|
+
)
|
18
23
|
else
|
19
|
-
Watir.tag_to_class.key(klass) ||
|
20
|
-
Watir.tag_to_class.key(CLASS_MAP.key(klass))
|
24
|
+
Watir.tag_to_class.key(klass) || Watir.tag_to_class.key(CLASS_MAP.key(klass))
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
@@ -64,31 +68,6 @@ module Insite
|
|
64
68
|
@browser.close if browser?
|
65
69
|
end
|
66
70
|
|
67
|
-
def describe
|
68
|
-
puts <<-EOF
|
69
|
-
Wrapper class for all pages defined for the site.
|
70
|
-
Site:\t#{self.class} (#{__FILE__})
|
71
|
-
Base URL:\t#{@base_url}
|
72
|
-
Browser:\t#{@browser}
|
73
|
-
Current Page:\t#{page.class}
|
74
|
-
|
75
|
-
Page Accessor Methods (Use '?' with name to check for presence.)
|
76
|
-
-----------------------------------------------------------------
|
77
|
-
#{
|
78
|
-
tmp = []
|
79
|
-
max = pages.map(&:to_s).max { |x| x.length }
|
80
|
-
if max.length > 40
|
81
|
-
pages.map(&:to_s).sort.map(&:underscore).join("\n")
|
82
|
-
else
|
83
|
-
pages.map(&:to_s).sort.map(&:underscore).each_slice(2) do |arr|
|
84
|
-
tmp << arr[0].to_s.ljust(40) + arr[1].to_s.ljust(40)
|
85
|
-
end
|
86
|
-
tmp.join("\n")
|
87
|
-
end
|
88
|
-
}
|
89
|
-
EOF
|
90
|
-
end
|
91
|
-
|
92
71
|
# Returns a Selenium driver object.
|
93
72
|
def driver
|
94
73
|
@browser.driver
|
@@ -99,23 +78,24 @@ EOF
|
|
99
78
|
browser?
|
100
79
|
end
|
101
80
|
|
102
|
-
def generate_tag_classes
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
81
|
+
# def generate_tag_classes
|
82
|
+
# tags = []
|
83
|
+
# cli = Highline.new
|
84
|
+
#
|
85
|
+
# loop do
|
86
|
+
# tags = (tags + find_non_standard_tags).uniq.sort
|
87
|
+
# cli.choose do |menu|
|
88
|
+
# menu.prompt "Found #{tags.length} non-standard tags. Choose one of the following options:"
|
89
|
+
# menu.choice(:list_tags) { puts tags.join(",\n") + "\n" }
|
90
|
+
# menu.choice(:continue) {}
|
91
|
+
# menu.choice(:write_to_console) do
|
92
|
+
# end
|
93
|
+
# menu.choice(:exist_without_writing) { break }
|
94
|
+
#
|
95
|
+
# end
|
96
|
+
# end
|
97
|
+
# end
|
115
98
|
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
99
|
# Creates a site object, which will have accessor methods for all pages that
|
120
100
|
# you have defined for the site. This object takes a hash argument. There is
|
121
101
|
# only one required value (the base_url for the site.) Example:
|
@@ -137,13 +117,18 @@ EOF
|
|
137
117
|
# => 1
|
138
118
|
# TODO: Sort args.
|
139
119
|
def initialize(base_url = nil, hsh={})
|
140
|
-
@
|
141
|
-
@
|
142
|
-
@
|
143
|
-
@
|
120
|
+
@site = self
|
121
|
+
@arguments = hsh.with_indifferent_access
|
122
|
+
@base_url = base_url
|
123
|
+
@browser_type = (@arguments[:browser] ? @arguments[:browser].to_sym : nil)
|
124
|
+
|
125
|
+
# Cull templates from array of pages that gets returned (since templates
|
126
|
+
# should never be used directly.)
|
127
|
+
@pages = self.class::DefinedPage.descendants.reject do |pg|
|
128
|
+
pg.page_template?
|
129
|
+
end
|
144
130
|
|
145
|
-
#
|
146
|
-
# using Site.custom_tags.
|
131
|
+
# Builds generic components for custom tags.
|
147
132
|
if self.class.custom_tags
|
148
133
|
self.class.custom_tags.each do |tag|
|
149
134
|
# TODO: Ditch string interpolation.
|
@@ -182,6 +167,14 @@ EOF
|
|
182
167
|
end
|
183
168
|
end
|
184
169
|
|
170
|
+
# Sort templates by variable count: Templates with more vars will be
|
171
|
+
# prioritized. This will partially eliminate the potential for a match on
|
172
|
+
# the wrong template when there are two or more templates that match the
|
173
|
+
# URL.
|
174
|
+
@pages = @pages.sort do |pg1, pg2|
|
175
|
+
pg1.url_template.variables.length <=> pg2.url_template.variables.length
|
176
|
+
end
|
177
|
+
|
185
178
|
visited = Set.new
|
186
179
|
tmp = @pages.map {|p| p.instance_methods }.flatten
|
187
180
|
tmp.each do |element|
|
@@ -205,6 +198,10 @@ EOF
|
|
205
198
|
end.uniq.sort
|
206
199
|
end
|
207
200
|
|
201
|
+
def html
|
202
|
+
@browser.html
|
203
|
+
end
|
204
|
+
|
208
205
|
def html_tags
|
209
206
|
%i(html title head body) + Insite::METHOD_MAP.values.flatten.each do |mth|
|
210
207
|
elem = @browser.send(mth)
|
@@ -227,10 +224,12 @@ EOF
|
|
227
224
|
# what was attempted.
|
228
225
|
def method_missing(mth, *args, &block)
|
229
226
|
original_page = @most_recent_page
|
227
|
+
|
230
228
|
if original_page.respond_to?(mth)
|
231
229
|
original_page.public_send(mth, *args, &block)
|
232
230
|
else
|
233
231
|
new_page = page
|
232
|
+
|
234
233
|
if new_page.respond_to?(mth)
|
235
234
|
page.public_send(mth, *args, &block)
|
236
235
|
elsif !new_page.defined?
|
@@ -322,15 +321,54 @@ EOF
|
|
322
321
|
# URL in the browser.
|
323
322
|
#
|
324
323
|
# If a matching page can't be found then Insite will return an "undefined page"
|
325
|
-
# object. See the
|
324
|
+
# object. See the UndefinedPage class for more details.
|
326
325
|
def page
|
326
|
+
# 1.)
|
327
|
+
# Before anything else, look to see if it's the most recent page:
|
327
328
|
return @most_recent_page if @most_recent_page && @most_recent_page.on_page?
|
329
|
+
process_browser
|
328
330
|
url = @browser.url
|
331
|
+
|
329
332
|
found_page = nil
|
333
|
+
# 2.)
|
334
|
+
# Ensure that static templates are always prioritized when attempting to
|
335
|
+
# match, which will prevent the wrong template from getting matched in this
|
336
|
+
# scenario:
|
337
|
+
# - "/accounts/{account_code}"
|
338
|
+
# - "/accounts/new"
|
339
|
+
#
|
340
|
+
# Start by working through the array from FRONT to BACK, since any static
|
341
|
+
# templates will be at the front of the array. Stop when we start to see
|
342
|
+
# templates whth vars (These will get handled in the next statement.)
|
330
343
|
@pages.each do |pg|
|
344
|
+
break if pg.url_template.variables.length > 0
|
345
|
+
|
346
|
+
if pg.url_matcher && pg.url_matcher =~ url
|
347
|
+
found_page = pg
|
348
|
+
elsif pg.url_template.match(url)
|
349
|
+
found_page = pg
|
350
|
+
else
|
351
|
+
next
|
352
|
+
end
|
353
|
+
|
354
|
+
break if found_page
|
355
|
+
end
|
356
|
+
|
357
|
+
# 3.) Now we've reached the templates that include one or more variables.
|
358
|
+
# For these, we want to try to match on the templates with more variables.
|
359
|
+
# This prevents an invalid match in the following situation and removes the
|
360
|
+
# need to provide a URL matcher to override the URL template:
|
361
|
+
# - "/accounts/{account_code}/edit"
|
362
|
+
# - "/accounts/{account_code}"
|
363
|
+
# Now work through all the array from BACK to FRONT, stopping when we reach
|
364
|
+
# the point where we see templates without a var (since those were already
|
365
|
+
# handled above.)
|
366
|
+
@pages.reverse.each do |pg|
|
367
|
+
break if pg.url_template.variables.length == 0
|
368
|
+
|
331
369
|
if pg.url_matcher && pg.url_matcher =~ url
|
332
370
|
found_page = pg
|
333
|
-
elsif
|
371
|
+
elsif pg.url_template.match(url)
|
334
372
|
found_page = pg
|
335
373
|
else
|
336
374
|
next
|
@@ -12,10 +12,6 @@ module Insite
|
|
12
12
|
end
|
13
13
|
alias nokogiri document
|
14
14
|
|
15
|
-
# Returns a string representation of the page.
|
16
|
-
def inspect
|
17
|
-
"#<#{self.class.name}:#{object_id} @url=#{@browser.url}>"
|
18
|
-
end
|
19
15
|
|
20
16
|
private
|
21
17
|
def process_browser
|
@@ -29,8 +25,6 @@ module Insite
|
|
29
25
|
"Browser check failed. The browser is no longer present.\n\n"
|
30
26
|
)
|
31
27
|
end
|
32
|
-
rescue(Insite::Errors::BrowserNotOpenError) => e
|
33
|
-
raise e
|
34
28
|
rescue => e
|
35
29
|
raise(
|
36
30
|
Insite::Errors::BrowserResponseError,
|
@@ -57,6 +51,46 @@ module Insite
|
|
57
51
|
|
58
52
|
end
|
59
53
|
public
|
54
|
+
# private
|
55
|
+
# def process_browser
|
56
|
+
# if @site.browser.is_a?(Watir::Browser)
|
57
|
+
# begin
|
58
|
+
# if @site.browser.exists?
|
59
|
+
# return @site.browser
|
60
|
+
# else
|
61
|
+
# raise(
|
62
|
+
# Insite::Errors::BrowserClosedError,
|
63
|
+
# "Browser check failed. The browser is no longer present.\n\n"
|
64
|
+
# )
|
65
|
+
# end
|
66
|
+
# rescue(Insite::Errors::BrowserNotOpenError) => e
|
67
|
+
# raise e
|
68
|
+
# rescue => e
|
69
|
+
# raise(
|
70
|
+
# Insite::Errors::BrowserResponseError,
|
71
|
+
# <<~eos
|
72
|
+
# Browser check failed. The browser returned an #{e.class} (#{e}) when it was queried.
|
73
|
+
# Backtrace for the error:
|
74
|
+
# #{e.backtrace.join("\n")}
|
75
|
+
#
|
76
|
+
# eos
|
77
|
+
# )
|
78
|
+
# end
|
79
|
+
# elsif @site.browser.nil?
|
80
|
+
# raise(
|
81
|
+
# Insite::Errors::BrowserNotOpenError,
|
82
|
+
# "A browser has not been defined for the site. Try using Site#open to " \
|
83
|
+
# "start a browser.\n\n"
|
84
|
+
# )
|
85
|
+
# else
|
86
|
+
# raise(
|
87
|
+
# Insite::Errors::BrowserNotValidError,
|
88
|
+
# "Expected: Watir::Browser. Actual: #{@site.browser.class}.\n\n"
|
89
|
+
# )
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# end
|
93
|
+
# public
|
60
94
|
|
61
95
|
def update_object(hash_args = {})
|
62
96
|
rescues = [
|
@@ -12,27 +12,9 @@ module Insite
|
|
12
12
|
alias_method :update_page, :update_object
|
13
13
|
|
14
14
|
class << self
|
15
|
-
attr_reader :has_fragment, :page_attributes, :page_elements, :page_features, :page_url, :url_matcher, :url_template
|
15
|
+
attr_reader :has_fragment, :page_attributes, :page_elements, :page_features, :page_url, :url_matcher, :url_hash, :url_template
|
16
16
|
attr_accessor :component_elements
|
17
17
|
|
18
|
-
def describe
|
19
|
-
puts <<-EOF
|
20
|
-
Page Class:\t#{name} (#{__FILE__})
|
21
|
-
URL Template:\t#{@url_template.pattern}"
|
22
|
-
URL Matcher:\t#{@url_matcher || 'Not specified.'}
|
23
|
-
|
24
|
-
Contains user-defined logic for a single page.
|
25
|
-
|
26
|
-
Page Elements:\n#{@page_elements.sort.map { |x| " #{x} #{x.class.to_s.methodize}\n" }.join }
|
27
|
-
|
28
|
-
Components:\n#{@component_elements.sort.map { |x| " #{x} #{x.class.to_s.methodize}\n" }.join }
|
29
|
-
|
30
|
-
Features:\n#{@component_elements.sort.map { |x| " #{x} #{x.class.to_s.methodize}\n" }.join }
|
31
|
-
|
32
|
-
EOF
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
18
|
# Allows you to set special page attributes that affect page behavior. The two page
|
37
19
|
# attributes currently supported are :navigation_disabled and :page_template:
|
38
20
|
#
|
@@ -220,39 +202,20 @@ module Insite
|
|
220
202
|
regexp ? @url_matcher = regexp : nil
|
221
203
|
end
|
222
204
|
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
# use_features :footer, :sidebar
|
227
|
-
# end
|
228
|
-
#
|
229
|
-
# Then, once the page object has been initialized:
|
205
|
+
# def component_method(method_name, component_symbol, component_method, target_element)
|
206
|
+
# @component_methods ||= []
|
207
|
+
# @component_methods << method_name.to_sym unless @component_methods.include?(method_name.to_sym)
|
230
208
|
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
else
|
238
|
-
@page_features = args
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def component_method(method_name, component_symbol, component_method, target_element)
|
243
|
-
@component_methods ||= []
|
244
|
-
@component_methods << method_name.to_sym unless @component_methods.include?(method_name.to_sym)
|
245
|
-
|
246
|
-
define_method(method_name) do |*args, &block|
|
247
|
-
self.class.const_get(component_symbol.to_s.camelize)
|
248
|
-
.new(@site, @site.send(target_element))
|
249
|
-
.send(component_method, *args, &block)
|
250
|
-
end
|
251
|
-
end
|
209
|
+
# define_method(method_name) do |*args, &block|
|
210
|
+
# self.class.const_get(component_symbol.to_s.camelize)
|
211
|
+
# .new(@site, @site.send(target_element))
|
212
|
+
# .send(component_method, *args, &block)
|
213
|
+
# end
|
214
|
+
# end
|
252
215
|
end # Self.
|
253
216
|
|
254
|
-
def
|
255
|
-
|
217
|
+
def browser?
|
218
|
+
@site.browser?
|
256
219
|
end
|
257
220
|
|
258
221
|
def defined?
|
@@ -263,6 +226,10 @@ module Insite
|
|
263
226
|
@browser.driver
|
264
227
|
end
|
265
228
|
|
229
|
+
def driver?
|
230
|
+
browser?
|
231
|
+
end
|
232
|
+
|
266
233
|
def html
|
267
234
|
@browser.html
|
268
235
|
end
|
@@ -499,7 +466,6 @@ module Insite
|
|
499
466
|
end
|
500
467
|
|
501
468
|
@site.most_recent_page = self
|
502
|
-
self
|
503
469
|
end
|
504
470
|
end
|
505
471
|
end
|
@@ -12,27 +12,6 @@ module Insite
|
|
12
12
|
false
|
13
13
|
end
|
14
14
|
|
15
|
-
def describe
|
16
|
-
puts <<-EOF
|
17
|
-
Page Class:\t#{name} (#{__FILE__})
|
18
|
-
URL Template:\tNA
|
19
|
-
URL Matcher:\tNA
|
20
|
-
|
21
|
-
Page class for any page that hasn't been defined (or that Insite doesn't recognize.)
|
22
|
-
|
23
|
-
Note: If there is a page class that is defined for this page that isn't getting
|
24
|
-
loaded, try the following:
|
25
|
-
- Review the pages URL template for problems. A URL template is *not* an interpolated
|
26
|
-
string -- it just looks like one. See the documentation for more details.
|
27
|
-
- If the URL template seems to be designed correctly for loading the page, but the
|
28
|
-
page's URL changes after the load, you will need to look at adding a URL matcher,
|
29
|
-
which overrides the URL template for purposes of checking whether the page object
|
30
|
-
is matching the currently displayed page after it has been loaded.
|
31
|
-
|
32
|
-
Page Elements:\tNA
|
33
|
-
EOF
|
34
|
-
end
|
35
|
-
|
36
15
|
def driver
|
37
16
|
@browser.driver
|
38
17
|
end
|
@@ -50,13 +29,13 @@ module Insite
|
|
50
29
|
# TODO: Do the same cache check that's done for a defined page and reapply the
|
51
30
|
# method if the cache is updated and the new page DOES respond to the method.
|
52
31
|
def method_missing(mth, *args, &block)
|
53
|
-
raise NoMethodError, "Could not apply #{mth}. The current page
|
54
|
-
"recognized. Current URL #{@browser.url}"
|
32
|
+
raise NoMethodError, "Could not apply #{mth}. The current page couldn't " \
|
33
|
+
"be recognized. Current URL #{@browser.url}"
|
55
34
|
end
|
56
35
|
|
57
36
|
# Returns a Nokogiri object for the page HTML.
|
58
37
|
def nokogiri
|
59
|
-
|
38
|
+
Nokogiri::HTML(html)
|
60
39
|
end
|
61
40
|
|
62
41
|
# Similar to the method that you can call on a page object you've defined (but always
|