page_magic 0.10.0 → 0.11.0.alpha
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.
- data/.rspec +1 -0
- data/VERSION +1 -1
- data/lib/ext/string.rb +9 -0
- data/lib/page_magic/element.rb +54 -62
- data/lib/page_magic/element_context.rb +4 -4
- data/lib/page_magic/elements.rb +23 -44
- data/lib/page_magic/exceptions.rb +10 -0
- data/lib/page_magic/page_magic.rb +5 -31
- data/lib/page_magic/session.rb +10 -6
- data/lib/page_magic.rb +1 -1
- data/page_magic.gemspec +12 -7
- data/spec/element_context_spec.rb +25 -3
- data/spec/element_spec.rb +96 -21
- data/spec/member_methods_spec.rb +0 -22
- data/spec/{elements_spec.rb → page_magic/elements/elements_spec.rb} +76 -85
- data/spec/page_magic/usage/defining_page_elements_spec.rb +8 -0
- data/spec/page_magic/usage/defining_pages_spec.rb +88 -0
- data/spec/page_magic/usage/include_page_magic_spec.rb +20 -0
- data/spec/page_magic/usage/interacting_with_pages_spec.rb +56 -0
- data/spec/page_magic/usage/starting_a_session_spec.rb +63 -0
- data/spec/spec_helper.rb +35 -2
- metadata +15 -10
- data/lib/page_magic/section.rb +0 -105
- data/spec/page_magic_spec.rb +0 -168
- data/spec/section_spec.rb +0 -106
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require 'spec_helper'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.11.0.alpha
|
data/lib/ext/string.rb
ADDED
data/lib/page_magic/element.rb
CHANGED
@@ -1,43 +1,28 @@
|
|
1
|
-
require 'watir-webdriver'
|
2
1
|
module PageMagic
|
3
2
|
|
4
|
-
class UnsupportedSelectorException < Exception
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
3
|
class Element
|
4
|
+
attr_reader :type, :name, :selector, :browser_element
|
9
5
|
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
include AjaxSupport
|
14
|
-
|
15
|
-
attr_reader :type, :name, :selector, :before_hook, :after_hook, :browser_element, :locator
|
16
|
-
|
17
|
-
class << self
|
18
|
-
def default_before_hook
|
19
|
-
@default_before_hook ||= Proc.new {}
|
20
|
-
end
|
21
|
-
|
22
|
-
def default_after_hook
|
23
|
-
@default_after_hook ||= Proc.new {}
|
24
|
-
end
|
25
|
-
end
|
6
|
+
include AjaxSupport, Elements
|
26
7
|
|
27
8
|
def initialize name, parent_page_element, type=nil, selector=nil, &block
|
28
|
-
|
29
|
-
|
30
|
-
@browser_element = parent_page_element.browser_element
|
9
|
+
if selector.is_a?(Hash)
|
10
|
+
@selector = selector
|
31
11
|
else
|
32
|
-
@browser_element =
|
12
|
+
@browser_element = selector
|
33
13
|
end
|
34
14
|
|
35
|
-
@type = type
|
36
|
-
|
15
|
+
@parent_page_element, @type, @name = parent_page_element, type, name.to_s.downcase.to_sym
|
16
|
+
instance_eval &block if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
def selector selector=nil
|
20
|
+
return @selector unless selector
|
37
21
|
@selector = selector
|
22
|
+
end
|
38
23
|
|
39
|
-
|
40
|
-
|
24
|
+
def section?
|
25
|
+
!element_definitions.empty?
|
41
26
|
end
|
42
27
|
|
43
28
|
def session
|
@@ -45,50 +30,57 @@ module PageMagic
|
|
45
30
|
end
|
46
31
|
|
47
32
|
def before &block
|
33
|
+
return @before_hook unless block
|
48
34
|
@before_hook = block
|
49
35
|
end
|
50
36
|
|
51
37
|
def after &block
|
38
|
+
return @after_hook unless block
|
52
39
|
@after_hook = block
|
53
40
|
end
|
54
41
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
when :label
|
64
|
-
@browser_element.find_field(selector)
|
65
|
-
when :text
|
66
|
-
if @type == :link
|
67
|
-
@browser_element.find_link(selector)
|
68
|
-
elsif @type == :button
|
69
|
-
@browser_element.find_button(selector)
|
70
|
-
else
|
71
|
-
raise UnsupportedSelectorException
|
72
|
-
end
|
73
|
-
when :css
|
74
|
-
@browser_element.find(:css, selector)
|
75
|
-
else
|
76
|
-
raise UnsupportedSelectorException
|
77
|
-
|
42
|
+
def method_missing method, *args
|
43
|
+
begin
|
44
|
+
ElementContext.new(self, @browser_element, self, *args).send(method, args.first)
|
45
|
+
rescue ElementMissingException
|
46
|
+
begin
|
47
|
+
@browser_element.send(method, *args)
|
48
|
+
rescue
|
49
|
+
super
|
78
50
|
end
|
79
|
-
else
|
80
|
-
@browser_element
|
81
51
|
end
|
82
52
|
end
|
83
53
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
54
|
+
def browser_element *args
|
55
|
+
return @browser_element if @browser_element
|
56
|
+
raise UndefinedSelectorException, "Pass a selector/define one on the class" unless @selector
|
57
|
+
if @selector
|
58
|
+
method, selector = @selector.to_a.flatten
|
59
|
+
browser_element = @parent_page_element.browser_element
|
60
|
+
@browser_element = case method
|
61
|
+
when :id
|
62
|
+
browser_element.find("##{selector}")
|
63
|
+
when :xpath
|
64
|
+
browser_element.find(:xpath, selector)
|
65
|
+
when :name
|
66
|
+
browser_element.find("*[name='#{selector}']")
|
67
|
+
when :label
|
68
|
+
browser_element.find_field(selector)
|
69
|
+
when :text
|
70
|
+
if @type == :link
|
71
|
+
browser_element.find_link(selector)
|
72
|
+
elsif @type == :button
|
73
|
+
browser_element.find_button(selector)
|
74
|
+
else
|
75
|
+
raise UnsupportedSelectorException
|
76
|
+
end
|
77
|
+
when :css
|
78
|
+
browser_element.find(:css, selector)
|
79
|
+
else
|
80
|
+
raise UnsupportedSelectorException
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@browser_element
|
92
84
|
end
|
93
85
|
end
|
94
86
|
end
|
@@ -35,15 +35,15 @@ module PageMagic
|
|
35
35
|
element_locator = element_locator_factory.call(@page_element, *args)
|
36
36
|
end
|
37
37
|
|
38
|
-
result = element_locator.
|
38
|
+
result = element_locator.browser_element
|
39
39
|
|
40
|
-
return element_locator if element_locator.
|
40
|
+
return element_locator if element_locator.section? && action.nil?
|
41
41
|
|
42
42
|
[:set, :select_option, :unselect_option, :click].each do |action_method|
|
43
43
|
apply_hooks(page_element: result,
|
44
44
|
capybara_method: action_method,
|
45
|
-
before_hook: element_locator.
|
46
|
-
after_hook: element_locator.
|
45
|
+
before_hook: element_locator.before,
|
46
|
+
after_hook: element_locator.after,
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
data/lib/page_magic/elements.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'ext/string'
|
1
2
|
module PageMagic
|
2
3
|
module Elements
|
3
4
|
class InvalidElementNameException < Exception
|
@@ -24,67 +25,45 @@ module PageMagic
|
|
24
25
|
raise InvalidMethodNameException, "method name matches element name" if element_definitions[method]
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
28
|
def elements(browser_element, *args)
|
29
29
|
element_definitions.values.collect { |definition| definition.call(browser_element, *args) }
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
TYPES = [:element, :text_field, :button, :link, :checkbox, :select_list, :radios, :textarea, :section]
|
33
|
+
TYPES.each do |type|
|
34
|
+
define_method type do |*args, &block|
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
define_method field do |*args, &block|
|
39
|
-
name, selector = args
|
40
|
-
add_element_definition(name) do |browser_element|
|
41
|
-
case selector
|
42
|
-
when Hash, NilClass
|
43
|
-
Element.new(name, browser_element, field, selector, &block)
|
44
|
-
else
|
45
|
-
Element.new(name, selector, field, nil, &block)
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def section *args, &block
|
53
|
-
case args.first
|
54
|
-
when Symbol
|
36
|
+
first_arg = args.first
|
37
|
+
if first_arg.is_a?(Symbol)
|
55
38
|
name, selector = args
|
56
39
|
|
57
|
-
add_element_definition(name) do |
|
58
|
-
page_section =
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
page_section.parent_browser_element = parent_browser_element.browser_element
|
40
|
+
add_element_definition(name) do |*args_for_block|
|
41
|
+
page_section = PageMagic::Element.new name, args_for_block.delete_at(0), type, selector
|
42
|
+
page_section.instance_exec *args_for_block, &(block || Proc.new {})
|
43
|
+
page_section
|
44
|
+
end
|
63
45
|
|
64
|
-
|
65
|
-
|
66
|
-
page_section.selector selector
|
67
|
-
else
|
68
|
-
page_section.browser_element = selector
|
69
|
-
end
|
46
|
+
elsif first_arg < PageMagic::Element
|
47
|
+
section_class, name, selector = args
|
70
48
|
|
71
|
-
|
72
|
-
|
73
|
-
|
49
|
+
unless selector
|
50
|
+
selector = name
|
51
|
+
name = section_class.name.to_snake_case
|
74
52
|
end
|
75
|
-
|
76
|
-
section_class, name, selector = args
|
53
|
+
|
77
54
|
add_element_definition(name) do |parent_browser_element|
|
78
|
-
section_class.new(parent_browser_element,
|
55
|
+
section_class.new(name, parent_browser_element, :section, selector)
|
79
56
|
end
|
80
|
-
end
|
81
|
-
|
82
57
|
|
58
|
+
end
|
59
|
+
end
|
83
60
|
end
|
84
61
|
|
85
62
|
def add_element_definition name, &block
|
86
63
|
raise InvalidElementNameException, "duplicate page element defined" if element_definitions[name]
|
87
|
-
|
64
|
+
|
65
|
+
methods = respond_to?(:instance_methods) ? instance_methods : methods()
|
66
|
+
raise InvalidElementNameException, "a method already exists with this method name" if methods.find { |method| method == name }
|
88
67
|
|
89
68
|
element_definitions[name] = block
|
90
69
|
end
|
@@ -3,13 +3,11 @@ module PageMagic
|
|
3
3
|
|
4
4
|
include AjaxSupport
|
5
5
|
|
6
|
-
def initialize session=Capybara.current_session, options={}, &block
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@session = session
|
12
|
-
end
|
6
|
+
def initialize session=Session.new(Capybara.current_session), options={}, &block
|
7
|
+
|
8
|
+
@browser = session.raw_session
|
9
|
+
@session = session
|
10
|
+
|
13
11
|
@browser_element = @browser
|
14
12
|
navigate if options[:navigate_to_page]
|
15
13
|
block.call @browser if block
|
@@ -23,39 +21,15 @@ module PageMagic
|
|
23
21
|
@browser.refresh
|
24
22
|
end
|
25
23
|
|
26
|
-
def current_path
|
27
|
-
@browser.current_path
|
28
|
-
end
|
29
|
-
|
30
24
|
def text_on_page? text
|
31
25
|
text().downcase.include?(text.downcase)
|
32
26
|
end
|
33
27
|
|
34
|
-
def window_exists? title
|
35
|
-
raise "implement me"
|
36
|
-
end
|
37
|
-
|
38
|
-
def accept_popup
|
39
|
-
raise "implement me"
|
40
|
-
end
|
41
|
-
|
42
|
-
def alert_present?
|
43
|
-
raise "implement me"
|
44
|
-
end
|
45
|
-
|
46
|
-
def text_in_popup? text
|
47
|
-
raise "implement me"
|
48
|
-
end
|
49
|
-
|
50
28
|
def visit
|
51
29
|
@browser.visit self.class.url
|
52
30
|
self
|
53
31
|
end
|
54
32
|
|
55
|
-
def click element
|
56
|
-
self.send(element.downcase.gsub(" ", "_").to_sym)
|
57
|
-
end
|
58
|
-
|
59
33
|
def text
|
60
34
|
@browser.text
|
61
35
|
end
|
data/lib/page_magic/session.rb
CHANGED
@@ -1,27 +1,30 @@
|
|
1
1
|
require 'wait'
|
2
2
|
module PageMagic
|
3
3
|
class Session
|
4
|
-
|
5
|
-
attr_accessor :current_page
|
4
|
+
attr_accessor :current_page, :raw_session
|
6
5
|
|
7
6
|
def initialize browser
|
8
|
-
@
|
7
|
+
@raw_session = browser
|
9
8
|
end
|
10
9
|
|
11
10
|
def visit page
|
12
|
-
@
|
11
|
+
@raw_session.visit page.url
|
13
12
|
@current_page = page.new self
|
14
13
|
self
|
15
14
|
end
|
16
15
|
|
16
|
+
def current_path
|
17
|
+
@raw_session.current_path
|
18
|
+
end
|
19
|
+
|
17
20
|
def current_url
|
18
|
-
@
|
21
|
+
@raw_session.current_url
|
19
22
|
end
|
20
23
|
|
21
24
|
def move_to page_class
|
22
25
|
page_class = eval(page_class) if page_class.is_a?(String)
|
23
26
|
@current_page = page_class.new self
|
24
|
-
wait_until {
|
27
|
+
wait_until { raw_session.current_url == page_class.url }
|
25
28
|
end
|
26
29
|
|
27
30
|
def wait_until &block
|
@@ -32,5 +35,6 @@ module PageMagic
|
|
32
35
|
def method_missing name, *args, &block
|
33
36
|
@current_page.send(name, *args, &block)
|
34
37
|
end
|
38
|
+
|
35
39
|
end
|
36
40
|
end
|
data/lib/page_magic.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
|
2
2
|
require 'capybara'
|
3
|
+
require 'page_magic/exceptions'
|
3
4
|
require 'page_magic/browser'
|
4
5
|
require 'page_magic/session'
|
5
6
|
require 'page_magic/ajax_support'
|
@@ -7,7 +8,6 @@ require 'page_magic/elements'
|
|
7
8
|
require 'page_magic/element_context'
|
8
9
|
require 'page_magic/element'
|
9
10
|
require 'page_magic/page_magic'
|
10
|
-
require 'page_magic/section'
|
11
11
|
|
12
12
|
module PageMagic
|
13
13
|
class << self
|
data/page_magic.gemspec
CHANGED
@@ -5,17 +5,18 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "page_magic"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.11.0.alpha"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Leon Davis"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2014-03-05"
|
13
13
|
s.description = "Framework for modeling and interacting with webpages which wraps capybara"
|
14
14
|
s.email = "info@lad-tech.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.md"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
+
".rspec",
|
19
20
|
".ruby-gemset",
|
20
21
|
".ruby-version",
|
21
22
|
".travis.yml",
|
@@ -24,24 +25,28 @@ Gem::Specification.new do |s|
|
|
24
25
|
"README.md",
|
25
26
|
"Rakefile",
|
26
27
|
"VERSION",
|
28
|
+
"lib/ext/string.rb",
|
27
29
|
"lib/page_magic.rb",
|
28
30
|
"lib/page_magic/ajax_support.rb",
|
29
31
|
"lib/page_magic/browser.rb",
|
30
32
|
"lib/page_magic/element.rb",
|
31
33
|
"lib/page_magic/element_context.rb",
|
32
34
|
"lib/page_magic/elements.rb",
|
35
|
+
"lib/page_magic/exceptions.rb",
|
33
36
|
"lib/page_magic/page_magic.rb",
|
34
|
-
"lib/page_magic/section.rb",
|
35
37
|
"lib/page_magic/session.rb",
|
36
38
|
"page_magic.gemspec",
|
37
39
|
"spec/browser_spec.rb",
|
38
40
|
"spec/element_context_spec.rb",
|
39
41
|
"spec/element_spec.rb",
|
40
|
-
"spec/elements_spec.rb",
|
41
42
|
"spec/helpers/capybara.rb",
|
42
43
|
"spec/member_methods_spec.rb",
|
43
|
-
"spec/
|
44
|
-
"spec/
|
44
|
+
"spec/page_magic/elements/elements_spec.rb",
|
45
|
+
"spec/page_magic/usage/defining_page_elements_spec.rb",
|
46
|
+
"spec/page_magic/usage/defining_pages_spec.rb",
|
47
|
+
"spec/page_magic/usage/include_page_magic_spec.rb",
|
48
|
+
"spec/page_magic/usage/interacting_with_pages_spec.rb",
|
49
|
+
"spec/page_magic/usage/starting_a_session_spec.rb",
|
45
50
|
"spec/session_spec.rb",
|
46
51
|
"spec/spec_helper.rb"
|
47
52
|
]
|
@@ -22,7 +22,7 @@ describe 'Element Context' do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
let!(:session) do
|
25
|
-
double('session',
|
25
|
+
double('session', raw_session: double('browser'))
|
26
26
|
end
|
27
27
|
|
28
28
|
describe 'resolving field definitions' do
|
@@ -70,7 +70,7 @@ describe 'Element Context' do
|
|
70
70
|
page.visit
|
71
71
|
|
72
72
|
PageMagic::ElementContext.new(page, page.browser, self).click_next
|
73
|
-
page.current_path.should == '/page2'
|
73
|
+
page.session.current_path.should == '/page2'
|
74
74
|
page.text.should == 'page 2 content'
|
75
75
|
end
|
76
76
|
end
|
@@ -82,16 +82,38 @@ describe 'Element Context' do
|
|
82
82
|
elements_page.class_eval do
|
83
83
|
section :form do
|
84
84
|
selector css: '.form'
|
85
|
+
link :form_link, text: 'in a form'
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
88
89
|
page = elements_page.new
|
89
90
|
page.visit
|
90
91
|
|
91
|
-
PageMagic::ElementContext.new(page, page.browser, self).form
|
92
|
+
PageMagic::ElementContext.new(page, page.browser, self).form
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'they are clickable too' do
|
96
|
+
elements_page.class_eval do
|
97
|
+
section :section do
|
98
|
+
selector id: 'form_link'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
page = elements_page.new
|
103
|
+
page.visit
|
104
|
+
|
105
|
+
|
106
|
+
PageMagic::ElementContext.new(page, page.browser, self).click_section
|
107
|
+
page.session.current_path.should == '/page2'
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should delegate to page element if method not found' do
|
111
|
+
#TODO call page method, look for subelement, delagate to capybara object
|
92
112
|
end
|
93
113
|
end
|
94
114
|
|
115
|
+
|
116
|
+
|
95
117
|
describe 'hooks' do
|
96
118
|
|
97
119
|
it 'should execute a before and after action that gives access to the browser' do
|