page_magic 0.8.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +74 -0
- data/README.md +1 -0
- data/Rakefile +20 -0
- data/VERSION +1 -0
- data/lib/page_magic/ajax_support.rb +21 -0
- data/lib/page_magic/browser.rb +16 -0
- data/lib/page_magic/element_context.rb +81 -0
- data/lib/page_magic/page_element.rb +99 -0
- data/lib/page_magic/page_elements.rb +91 -0
- data/lib/page_magic/page_magic.rb +70 -0
- data/lib/page_magic/page_section.rb +101 -0
- data/lib/page_magic/session.rb +28 -0
- data/lib/page_magic/wait.rb +7 -0
- data/lib/page_magic.rb +55 -0
- data/page_magic.gemspec +80 -0
- data/spec/browser_spec.rb +33 -0
- data/spec/element_context_spec.rb +123 -0
- data/spec/helpers/capybara.rb +10 -0
- data/spec/helpers.rb +1 -0
- data/spec/member_methods_spec.rb +36 -0
- data/spec/page_element_spec.rb +80 -0
- data/spec/page_elements_spec.rb +202 -0
- data/spec/page_magic_spec.rb +143 -0
- data/spec/page_section_spec.rb +101 -0
- data/spec/session_spec.rb +64 -0
- data/spec/spec_helper.rb +45 -0
- metadata +159 -0
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
page_magic
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "watir-webdriver"
|
4
|
+
gem 'capybara'
|
5
|
+
gem 'wait'
|
6
|
+
|
7
|
+
group :test do
|
8
|
+
gem 'sinatra'
|
9
|
+
gem "rspec", require: 'rspec/core/rake_task'
|
10
|
+
gem "simplecov", require: false
|
11
|
+
end
|
12
|
+
|
13
|
+
group :development do
|
14
|
+
gem "jeweler", "~> 1.8.4"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
capybara (2.1.0)
|
5
|
+
mime-types (>= 1.16)
|
6
|
+
nokogiri (>= 1.3.3)
|
7
|
+
rack (>= 1.0.0)
|
8
|
+
rack-test (>= 0.5.4)
|
9
|
+
xpath (~> 2.0)
|
10
|
+
childprocess (0.3.9)
|
11
|
+
ffi (~> 1.0, >= 1.0.11)
|
12
|
+
diff-lcs (1.2.4)
|
13
|
+
ffi (1.8.1)
|
14
|
+
git (1.2.5)
|
15
|
+
jeweler (1.8.4)
|
16
|
+
bundler (~> 1.0)
|
17
|
+
git (>= 1.2.5)
|
18
|
+
rake
|
19
|
+
rdoc
|
20
|
+
json (1.7.7)
|
21
|
+
mime-types (1.25)
|
22
|
+
mini_portile (0.5.1)
|
23
|
+
multi_json (1.7.3)
|
24
|
+
nokogiri (1.6.0)
|
25
|
+
mini_portile (~> 0.5.0)
|
26
|
+
rack (1.5.2)
|
27
|
+
rack-protection (1.5.0)
|
28
|
+
rack
|
29
|
+
rack-test (0.6.2)
|
30
|
+
rack (>= 1.0)
|
31
|
+
rake (10.0.4)
|
32
|
+
rdoc (4.0.1)
|
33
|
+
json (~> 1.4)
|
34
|
+
rspec (2.14.1)
|
35
|
+
rspec-core (~> 2.14.0)
|
36
|
+
rspec-expectations (~> 2.14.0)
|
37
|
+
rspec-mocks (~> 2.14.0)
|
38
|
+
rspec-core (2.14.6)
|
39
|
+
rspec-expectations (2.14.3)
|
40
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
41
|
+
rspec-mocks (2.14.4)
|
42
|
+
rubyzip (0.9.9)
|
43
|
+
selenium-webdriver (2.32.1)
|
44
|
+
childprocess (>= 0.2.5)
|
45
|
+
multi_json (~> 1.0)
|
46
|
+
rubyzip
|
47
|
+
websocket (~> 1.0.4)
|
48
|
+
simplecov (0.7.1)
|
49
|
+
multi_json (~> 1.0)
|
50
|
+
simplecov-html (~> 0.7.1)
|
51
|
+
simplecov-html (0.7.1)
|
52
|
+
sinatra (1.4.3)
|
53
|
+
rack (~> 1.4)
|
54
|
+
rack-protection (~> 1.4)
|
55
|
+
tilt (~> 1.3, >= 1.3.4)
|
56
|
+
tilt (1.4.1)
|
57
|
+
wait (0.5.1)
|
58
|
+
watir-webdriver (0.6.4)
|
59
|
+
selenium-webdriver (>= 2.18.0)
|
60
|
+
websocket (1.0.7)
|
61
|
+
xpath (2.0.0)
|
62
|
+
nokogiri (~> 1.3)
|
63
|
+
|
64
|
+
PLATFORMS
|
65
|
+
ruby
|
66
|
+
|
67
|
+
DEPENDENCIES
|
68
|
+
capybara
|
69
|
+
jeweler (~> 1.8.4)
|
70
|
+
rspec
|
71
|
+
simplecov
|
72
|
+
sinatra
|
73
|
+
wait
|
74
|
+
watir-webdriver
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/Ladtech/page_magic.png)](https://travis-ci.org/Ladtech/page_magic)
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Bundler.require :test,:development
|
2
|
+
|
3
|
+
RSpec::Core::RakeTask.new(:spec) do
|
4
|
+
ENV['coverage'] = "true"
|
5
|
+
end
|
6
|
+
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = "page_magic"
|
9
|
+
gem.homepage = "https://github.com/ladtech/page_magic"
|
10
|
+
gem.license = "ruby"
|
11
|
+
gem.summary = "Framework for modeling and interacting with webpages"
|
12
|
+
gem.description = "Framework for modeling and interacting with webpages which wraps capybara"
|
13
|
+
gem.email = "info@lad-tech.com"
|
14
|
+
gem.authors = ["Leon Davis"]
|
15
|
+
gem.add_dependency "watir-webdriver"
|
16
|
+
end
|
17
|
+
|
18
|
+
Jeweler::RubygemsDotOrgTasks.new
|
19
|
+
|
20
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.8.8
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PageMagic
|
2
|
+
module AjaxSupport
|
3
|
+
def on_element_with_trigger css_selector, event, browser, &block
|
4
|
+
set_variable_on_event(browser, css_selector, event)
|
5
|
+
yield
|
6
|
+
wait_until(:timeout_after => 20.seconds, :retry_every => 1.second) do
|
7
|
+
event_triggered(browser, event)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def event_triggered(browser, variable)
|
12
|
+
browser.execute_script("return #{variable}_triggered")
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_variable_on_event(browser, element, event)
|
16
|
+
variable_name="#{event}_triggered"
|
17
|
+
browser.execute_script("#{variable_name}=false")
|
18
|
+
browser.execute_script("$('#{element}').on('#{event}', function(){#{variable_name}=true})")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module PageMagic
|
2
|
+
module Browser
|
3
|
+
class << self
|
4
|
+
attr_reader :browser
|
5
|
+
attr_accessor :session
|
6
|
+
|
7
|
+
def use browser
|
8
|
+
@browser = browser
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def browser
|
13
|
+
Browser.session ||= PageMagic.session(Browser.browser || :chrome)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module PageMagic
|
2
|
+
|
3
|
+
class ElementMissingException < Exception
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
class ElementContext
|
8
|
+
|
9
|
+
attr_reader :caller, :page_element
|
10
|
+
|
11
|
+
def initialize page_element, browser, caller, *args
|
12
|
+
@page_element = page_element
|
13
|
+
@browser = browser
|
14
|
+
@caller = caller
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing method, *args
|
18
|
+
return @caller.send(method, *args) if @executing_hooks
|
19
|
+
return @page_element.send(method, *args) if @page_element.methods.include?(method)
|
20
|
+
|
21
|
+
|
22
|
+
element_locator_factory = @page_element.element_definitions[method]
|
23
|
+
|
24
|
+
action = nil
|
25
|
+
unless element_locator_factory
|
26
|
+
action = resolve_action(method)
|
27
|
+
element_locator_factory = @page_element.element_definitions[method.to_s.gsub("#{action}_", '').to_sym]
|
28
|
+
end
|
29
|
+
|
30
|
+
raise ElementMissingException, "Could not find: #{method}" unless element_locator_factory
|
31
|
+
|
32
|
+
if args.empty?
|
33
|
+
element_locator = element_locator_factory.call(@page_element, nil)
|
34
|
+
else
|
35
|
+
element_locator = element_locator_factory.call(@page_element, *args)
|
36
|
+
end
|
37
|
+
|
38
|
+
result = element_locator.locate
|
39
|
+
|
40
|
+
return element_locator if element_locator.class.is_a? PageSection
|
41
|
+
|
42
|
+
[:set, :select_option, :unselect_option, :click].each do |action_method|
|
43
|
+
apply_hooks(page_element: result,
|
44
|
+
capybara_method: action_method,
|
45
|
+
before_hook: element_locator.before_hook,
|
46
|
+
after_hook: element_locator.after_hook,
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
action ? result.send(action) : result
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolve_action(field)
|
54
|
+
{/^click_/ => :click}.each do |prefix, action|
|
55
|
+
return action if field.to_s =~ prefix
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def apply_hooks(options)
|
60
|
+
_self = self
|
61
|
+
page_element, capybara_method = options[:page_element], options[:capybara_method]
|
62
|
+
|
63
|
+
original_method = page_element.method(capybara_method)
|
64
|
+
|
65
|
+
page_element.define_singleton_method capybara_method do |*arguments, &block|
|
66
|
+
_self.call_hook &options[:before_hook]
|
67
|
+
original_method.call *arguments, &block
|
68
|
+
_self.call_hook &options[:after_hook]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def call_hook &block
|
74
|
+
@executing_hooks = true
|
75
|
+
result = self.instance_exec @browser, &block
|
76
|
+
@executing_hooks = false
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'watir-webdriver'
|
2
|
+
module PageMagic
|
3
|
+
|
4
|
+
class UnsupportedSelectorException < Exception
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
class PageElement
|
9
|
+
|
10
|
+
class MissingLocatorOrSelector < Exception
|
11
|
+
end
|
12
|
+
|
13
|
+
include PageElements
|
14
|
+
include AjaxSupport
|
15
|
+
|
16
|
+
module ::Watir
|
17
|
+
SelectList = Select
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :type, :name, :selector, :before_hook, :after_hook, :browser_element, :locator
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def default_before_hook
|
24
|
+
@default_before_hook ||= Proc.new {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_after_hook
|
28
|
+
@default_after_hook ||= Proc.new {}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize name, parent_page_element, type=nil, selector=nil, &block
|
33
|
+
@parent_page_element = parent_page_element
|
34
|
+
if selector
|
35
|
+
@browser_element = parent_page_element.browser_element
|
36
|
+
else
|
37
|
+
@browser_element = parent_page_element
|
38
|
+
end
|
39
|
+
|
40
|
+
@type = type
|
41
|
+
@name = name.downcase.to_sym
|
42
|
+
@selector = selector
|
43
|
+
|
44
|
+
@before_hook, @after_hook = self.class.default_before_hook, self.class.default_after_hook
|
45
|
+
instance_eval &block if block_given?
|
46
|
+
end
|
47
|
+
|
48
|
+
def session
|
49
|
+
@parent_page_element.session
|
50
|
+
end
|
51
|
+
|
52
|
+
def before &block
|
53
|
+
@before_hook = block
|
54
|
+
end
|
55
|
+
|
56
|
+
def after &block
|
57
|
+
@after_hook = block
|
58
|
+
end
|
59
|
+
|
60
|
+
def locate *args
|
61
|
+
if @selector && @selector.is_a?(Hash)
|
62
|
+
method, selector = @selector.to_a.flatten
|
63
|
+
case method
|
64
|
+
when :id
|
65
|
+
@browser_element.find("##{selector}")
|
66
|
+
when :name
|
67
|
+
@browser_element.find("*[name='#{selector}']")
|
68
|
+
when :label
|
69
|
+
@browser_element.find_field(selector)
|
70
|
+
when :text
|
71
|
+
if @type == :link
|
72
|
+
@browser_element.find_link(selector)
|
73
|
+
elsif @type == :button
|
74
|
+
@browser_element.find_button(selector)
|
75
|
+
else
|
76
|
+
raise UnsupportedSelectorException
|
77
|
+
end
|
78
|
+
when :css
|
79
|
+
@browser_element.find(:css, selector)
|
80
|
+
else
|
81
|
+
raise UnsupportedSelectorException
|
82
|
+
|
83
|
+
end
|
84
|
+
else
|
85
|
+
@browser_element
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def == page_element
|
91
|
+
page_element.is_a?(PageElement) &&
|
92
|
+
@type == page_element.type &&
|
93
|
+
@name == page_element.name &&
|
94
|
+
@selector == page_element.selector
|
95
|
+
@before_hook == page_element.before_hook &&
|
96
|
+
@after_hook == page_element.after_hook
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module PageMagic
|
2
|
+
module PageElements
|
3
|
+
class InvalidElementNameException < Exception
|
4
|
+
end
|
5
|
+
|
6
|
+
class InvalidMethodNameException < Exception
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.extended clazz
|
10
|
+
clazz.class_eval do
|
11
|
+
attr_reader :browser_element
|
12
|
+
|
13
|
+
def elements browser_element, *args
|
14
|
+
self.class.elements browser_element, *args
|
15
|
+
end
|
16
|
+
|
17
|
+
def element_definitions
|
18
|
+
self.class.element_definitions
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_added method
|
25
|
+
raise InvalidMethodNameException, "method name matches element name" if element_definitions[method]
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def elements(browser_element, *args)
|
31
|
+
element_definitions.values.collect { |definition| definition.call(browser_element, *args) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def elements?
|
35
|
+
!element_definitions.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
ELEMENT_TYPES = [:element, :text_field, :button, :link, :checkbox, :select_list, :radios, :textarea]
|
39
|
+
ELEMENT_TYPES.each do |field|
|
40
|
+
define_method field do |*args, &block|
|
41
|
+
name, selector = args
|
42
|
+
add_element_definition(name) do |browser_element|
|
43
|
+
case selector
|
44
|
+
when Hash, NilClass
|
45
|
+
PageElement.new(name, browser_element, field, selector, &block)
|
46
|
+
else
|
47
|
+
PageElement.new(name, selector, field, nil, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def section *args, &block
|
55
|
+
case args.first
|
56
|
+
when Symbol
|
57
|
+
name, selector = args
|
58
|
+
|
59
|
+
add_element_definition(name) do |parent_browser_element, *args_for_section|
|
60
|
+
page_section = Class.new do
|
61
|
+
extend PageMagic::PageSection
|
62
|
+
end
|
63
|
+
|
64
|
+
page_section.parent_browser_element = parent_browser_element.browser_element
|
65
|
+
page_section.selector selector if selector
|
66
|
+
|
67
|
+
page_section.class_exec *args_for_section, &block
|
68
|
+
page_section.new(parent_browser_element, name, selector)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
section_class, name, selector = args
|
72
|
+
add_element_definition(name) do |parent_browser_element|
|
73
|
+
section_class.new(parent_browser_element, name, selector)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_element_definition name, &block
|
81
|
+
raise InvalidElementNameException, "duplicate page element defined" if element_definitions[name]
|
82
|
+
raise InvalidElementNameException, "a method already exists with this method name" if instance_methods.find { |method| method == name }
|
83
|
+
|
84
|
+
element_definitions[name] = block
|
85
|
+
end
|
86
|
+
|
87
|
+
def element_definitions
|
88
|
+
@element_definitions ||= {}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module PageMagic
|
2
|
+
attr_reader :browser, :session
|
3
|
+
|
4
|
+
include AjaxSupport
|
5
|
+
|
6
|
+
def initialize session=Capybara.current_session, options={}, &block
|
7
|
+
if session.is_a? Capybara::Session
|
8
|
+
@browser = session
|
9
|
+
else
|
10
|
+
@browser = session.browser
|
11
|
+
@session = session
|
12
|
+
end
|
13
|
+
@browser_element = @browser
|
14
|
+
navigate if options[:navigate_to_page]
|
15
|
+
block.call @browser if block
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
@browser.title
|
20
|
+
end
|
21
|
+
|
22
|
+
def refresh
|
23
|
+
@browser.refresh
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_path
|
27
|
+
@browser.current_path
|
28
|
+
end
|
29
|
+
|
30
|
+
def text_on_page? text
|
31
|
+
text().downcase.include?(text.downcase)
|
32
|
+
end
|
33
|
+
|
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
|
+
def visit
|
51
|
+
@browser.visit self.class.url
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def click element
|
56
|
+
self.send(element.downcase.gsub(" ", "_").to_sym)
|
57
|
+
end
|
58
|
+
|
59
|
+
def text
|
60
|
+
@browser.text
|
61
|
+
end
|
62
|
+
|
63
|
+
def method_missing method, *args
|
64
|
+
ElementContext.new(self, @browser, self).send(method, *args)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module PageMagic
|
2
|
+
module PageSection
|
3
|
+
|
4
|
+
module Location
|
5
|
+
def locate_in browser_element, selector
|
6
|
+
method, selector = selector.to_a.flatten
|
7
|
+
case method
|
8
|
+
when :id
|
9
|
+
browser_element.find("##{selector}")
|
10
|
+
when :css
|
11
|
+
browser_element.find(:css, selector)
|
12
|
+
else
|
13
|
+
raise UnsupportedSelectorException
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class UndefinedSelectorException < Exception
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def extended clazz
|
23
|
+
clazz.extend(PageElements)
|
24
|
+
clazz.class_eval do
|
25
|
+
attr_reader :name, :selector
|
26
|
+
class << self
|
27
|
+
def selector selector=nil
|
28
|
+
return @selector unless selector
|
29
|
+
|
30
|
+
if @parent_browser_element
|
31
|
+
@browser_element = locate_in @parent_browser_element, selector
|
32
|
+
end
|
33
|
+
|
34
|
+
@selector = selector
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :parent_browser_element, :browser_element
|
38
|
+
end
|
39
|
+
|
40
|
+
include Location
|
41
|
+
extend Location
|
42
|
+
|
43
|
+
def initialize parent_page_element, name=nil, selector=self.class.selector
|
44
|
+
|
45
|
+
@selector = selector
|
46
|
+
@parent_page_element = parent_page_element
|
47
|
+
|
48
|
+
@selector = selector ? selector : self.class.selector
|
49
|
+
|
50
|
+
raise UndefinedSelectorException, "Pass a selector to the constructor/define one the class" unless @selector
|
51
|
+
@browser_element = locate_in(@parent_page_element.browser_element, @selector)
|
52
|
+
if name
|
53
|
+
@name = name
|
54
|
+
else
|
55
|
+
@name = underscore(self.class.name).to_sym
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def session
|
62
|
+
@parent_page_element.session
|
63
|
+
end
|
64
|
+
|
65
|
+
# TODO test this
|
66
|
+
def locate *args
|
67
|
+
@browser_element
|
68
|
+
end
|
69
|
+
|
70
|
+
#TODO - consolidate this
|
71
|
+
def method_missing method, *args
|
72
|
+
begin
|
73
|
+
ElementContext.new(self, @browser_element, self, *args).send(method, args.first)
|
74
|
+
rescue ElementMissingException
|
75
|
+
begin
|
76
|
+
@browser_element.send(method, *args)
|
77
|
+
rescue
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def underscore string
|
87
|
+
string.gsub(/::/, '/').
|
88
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
89
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
90
|
+
tr("-", "_").
|
91
|
+
downcase
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PageMagic
|
2
|
+
class Session
|
3
|
+
attr_reader :browser
|
4
|
+
attr_accessor :current_page
|
5
|
+
|
6
|
+
include WaitUntil
|
7
|
+
|
8
|
+
def initialize browser
|
9
|
+
@browser = browser
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit page
|
13
|
+
@browser.visit page.url
|
14
|
+
@current_page = page.new self
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def move_to page_class
|
19
|
+
page_class = eval(page_class) if page_class.is_a?(String)
|
20
|
+
@current_page = page_class.new self
|
21
|
+
wait.until { browser.current_url == page_class.url }
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing name, *args, &block
|
25
|
+
@current_page.send(name, *args, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|