page_magic 1.0.0.alpha17 → 1.0.0.alpha18
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +4 -0
- data/.pullreview.yml +14 -0
- data/.rubocop.yml +0 -3
- data/.simplecov +5 -0
- data/.yardopts +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +35 -5
- data/README.md +4 -3
- data/VERSION +1 -1
- data/circle.yml +3 -0
- data/lib/page_magic/driver.rb +1 -0
- data/lib/page_magic/drivers/poltergeist.rb +3 -7
- data/lib/page_magic/drivers/rack_test.rb +2 -6
- data/lib/page_magic/drivers/selenium.rb +3 -7
- data/lib/page_magic/drivers.rb +4 -0
- data/lib/page_magic/element/method_observer.rb +7 -0
- data/lib/page_magic/element/query.rb +7 -1
- data/lib/page_magic/element/selector.rb +7 -0
- data/lib/page_magic/element/selector_methods.rb +1 -0
- data/lib/page_magic/element.rb +8 -11
- data/lib/page_magic/element_context.rb +4 -8
- data/lib/page_magic/elements.rb +44 -19
- data/lib/page_magic/exceptions.rb +10 -3
- data/lib/page_magic/instance_methods.rb +48 -0
- data/lib/page_magic/session.rb +49 -14
- data/lib/page_magic.rb +11 -15
- data/spec/page_magic/drivers/poltergeist_spec.rb +4 -6
- data/spec/page_magic/drivers/selenium_spec.rb +9 -11
- data/spec/page_magic/drivers_spec.rb +0 -1
- data/spec/page_magic/element_context_spec.rb +5 -5
- data/spec/page_magic/instance_methods_spec.rb +63 -0
- data/spec/page_magic/session_spec.rb +7 -7
- data/spec/spec_helper.rb +3 -2
- metadata +64 -4
- data/lib/page_magic/page_magic.rb +0 -40
- data/spec/page_magic/page_magic_spec.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57c321555c03ce3b8a6a43d895ffd657eca3c5ae
|
4
|
+
data.tar.gz: f656f163ed661b0b48ffbc5b2b2d30f5db777beb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cd81bb246ed5a267265db1ab31d8861a772c9fa54ac000e0d5dd4ac9340a180a0c047876fe28bd2cbf3a58e29840b342f221c15f1f13564f6486dcc0b1e2806
|
7
|
+
data.tar.gz: 8957aa92ef4ae0dc088fed4d4bf7d13feae4118064b12270add171fe52f0fda423fa8787fcef5b1112b526171bc308676bdc2d9f40c79502da928250b1c8a3a1
|
data/.codeclimate.yml
ADDED
data/.pullreview.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
languages:
|
3
|
+
- ruby
|
4
|
+
rules:
|
5
|
+
test_infection:
|
6
|
+
except:
|
7
|
+
- 'lib/page_magic/exceptions*'
|
8
|
+
missing_class_documentation:
|
9
|
+
except:
|
10
|
+
- 'lib/page_magic/element/query.rb'
|
11
|
+
- 'lib/page_magic/element/selector.rb'
|
12
|
+
- 'lib/page_magic/element/method_observer.rb'
|
13
|
+
- 'lib/page_magic/element.rb'
|
14
|
+
- 'lib/page_magic/session.rb'
|
data/.rubocop.yml
CHANGED
data/.simplecov
CHANGED
data/.yardopts
ADDED
data/Gemfile
CHANGED
@@ -10,9 +10,15 @@ group :test do
|
|
10
10
|
gem 'rspec', require: 'rspec/core/rake_task'
|
11
11
|
gem 'simplecov', require: false
|
12
12
|
gem 'poltergeist'
|
13
|
+
gem 'codeclimate-test-reporter', group: :test, require: nil
|
14
|
+
gem 'pullreview-coverage', require: false
|
13
15
|
end
|
14
16
|
|
15
17
|
group :development do
|
16
18
|
gem 'jeweler'
|
17
19
|
gem 'rubocop', require: 'rubocop/rake_task'
|
20
|
+
gem 'pry-byebug'
|
21
|
+
gem 'yard'
|
22
|
+
gem 'redcarpet'
|
23
|
+
gem 'github-markup'
|
18
24
|
end
|
data/Gemfile.lock
CHANGED
@@ -12,20 +12,29 @@ GEM
|
|
12
12
|
astrolabe (1.3.1)
|
13
13
|
parser (~> 2.2)
|
14
14
|
builder (3.2.2)
|
15
|
+
byebug (5.0.0)
|
16
|
+
columnize (= 0.9.0)
|
15
17
|
capybara (2.1.0)
|
16
18
|
mime-types (>= 1.16)
|
17
19
|
nokogiri (>= 1.3.3)
|
18
20
|
rack (>= 1.0.0)
|
19
21
|
rack-test (>= 0.5.4)
|
20
22
|
xpath (~> 2.0)
|
23
|
+
certifi (2015.08.10)
|
21
24
|
childprocess (0.3.9)
|
22
25
|
ffi (~> 1.0, >= 1.0.11)
|
23
26
|
cliver (0.2.2)
|
27
|
+
codeclimate-test-reporter (0.4.8)
|
28
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
29
|
+
coderay (1.1.0)
|
30
|
+
columnize (0.9.0)
|
24
31
|
diff-lcs (1.2.5)
|
32
|
+
docile (1.1.5)
|
25
33
|
faraday (0.8.9)
|
26
34
|
multipart-post (~> 1.2.0)
|
27
35
|
ffi (1.9.3)
|
28
36
|
git (1.2.6)
|
37
|
+
github-markup (1.4.0)
|
29
38
|
github_api (0.10.2)
|
30
39
|
addressable
|
31
40
|
faraday (~> 0.8.7)
|
@@ -48,10 +57,11 @@ GEM
|
|
48
57
|
json (1.8.1)
|
49
58
|
jwt (0.1.11)
|
50
59
|
multi_json (>= 1.5)
|
60
|
+
method_source (0.8.2)
|
51
61
|
mime-types (1.25)
|
52
62
|
mini_portile (0.5.1)
|
53
63
|
minitest (5.7.0)
|
54
|
-
multi_json (1.
|
64
|
+
multi_json (1.11.2)
|
55
65
|
multi_xml (0.5.5)
|
56
66
|
multipart-post (1.2.0)
|
57
67
|
nokogiri (1.6.0)
|
@@ -70,6 +80,16 @@ GEM
|
|
70
80
|
multi_json (~> 1.0)
|
71
81
|
websocket-driver (>= 0.2.0)
|
72
82
|
powerpack (0.1.1)
|
83
|
+
pry (0.10.3)
|
84
|
+
coderay (~> 1.1.0)
|
85
|
+
method_source (~> 0.8.1)
|
86
|
+
slop (~> 3.4)
|
87
|
+
pry-byebug (3.2.0)
|
88
|
+
byebug (~> 5.0)
|
89
|
+
pry (~> 0.10)
|
90
|
+
pullreview-coverage (0.0.5)
|
91
|
+
certifi
|
92
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
73
93
|
rack (1.5.2)
|
74
94
|
rack-protection (1.5.0)
|
75
95
|
rack
|
@@ -79,6 +99,7 @@ GEM
|
|
79
99
|
rake (10.2.2)
|
80
100
|
rdoc (4.1.1)
|
81
101
|
json (~> 1.4)
|
102
|
+
redcarpet (3.3.3)
|
82
103
|
rspec (3.3.0)
|
83
104
|
rspec-core (~> 3.3.0)
|
84
105
|
rspec-expectations (~> 3.3.0)
|
@@ -105,14 +126,16 @@ GEM
|
|
105
126
|
multi_json (~> 1.0)
|
106
127
|
rubyzip (< 1.0.0)
|
107
128
|
websocket (~> 1.0.4)
|
108
|
-
simplecov (0.
|
109
|
-
|
110
|
-
|
111
|
-
|
129
|
+
simplecov (0.10.0)
|
130
|
+
docile (~> 1.1.0)
|
131
|
+
json (~> 1.8)
|
132
|
+
simplecov-html (~> 0.10.0)
|
133
|
+
simplecov-html (0.10.0)
|
112
134
|
sinatra (1.4.3)
|
113
135
|
rack (~> 1.4)
|
114
136
|
rack-protection (~> 1.4)
|
115
137
|
tilt (~> 1.3, >= 1.3.4)
|
138
|
+
slop (3.6.0)
|
116
139
|
thread_safe (0.3.5)
|
117
140
|
tilt (1.4.1)
|
118
141
|
tzinfo (1.2.2)
|
@@ -124,6 +147,7 @@ GEM
|
|
124
147
|
websocket-driver (0.3.0)
|
125
148
|
xpath (2.0.0)
|
126
149
|
nokogiri (~> 1.3)
|
150
|
+
yard (0.8.7.6)
|
127
151
|
|
128
152
|
PLATFORMS
|
129
153
|
ruby
|
@@ -131,11 +155,17 @@ PLATFORMS
|
|
131
155
|
DEPENDENCIES
|
132
156
|
activesupport
|
133
157
|
capybara
|
158
|
+
codeclimate-test-reporter
|
159
|
+
github-markup
|
134
160
|
jeweler
|
135
161
|
poltergeist
|
162
|
+
pry-byebug
|
163
|
+
pullreview-coverage
|
164
|
+
redcarpet
|
136
165
|
rspec
|
137
166
|
rubocop
|
138
167
|
simplecov
|
139
168
|
sinatra
|
140
169
|
wait
|
141
170
|
watir-webdriver
|
171
|
+
yard
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[](https://codeclimate.com/github/Ladtech/page_magic) [](https://codeclimate.com/github/Ladtech/page_magic/coverage) [](https://www.pullreview.com/github/Ladtech/page_magic/reviews/master)
|
1
2
|
#PageMagic
|
2
3
|
PageMagic is an API for testing web applications.
|
3
4
|
|
@@ -33,7 +34,7 @@ What we really want to write is something like
|
|
33
34
|
```ruby
|
34
35
|
test_subject = send_test_mail('test@21st-century-mail.com')
|
35
36
|
#Visit your site using a PageMagic session we prepared earlier
|
36
|
-
session.visit(LoginPage
|
37
|
+
session.visit(LoginPage)
|
37
38
|
|
38
39
|
#Login using some handy helper method on our page object
|
39
40
|
session.login('username', 'password')
|
@@ -51,7 +52,7 @@ fail "message is still there!" if session.message(subject: test_subject).exists?
|
|
51
52
|
## Starting a session
|
52
53
|
To start a PageMagic session simply decide what browser you want to use and pass it to PageMagic's `.session` method
|
53
54
|
```ruby
|
54
|
-
session = PageMagic.session(browser: :chrome)
|
55
|
+
session = PageMagic.session(browser: :chrome, url: 'https://21st-century-mail.com')
|
55
56
|
```
|
56
57
|
Out of the box, PageMagic knows how to work with:
|
57
58
|
- Chrome and Firefox
|
@@ -196,7 +197,7 @@ end
|
|
196
197
|
PageMagic.drivers.register Webkit
|
197
198
|
|
198
199
|
#3. Use registered driver
|
199
|
-
session = PageMagic.session(browser: webkit)
|
200
|
+
session = PageMagic.session(browser: webkit, url: 'https://21st-century-mail.com')
|
200
201
|
```
|
201
202
|
##What else can you do with PageMagic?
|
202
203
|
PageMagic has lots of other useful features. I'm writing up the documentation so check back here soon!
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.alpha18
|
data/circle.yml
ADDED
data/lib/page_magic/driver.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require 'capybara/poltergeist'
|
5
|
-
Capybara::Poltergeist::Driver.new(app, options)
|
6
|
-
end
|
7
|
-
end
|
1
|
+
PageMagic::Drivers::Poltergeist = PageMagic::Driver.new(:poltergeist) do |app, options|
|
2
|
+
require 'capybara/poltergeist'
|
3
|
+
Capybara::Poltergeist::Driver.new(app, options)
|
8
4
|
end
|
@@ -1,7 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
RackTest = Driver.new(:rack_test) do |app, options|
|
4
|
-
Capybara::RackTest::Driver.new(app, options)
|
5
|
-
end
|
6
|
-
end
|
1
|
+
PageMagic::Drivers::RackTest = PageMagic::Driver.new(:rack_test) do |app, options|
|
2
|
+
Capybara::RackTest::Driver.new(app, options)
|
7
3
|
end
|
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require 'watir-webdriver'
|
5
|
-
Capybara::Selenium::Driver.new(app, options.dup.merge(browser: browser))
|
6
|
-
end
|
7
|
-
end
|
1
|
+
PageMagic::Drivers::Selenium = PageMagic::Driver.new(:chrome, :firefox) do |app, options, browser|
|
2
|
+
require 'watir-webdriver'
|
3
|
+
Capybara::Selenium::Driver.new(app, options.dup.merge(browser: browser))
|
8
4
|
end
|
data/lib/page_magic/drivers.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'page_magic/driver'
|
2
2
|
module PageMagic
|
3
|
+
# class Drivers - creates an object that can be used to hold driver definitions
|
4
|
+
# These PageMagic gets the user's chosen driver from this object.
|
3
5
|
class Drivers
|
4
6
|
def all
|
5
7
|
@all ||= []
|
@@ -13,6 +15,8 @@ module PageMagic
|
|
13
15
|
all.find { |driver| driver.support?(browser) }
|
14
16
|
end
|
15
17
|
|
18
|
+
# Loads drivers defined in files at the given path
|
19
|
+
# @param [String] path where the drivers are located
|
16
20
|
def load(path = "#{__dir__}/drivers")
|
17
21
|
require 'active_support/inflector'
|
18
22
|
|
@@ -1,10 +1,17 @@
|
|
1
1
|
module PageMagic
|
2
2
|
class Element
|
3
|
+
# module MethodObserver - adds methods to check if a methods have been added.
|
3
4
|
module MethodObserver
|
5
|
+
# Hook called by ruby when a singleton method is added.
|
6
|
+
#
|
7
|
+
# @param [String] arg name of the method added
|
4
8
|
def singleton_method_added(arg)
|
5
9
|
@singleton_methods_added = true unless arg == :singleton_method_added
|
6
10
|
end
|
7
11
|
|
12
|
+
# returns true if a singleton method has been added
|
13
|
+
#
|
14
|
+
# @return [Boolean]
|
8
15
|
def singleton_methods_added?
|
9
16
|
@singleton_methods_added == true
|
10
17
|
end
|
@@ -4,9 +4,11 @@ module PageMagic
|
|
4
4
|
# - requirements on element type
|
5
5
|
# - selection criteria, modeled through the Selector class
|
6
6
|
# - options
|
7
|
-
|
8
7
|
class Query
|
9
8
|
class << self
|
9
|
+
# Find a query using it's name
|
10
|
+
# @param [Symbol] type the name of the required query in snakecase format
|
11
|
+
# @return [Query] returns the predefined query with the given name
|
10
12
|
def find(type)
|
11
13
|
query = constants.find { |constant| constant.to_s.downcase == type.to_s.downcase }
|
12
14
|
return ELEMENT unless query
|
@@ -21,6 +23,10 @@ module PageMagic
|
|
21
23
|
@type = type
|
22
24
|
end
|
23
25
|
|
26
|
+
# Build query parameters for Capybara's find method
|
27
|
+
# @param [Hash] locator the location method e.g. text: 'button text'
|
28
|
+
# @param [Hash] options additional options to be provided to Capybara. e.g. count: 3
|
29
|
+
# @return [Array] list of compatible capybara query parameters.
|
24
30
|
def build(locator, options = {})
|
25
31
|
[].tap do |array|
|
26
32
|
selector = Selector.find(locator.keys.first)
|
@@ -3,6 +3,10 @@ module PageMagic
|
|
3
3
|
# class Selector - models the selection criteria understood by Capybara
|
4
4
|
class Selector
|
5
5
|
class << self
|
6
|
+
# Find a Selecor using it's name
|
7
|
+
# @param [Symbol] name the name of the required Selector in snakecase format. See class constants for available
|
8
|
+
# selectors
|
9
|
+
# @return [Selector] returns the predefined selector with the given name
|
6
10
|
def find(name)
|
7
11
|
selector = constants.find { |constant| constant.to_s.downcase == name.to_s.downcase }
|
8
12
|
fail UnsupportedCriteriaException unless selector
|
@@ -10,6 +14,9 @@ module PageMagic
|
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
17
|
+
# Build selector query parameters for Capybara's find method
|
18
|
+
# @param [Symbol] element_type the type of browser element being found. e.g :link
|
19
|
+
# @param [Hash] locator the selection method and its parameter. E.g. text: 'click me'
|
13
20
|
def build(element_type, locator)
|
14
21
|
[].tap do |array|
|
15
22
|
array << element_type if supports_type
|
data/lib/page_magic/element.rb
CHANGED
@@ -3,19 +3,15 @@ require 'page_magic/element/selector_methods'
|
|
3
3
|
require 'page_magic/element/selector'
|
4
4
|
require 'page_magic/element/query'
|
5
5
|
module PageMagic
|
6
|
+
# class Element - represents an element in a html page.
|
6
7
|
class Element
|
7
8
|
EVENT_TYPES = [:set, :select, :select_option, :unselect_option, :click]
|
8
9
|
DEFAULT_HOOK = proc {}.freeze
|
10
|
+
|
9
11
|
attr_reader :type, :name, :parent_page_element, :browser_element
|
10
12
|
|
11
13
|
include Elements, MethodObserver, SelectorMethods
|
12
|
-
extend SelectorMethods
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def inherited(clazz)
|
16
|
-
clazz.extend(Elements)
|
17
|
-
end
|
18
|
-
end
|
14
|
+
extend Elements, SelectorMethods
|
19
15
|
|
20
16
|
def initialize(name, parent_page_element, type: :element, selector: {}, browser_element: nil, &block)
|
21
17
|
@browser_element = browser_element
|
@@ -26,6 +22,7 @@ module PageMagic
|
|
26
22
|
@parent_page_element = parent_page_element
|
27
23
|
@type = type
|
28
24
|
@name = name.to_s.downcase.to_sym
|
25
|
+
@element_definitions = self.class.element_definitions.dup
|
29
26
|
expand(&block) if block
|
30
27
|
end
|
31
28
|
|
@@ -53,7 +50,7 @@ module PageMagic
|
|
53
50
|
end
|
54
51
|
|
55
52
|
def method_missing(method, *args, &block)
|
56
|
-
ElementContext.new(self
|
53
|
+
ElementContext.new(self).send(method, args.first, &block)
|
57
54
|
rescue ElementMissingException
|
58
55
|
begin
|
59
56
|
return browser_element.send(method, *args, &block) if browser_element.respond_to?(method)
|
@@ -74,7 +71,7 @@ module PageMagic
|
|
74
71
|
|
75
72
|
query = Query.find(type).build(query_selector, query_options)
|
76
73
|
|
77
|
-
@browser_element = parent_browser_element.
|
74
|
+
@browser_element = parent_browser_element.find(*query).tap do |raw_element|
|
78
75
|
wrap_events(raw_element)
|
79
76
|
end
|
80
77
|
end
|
@@ -95,8 +92,8 @@ module PageMagic
|
|
95
92
|
selector.dup.delete_if { |key, _value| key == selector.keys.first }
|
96
93
|
end
|
97
94
|
|
98
|
-
def element_context
|
99
|
-
ElementContext.new(self
|
95
|
+
def element_context
|
96
|
+
ElementContext.new(self)
|
100
97
|
end
|
101
98
|
|
102
99
|
def wrap_events(raw_element)
|
@@ -1,17 +1,13 @@
|
|
1
1
|
module PageMagic
|
2
|
-
class
|
3
|
-
end
|
4
|
-
|
2
|
+
# class ElementContext - resolves which element definition to use when accessing the browser.
|
5
3
|
class ElementContext
|
6
|
-
|
7
|
-
|
8
|
-
attr_reader :caller, :page_element
|
4
|
+
attr_reader :page_element
|
9
5
|
|
10
|
-
def initialize(page_element
|
6
|
+
def initialize(page_element)
|
11
7
|
@page_element = page_element
|
12
|
-
@caller = caller
|
13
8
|
end
|
14
9
|
|
10
|
+
# acts as proxy to element defintions defined on @page_element
|
15
11
|
def method_missing(method, *args, &block)
|
16
12
|
return page_element.send(method, *args, &block) if page_element.methods.include?(method)
|
17
13
|
|
data/lib/page_magic/elements.rb
CHANGED
@@ -1,28 +1,51 @@
|
|
1
1
|
require 'active_support/inflector'
|
2
2
|
module PageMagic
|
3
|
+
# module Elements - contains methods that add element definitions to the objects it is mixed in to
|
3
4
|
module Elements
|
4
5
|
INVALID_METHOD_NAME_MSG = 'a method already exists with this method name'
|
6
|
+
TYPES = [:text_field, :button, :link, :checkbox, :select_list, :radios, :textarea]
|
5
7
|
|
6
|
-
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def self.extended(clazz)
|
13
|
-
clazz.class_eval do
|
14
|
-
include InstanceOnlyMethods
|
8
|
+
class << self
|
9
|
+
def included(clazz)
|
10
|
+
def clazz.inherited(clazz)
|
11
|
+
clazz.element_definitions.merge!(element_definitions)
|
12
|
+
end
|
15
13
|
end
|
16
|
-
|
17
|
-
|
18
|
-
def method_added(method)
|
19
|
-
fail InvalidMethodNameException, 'method name matches element name' if element_definitions[method]
|
14
|
+
alias_method :extended, :included
|
20
15
|
end
|
21
16
|
|
22
17
|
def elements(browser_element, *args)
|
23
18
|
element_definitions.values.collect { |definition| definition.call(browser_element, *args) }
|
24
19
|
end
|
25
20
|
|
21
|
+
# Creates an element defintion.
|
22
|
+
# Element defintions contain specifications for locating them and other sub elements.
|
23
|
+
# if a block is specified then it will be executed against the element defintion.
|
24
|
+
# This method is aliased to each of the names specified in {TYPES TYPES}
|
25
|
+
# @example
|
26
|
+
# element :widget, id: 'widget' do
|
27
|
+
# link :next, text: 'next'
|
28
|
+
# end
|
29
|
+
# @overload element(name, selector, &block)
|
30
|
+
# @param [Symbol] name the name of the element.
|
31
|
+
# @param [Hash] selector a key value pair defining the method for locating this element
|
32
|
+
# @option selector [String] :text text contained within the element
|
33
|
+
# @option selector [String] :css css selector
|
34
|
+
# @option selector [String] :id the id of the element
|
35
|
+
# @option selector [String] :name the value of the name attribute belonging to the element
|
36
|
+
# @option selector [String] :label value of the label tied to the require field
|
37
|
+
# @overload element(element_class, &block)
|
38
|
+
# @param [ElementClass] element_class a custom class of element that inherits {Element}.
|
39
|
+
# the name of the element is derived from the class name. the Class name coverted to snakecase.
|
40
|
+
# The selector must be defined on the class itself.
|
41
|
+
# @overload element(name, element_class, &block)
|
42
|
+
# @param [Symbol] name the name of the element.
|
43
|
+
# @param [ElementClass] element_class a custom class of element that inherits {Element}.
|
44
|
+
# The selector must be defined on the class itself.
|
45
|
+
# @overload element(name, element_class, selector, &block)
|
46
|
+
# @param [Symbol] name the name of the element.
|
47
|
+
# @param [ElementClass] element_class a custom class of element that inherits {Element}.
|
48
|
+
# @param [Hash] selector a key value pair defining the method for locating this element. See above for details
|
26
49
|
def element(*args, &block)
|
27
50
|
block ||= proc {}
|
28
51
|
|
@@ -38,10 +61,14 @@ module PageMagic
|
|
38
61
|
end
|
39
62
|
end
|
40
63
|
|
41
|
-
TYPES = [:text_field, :button, :link, :checkbox, :select_list, :radios, :textarea]
|
42
|
-
|
43
64
|
TYPES.each { |type| alias_method type, :element }
|
44
65
|
|
66
|
+
def element_definitions
|
67
|
+
@element_definitions ||= {}
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
45
72
|
def add_element_definition(name, &block)
|
46
73
|
fail InvalidElementNameException, 'duplicate page element defined' if element_definitions[name]
|
47
74
|
|
@@ -51,12 +78,10 @@ module PageMagic
|
|
51
78
|
element_definitions[name] = block
|
52
79
|
end
|
53
80
|
|
54
|
-
def
|
55
|
-
|
81
|
+
def method_added(method)
|
82
|
+
fail InvalidMethodNameException, 'method name matches element name' if element_definitions[method]
|
56
83
|
end
|
57
84
|
|
58
|
-
private
|
59
|
-
|
60
85
|
def remove_argument(args, clazz)
|
61
86
|
argument = args.find { |arg| arg.is_a?(clazz) }
|
62
87
|
args.delete(argument)
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module PageMagic
|
2
2
|
class UnsupportedSelectorException < Exception
|
3
3
|
end
|
4
|
-
class UndefinedSelectorException < Exception
|
5
|
-
end
|
6
4
|
|
7
|
-
class
|
5
|
+
class UndefinedSelectorException < Exception
|
8
6
|
end
|
9
7
|
|
10
8
|
class InvalidElementNameException < Exception
|
@@ -15,4 +13,13 @@ module PageMagic
|
|
15
13
|
|
16
14
|
class UnsupportedCriteriaException < Exception
|
17
15
|
end
|
16
|
+
|
17
|
+
class ElementMissingException < Exception
|
18
|
+
end
|
19
|
+
|
20
|
+
class InvalidURLException < Exception
|
21
|
+
end
|
22
|
+
|
23
|
+
class UnspportedBrowserException < Exception
|
24
|
+
end
|
18
25
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module PageMagic
|
2
|
+
# module InstanceMethods - provides instance level methods for page objects
|
3
|
+
module InstanceMethods
|
4
|
+
attr_reader :browser, :session, :browser_element
|
5
|
+
|
6
|
+
# Creates a new instance
|
7
|
+
# @param [Session] session session that provides gateway to the browser throw the users chosen browser
|
8
|
+
def initialize(session = Session.new(Capybara.current_session))
|
9
|
+
@browser = session.raw_session
|
10
|
+
@session = session
|
11
|
+
|
12
|
+
@browser_element = browser
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
browser.title
|
17
|
+
end
|
18
|
+
|
19
|
+
def text_on_page?(string)
|
20
|
+
text.downcase.include?(string.downcase)
|
21
|
+
end
|
22
|
+
|
23
|
+
def visit
|
24
|
+
browser.visit self.class.url
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def text
|
29
|
+
browser.text
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(method, *args)
|
33
|
+
element_context.send(method, *args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def respond_to?(*args)
|
37
|
+
super || element_context.respond_to?(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def element_definitions
|
41
|
+
self.class.element_definitions
|
42
|
+
end
|
43
|
+
|
44
|
+
def element_context
|
45
|
+
ElementContext.new(self)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/page_magic/session.rb
CHANGED
@@ -1,30 +1,54 @@
|
|
1
1
|
require 'wait'
|
2
2
|
module PageMagic
|
3
|
-
class
|
4
|
-
end
|
5
|
-
|
3
|
+
# class Session - coordinates access to the browser though page objects.
|
6
4
|
class Session
|
7
5
|
URL_MISSING_MSG = 'a path must be mapped or a url supplied'
|
8
6
|
REGEXP_MAPPING_MSG = 'URL could not be derived because mapping is a Regexp'
|
9
7
|
|
10
8
|
attr_reader :raw_session, :transitions
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
# Create a new session instance
|
11
|
+
# @param [Object] capybara_session an instance of a capybara session
|
12
|
+
# @param [String] url url to start the session at.
|
13
|
+
def initialize(capybara_session, url = nil)
|
14
|
+
@raw_session = capybara_session
|
15
|
+
visit(url: url) if url
|
15
16
|
@transitions = {}
|
16
17
|
end
|
17
18
|
|
19
|
+
# Map paths to Page classes. The session will auto load page objects from these mapping when
|
20
|
+
# the {Session#current_path}
|
21
|
+
# is matched.
|
22
|
+
# @example
|
23
|
+
# self.define_page_mappings '/' => HomePage, %r{/messages/d+}
|
24
|
+
# @param [Hash] transitions - paths mapped to page classes
|
25
|
+
# @option transitions [String] path as literal
|
26
|
+
# @option transitions [Regexp] path as a regexp for dynamic matching.
|
18
27
|
def define_page_mappings(transitions)
|
19
28
|
@transitions = transitions
|
20
29
|
end
|
21
30
|
|
31
|
+
# @return [Object] returns page object representing the currently loaded page on the browser. If no mapping
|
32
|
+
# is found then nil returned
|
22
33
|
def current_page
|
23
34
|
mapping = find_mapped_page(current_path)
|
24
35
|
@current_page = mapping.new(self) if mapping
|
25
36
|
@current_page
|
26
37
|
end
|
27
38
|
|
39
|
+
# Direct the browser to the given page or url. {Session#current_page} will be set be an instance of the given/mapped
|
40
|
+
# page class
|
41
|
+
# @overload visit(page: page_object)
|
42
|
+
# @param [Object] page page class. The required url will be generated using the session's base url and the mapped
|
43
|
+
# path
|
44
|
+
# @overload visit(url: url)
|
45
|
+
# @param [String] url url to be visited.
|
46
|
+
# @overload visit(page: page_class, url: url)
|
47
|
+
# @param [String] url url to be visited.
|
48
|
+
# @param [Object] page the supplied page class will be instantiated to be used against the given url.
|
49
|
+
# @raise [InvalidURLException] if a page is supplied and there isn't a mapped path for it
|
50
|
+
# @raise [InvalidURLException] if neither a page or url are supplied
|
51
|
+
# @raise [InvalidURLException] if the mapped path for a page is a Regexp
|
28
52
|
def visit(page = nil, url: nil)
|
29
53
|
if url
|
30
54
|
raw_session.visit(url)
|
@@ -38,33 +62,46 @@ module PageMagic
|
|
38
62
|
self
|
39
63
|
end
|
40
64
|
|
41
|
-
|
42
|
-
path = path.sub(%r{^/}, '')
|
43
|
-
base_url = base_url.sub(%r{/$}, '')
|
44
|
-
"#{base_url}/#{path}"
|
45
|
-
end
|
46
|
-
|
65
|
+
# @return [String] path in the browser
|
47
66
|
def current_path
|
48
67
|
raw_session.current_path
|
49
68
|
end
|
50
69
|
|
70
|
+
# @return [String] full url in the browser
|
51
71
|
def current_url
|
52
72
|
raw_session.current_url
|
53
73
|
end
|
54
74
|
|
75
|
+
# Wait until a the supplied block returns true
|
76
|
+
# @example
|
77
|
+
# wait_until do
|
78
|
+
# (rand % 2) == 0
|
79
|
+
# end
|
55
80
|
def wait_until(&block)
|
56
81
|
@wait ||= Wait.new
|
57
82
|
@wait.until(&block)
|
58
83
|
end
|
59
84
|
|
85
|
+
# proxies unknown method calls to the currently loaded page object
|
86
|
+
# @return [Object] returned object from the page object method call
|
60
87
|
def method_missing(name, *args, &block)
|
61
88
|
current_page.send(name, *args, &block)
|
62
89
|
end
|
63
90
|
|
91
|
+
# @param args see {::Object#respond_to?}
|
92
|
+
# @return [Boolean] true if self or the current page object responds to the give method name
|
64
93
|
def respond_to?(*args)
|
65
94
|
super || current_page.respond_to?(*args)
|
66
95
|
end
|
67
96
|
|
97
|
+
private
|
98
|
+
|
99
|
+
def url(base_url, path)
|
100
|
+
path = path.sub(%r{^/}, '')
|
101
|
+
base_url = base_url.sub(%r{/$}, '')
|
102
|
+
"#{base_url}/#{path}"
|
103
|
+
end
|
104
|
+
|
68
105
|
def find_mapped_page(path)
|
69
106
|
mapping = transitions.keys.find do |key|
|
70
107
|
string_matches?(path, key)
|
@@ -72,8 +109,6 @@ module PageMagic
|
|
72
109
|
transitions[mapping]
|
73
110
|
end
|
74
111
|
|
75
|
-
private
|
76
|
-
|
77
112
|
def string_matches?(string, matcher)
|
78
113
|
if matcher.is_a?(Regexp)
|
79
114
|
string =~ matcher
|
data/lib/page_magic.rb
CHANGED
@@ -2,26 +2,14 @@ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
|
|
2
2
|
require 'capybara'
|
3
3
|
require 'page_magic/exceptions'
|
4
4
|
require 'page_magic/session'
|
5
|
+
require 'page_magic/instance_methods'
|
5
6
|
require 'page_magic/elements'
|
6
7
|
require 'page_magic/element_context'
|
7
8
|
require 'page_magic/element'
|
8
|
-
require 'page_magic/page_magic'
|
9
9
|
require 'page_magic/drivers'
|
10
10
|
|
11
|
+
# module PageMagic - PageMagic is an api for modelling pages in a website.
|
11
12
|
module PageMagic
|
12
|
-
class UnspportedBrowserException < Exception; end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
def url(url = nil)
|
16
|
-
@url = url if url
|
17
|
-
@url
|
18
|
-
end
|
19
|
-
|
20
|
-
def inherited(clazz)
|
21
|
-
clazz.element_definitions.merge!(element_definitions)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
13
|
class << self
|
26
14
|
def drivers
|
27
15
|
@drivers ||= Drivers.new.tap(&:load)
|
@@ -39,7 +27,15 @@ module PageMagic
|
|
39
27
|
end
|
40
28
|
|
41
29
|
def included(clazz)
|
42
|
-
clazz.
|
30
|
+
clazz.class_eval do
|
31
|
+
def self.url(url = nil)
|
32
|
+
@url = url if url
|
33
|
+
@url
|
34
|
+
end
|
35
|
+
|
36
|
+
include(InstanceMethods)
|
37
|
+
extend(Elements)
|
38
|
+
end
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'page_magic/drivers/poltergeist'
|
2
2
|
module PageMagic
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
expect(driver).to be_a(Capybara::Poltergeist::Driver)
|
8
|
-
end
|
3
|
+
describe Drivers::Poltergeist do
|
4
|
+
it "is capybara's poltergeist driver" do
|
5
|
+
driver = described_class.build(:app, browser: :poltergeist, options: {})
|
6
|
+
expect(driver).to be_a(Capybara::Poltergeist::Driver)
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
require 'page_magic/drivers/selenium'
|
2
2
|
module PageMagic
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
3
|
+
describe Drivers::Selenium do
|
4
|
+
subject do
|
5
|
+
described_class.build(:app, browser: :selenium, options: {})
|
6
|
+
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
it 'is selenium' do
|
9
|
+
expect(subject).to be_a(Capybara::Selenium::Driver)
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
12
|
+
it 'sets the browser option' do
|
13
|
+
expect(subject.options[:browser]).to be(:selenium)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -21,13 +21,13 @@ module PageMagic
|
|
21
21
|
|
22
22
|
context 'neither a method or page element are defined' do
|
23
23
|
it 'raises an error' do
|
24
|
-
expect { described_class.new(page
|
24
|
+
expect { described_class.new(page).missing_thing }.to raise_error ElementMissingException
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
context 'method is a element defintion' do
|
29
29
|
it 'returns the sub page element' do
|
30
|
-
element = described_class.new(page
|
30
|
+
element = described_class.new(page).a_link
|
31
31
|
# TODO: - returns the capybara object. maybe we should think about wrapping this.
|
32
32
|
expect(element.text).to eq('a link')
|
33
33
|
end
|
@@ -39,7 +39,7 @@ module PageMagic
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
described_class.new(page
|
42
|
+
described_class.new(page).a_link
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -51,14 +51,14 @@ module PageMagic
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
expect(described_class.new(page
|
54
|
+
expect(described_class.new(page).page_method).to eq(:called)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
describe '#respond_to?' do
|
60
60
|
subject do
|
61
|
-
described_class.new(elements_page.new(session)
|
61
|
+
described_class.new(elements_page.new(session))
|
62
62
|
end
|
63
63
|
it 'checks against the names of the elements passed in' do
|
64
64
|
expect(subject.respond_to?(:a_link)).to eq(true)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module PageMagic
|
2
|
+
describe InstanceMethods do
|
3
|
+
include_context :webapp_fixture
|
4
|
+
subject do
|
5
|
+
clazz = Class.new do
|
6
|
+
include PageMagic
|
7
|
+
url '/page1'
|
8
|
+
link(:next_page, text: 'next page')
|
9
|
+
end
|
10
|
+
clazz.new.tap(&:visit)
|
11
|
+
end
|
12
|
+
|
13
|
+
context '#respond_to?' do
|
14
|
+
it 'checks self' do
|
15
|
+
expect(subject.respond_to?(:visit)).to eq(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'checks the current page' do
|
19
|
+
expect(subject.respond_to?(:next_page)).to eq(true)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'visit' do
|
24
|
+
it 'goes to the class define url' do
|
25
|
+
expect(subject.session.current_path).to eq('/page1')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'session' do
|
30
|
+
it 'gives access to the page magic object wrapping the user session' do
|
31
|
+
expect(subject.session.raw_session).to be(Capybara.current_session)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'text_on_page?' do
|
36
|
+
it 'returns true if the text is present' do
|
37
|
+
expect(subject.text_on_page?('next page')).to eq(true)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns false if the text is not present' do
|
41
|
+
expect(subject.text_on_page?('not on page')).to eq(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'title' do
|
46
|
+
it 'returns the title' do
|
47
|
+
expect(subject.title).to eq('page1')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'text' do
|
52
|
+
it 'returns the text on the page' do
|
53
|
+
expect(subject.text).to eq('next page')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'method_missing' do
|
58
|
+
it 'gives access to the elements defined on your page classes' do
|
59
|
+
expect(subject.next_page.tag_name).to eq('a')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -61,18 +61,18 @@ module PageMagic
|
|
61
61
|
|
62
62
|
context 'mapping is string' do
|
63
63
|
it 'returns the page class' do
|
64
|
-
expect(subject.find_mapped_page('/page')).to be(:mapped_page_using_string)
|
64
|
+
expect(subject.instance_eval { find_mapped_page('/page') }).to be(:mapped_page_using_string)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
context 'mapping is regex' do
|
68
68
|
it 'returns the page class' do
|
69
|
-
expect(subject.find_mapped_page('/page2')).to be(:mapped_page_using_regex)
|
69
|
+
expect(subject.instance_eval { find_mapped_page('/page2') }).to be(:mapped_page_using_regex)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
context 'mapping is not found' do
|
74
74
|
it 'returns nil' do
|
75
|
-
expect(subject.find_mapped_page('/fake_page')).to be(nil)
|
75
|
+
expect(subject.instance_eval { find_mapped_page('/fake_page') }).to be(nil)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
@@ -129,13 +129,13 @@ module PageMagic
|
|
129
129
|
|
130
130
|
context 'path has / at the beginning' do
|
131
131
|
it 'produces compound url' do
|
132
|
-
expect(subject.url
|
132
|
+
expect(subject.send(:url, base_url, path)).to eq(expected_url)
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
136
|
context 'path does not have / at the beginning' do
|
137
137
|
it 'produces compound url' do
|
138
|
-
expect(subject.url
|
138
|
+
expect(subject.send(:url, base_url, "/#{path}")).to eq(expected_url)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
@@ -143,13 +143,13 @@ module PageMagic
|
|
143
143
|
context 'current_url does not have a / on the end' do
|
144
144
|
context 'path has / at the beginning' do
|
145
145
|
it 'produces compound url' do
|
146
|
-
expect(subject.url
|
146
|
+
expect(subject.send(:url, base_url, "/#{path}")).to eq(expected_url)
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
150
|
context 'path does not have / at the beginning' do
|
151
151
|
it 'produces compound url' do
|
152
|
-
expect(subject.url
|
152
|
+
expect(subject.send(:url, base_url, path)).to eq(expected_url)
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: page_magic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.alpha18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leon Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -80,6 +80,62 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: redcarpet
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: github-markup
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
83
139
|
description: Framework for modeling and interacting with webpages which wraps capybara
|
84
140
|
email: info@lad-tech.com
|
85
141
|
executables: []
|
@@ -87,16 +143,20 @@ extensions: []
|
|
87
143
|
extra_rdoc_files:
|
88
144
|
- README.md
|
89
145
|
files:
|
146
|
+
- ".codeclimate.yml"
|
147
|
+
- ".pullreview.yml"
|
90
148
|
- ".rspec"
|
91
149
|
- ".rubocop.yml"
|
92
150
|
- ".ruby-gemset"
|
93
151
|
- ".ruby-version"
|
94
152
|
- ".simplecov"
|
153
|
+
- ".yardopts"
|
95
154
|
- Gemfile
|
96
155
|
- Gemfile.lock
|
97
156
|
- README.md
|
98
157
|
- Rakefile
|
99
158
|
- VERSION
|
159
|
+
- circle.yml
|
100
160
|
- lib/page_magic.rb
|
101
161
|
- lib/page_magic/driver.rb
|
102
162
|
- lib/page_magic/drivers.rb
|
@@ -111,7 +171,7 @@ files:
|
|
111
171
|
- lib/page_magic/element_context.rb
|
112
172
|
- lib/page_magic/elements.rb
|
113
173
|
- lib/page_magic/exceptions.rb
|
114
|
-
- lib/page_magic/
|
174
|
+
- lib/page_magic/instance_methods.rb
|
115
175
|
- lib/page_magic/session.rb
|
116
176
|
- page_magic.gemspec
|
117
177
|
- spec/element_spec.rb
|
@@ -125,7 +185,7 @@ files:
|
|
125
185
|
- spec/page_magic/element/selector_spec.rb
|
126
186
|
- spec/page_magic/element_context_spec.rb
|
127
187
|
- spec/page_magic/elements_spec.rb
|
128
|
-
- spec/page_magic/
|
188
|
+
- spec/page_magic/instance_methods_spec.rb
|
129
189
|
- spec/page_magic/session_spec.rb
|
130
190
|
- spec/page_magic_spec.rb
|
131
191
|
- spec/spec_helper.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module PageMagic
|
2
|
-
attr_reader :browser, :session, :browser_element
|
3
|
-
|
4
|
-
def initialize(session = Session.new(Capybara.current_session), &block)
|
5
|
-
@browser = session.raw_session
|
6
|
-
@session = session
|
7
|
-
|
8
|
-
@browser_element = browser
|
9
|
-
block.call browser if block
|
10
|
-
end
|
11
|
-
|
12
|
-
def title
|
13
|
-
browser.title
|
14
|
-
end
|
15
|
-
|
16
|
-
def text_on_page?(string)
|
17
|
-
text.downcase.include?(string.downcase)
|
18
|
-
end
|
19
|
-
|
20
|
-
def visit
|
21
|
-
browser.visit self.class.url
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
def text
|
26
|
-
browser.text
|
27
|
-
end
|
28
|
-
|
29
|
-
def method_missing(method, *args)
|
30
|
-
element_context.send(method, *args)
|
31
|
-
end
|
32
|
-
|
33
|
-
def respond_to?(*args)
|
34
|
-
super || element_context.respond_to?(*args)
|
35
|
-
end
|
36
|
-
|
37
|
-
def element_context
|
38
|
-
ElementContext.new(self, self)
|
39
|
-
end
|
40
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
describe PageMagic do
|
2
|
-
include_context :webapp_fixture
|
3
|
-
subject do
|
4
|
-
described_class = described_class()
|
5
|
-
page_class = Class.new do
|
6
|
-
include described_class
|
7
|
-
url '/page1'
|
8
|
-
link(:next_page, text: 'next page')
|
9
|
-
end
|
10
|
-
page_class.new.tap(&:visit)
|
11
|
-
end
|
12
|
-
|
13
|
-
context '#respond_to?' do
|
14
|
-
it 'checks self' do
|
15
|
-
expect(subject.respond_to?(:visit)).to eq(true)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'checks the current page' do
|
19
|
-
expect(subject.respond_to?(:next_page)).to eq(true)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe 'visit' do
|
24
|
-
it 'goes to the class define url' do
|
25
|
-
expect(subject.session.current_path).to eq('/page1')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe 'session' do
|
30
|
-
it 'gives access to the page magic object wrapping the user session' do
|
31
|
-
expect(subject.session.raw_session).to be(Capybara.current_session)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe 'text_on_page?' do
|
36
|
-
it 'returns true if the text is present' do
|
37
|
-
expect(subject.text_on_page?('next page')).to eq(true)
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'returns false if the text is not present' do
|
41
|
-
expect(subject.text_on_page?('not on page')). to eq(false)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe 'title' do
|
46
|
-
it 'returns the title' do
|
47
|
-
expect(subject.title).to eq('page1')
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe 'text' do
|
52
|
-
it 'returns the text on the page' do
|
53
|
-
expect(subject.text).to eq('next page')
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe 'method_missing' do
|
58
|
-
it 'gives access to the elements defined on your page classes' do
|
59
|
-
expect(subject.next_page.tag_name).to eq('a')
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|