test-page 0.0.1
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/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/.yardopts +6 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +106 -0
- data/Rakefile +9 -0
- data/examples/selenium/results_page.rb +9 -0
- data/examples/selenium/search_page.rb +15 -0
- data/examples/selenium/search_spec.rb +23 -0
- data/examples/watir/results_page.rb +9 -0
- data/examples/watir/search_page.rb +15 -0
- data/examples/watir/search_spec.rb +23 -0
- data/lib/test/page.rb +156 -0
- data/lib/test/page/version.rb +5 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test/page_spec.rb +165 -0
- data/test-page.gemspec +23 -0
- metadata +149 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jarmo Pertman
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Test::Page
|
2
|
+
|
3
|
+
[](http://travis-ci.org/jarmo/test-page)
|
4
|
+
[](https://gemnasium.com/jarmo/test-page)
|
5
|
+
[](https://codeclimate.com/github/jarmo/test-page)
|
6
|
+
|
7
|
+
Test::Page helps you to write easily maintainable integration tests by implementing [Page Objects](https://code.google.com/p/selenium/wiki/PageObjects) pattern.
|
8
|
+
|
9
|
+
Page Objects may be objects representing whole pages like LoginPage, ProfilePage or part of the pages like LoginForm, Header etc.
|
10
|
+
|
11
|
+
Test::Page can be described like:
|
12
|
+
|
13
|
+
* Is framework agnostic - you can use it with any library you want - [Watir](http://watir.com), [Selenium](http://seleniumhq.org/), [Capybara](https://github.com/jnicklas/capybara) etc.
|
14
|
+
* Has really [easy API](http://rubydoc.info/github/jarmo/test-page/frames) - you can start testing right away instead of spending too much time to learn new framework.
|
15
|
+
* Has really small codebase - even if you can't remember that small API you can dig right into the code - it's less than 100 lines!
|
16
|
+
* Despite of its name you may use it with [RSpec](http://rspec.info/), [Test::Unit](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/test/unit/rdoc/Test/Unit.html) or any other testing library.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
gem 'test-page'
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install test-page
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
The following example uses Watir with RSpec, but you can use whichever library
|
35
|
+
you like.
|
36
|
+
|
37
|
+
[Check out Selenium example](https://github.com/jarmo/test-page/tree/master/examples) instead, if that's your flavor of choice.
|
38
|
+
|
39
|
+
This is the spec we are trying to run:
|
40
|
+
|
41
|
+
# spec/search_spec.rb
|
42
|
+
|
43
|
+
require "test/page"
|
44
|
+
require "watir"
|
45
|
+
require File.expand_path("search_page", File.dirname(__FILE__))
|
46
|
+
|
47
|
+
describe "Bing" do
|
48
|
+
|
49
|
+
let(:browser) { Watir::Browser.new }
|
50
|
+
let(:search_page) { SearchPage.new }
|
51
|
+
|
52
|
+
before { Test::Page.browser = browser }
|
53
|
+
after { browser.close }
|
54
|
+
|
55
|
+
it "finds Google" do
|
56
|
+
results_page = search_page.search "google"
|
57
|
+
results_page.should have(10).results
|
58
|
+
results_page.results[0].should =~ /google/i
|
59
|
+
end
|
60
|
+
|
61
|
+
it "finds Bing itself" do
|
62
|
+
results_page = search_page.search "bing"
|
63
|
+
results_page.results.should include("Bing")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
Let's create the SearchPage object:
|
68
|
+
|
69
|
+
# spec/support/page/search_page.rb
|
70
|
+
|
71
|
+
require File.expand_path("results_page", File.dirname(__FILE__))
|
72
|
+
|
73
|
+
class SearchPage < Test::Page
|
74
|
+
element { browser.div(:id => "sbox") }
|
75
|
+
|
76
|
+
def setup
|
77
|
+
browser.goto "http://bing.com"
|
78
|
+
end
|
79
|
+
|
80
|
+
def search(term)
|
81
|
+
text_field(:id => "sb_form_q").set term
|
82
|
+
button(:id => "sb_form_go").click
|
83
|
+
redirect_to ResultsPage, browser.ul(:id => "wg0")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Let's create the ResultsPage object:
|
88
|
+
|
89
|
+
# spec/support/page/results_page.rb
|
90
|
+
|
91
|
+
class ResultsPage < Test::Page
|
92
|
+
def results
|
93
|
+
modify lis(:class => "sa_wr").map(&:text),
|
94
|
+
:include? => proc { |term|
|
95
|
+
regexp = Regexp.new Regexp.escape(term)
|
96
|
+
results.any? { |result| result =~ regexp }
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
There you have it, a fully functional spec using two page objects. Reference to the
|
102
|
+
[API documentation](http://rubydoc.info/github/jarmo/test-page/frames) for more usage information.
|
103
|
+
|
104
|
+
## License
|
105
|
+
|
106
|
+
Copyright (c) Jarmo Pertman (jarmo.p@gmail.com). See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path("results_page", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class SearchPage < Test::Page
|
4
|
+
element { browser.find_element(id: "sbox") }
|
5
|
+
|
6
|
+
def setup
|
7
|
+
browser.navigate.to("http://bing.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
def search(term)
|
11
|
+
find_element(:id => "sb_form_q").send_keys term
|
12
|
+
find_element(:id => "sb_form_go").click
|
13
|
+
redirect_to ResultsPage, browser.find_element(:id => "wg0")
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test/page"
|
2
|
+
require "selenium-webdriver"
|
3
|
+
require File.expand_path("search_page", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
describe "Bing" do
|
6
|
+
|
7
|
+
let(:browser) { Selenium::WebDriver.for :firefox }
|
8
|
+
let(:search_page) { SearchPage.new }
|
9
|
+
|
10
|
+
before { Test::Page.browser = browser }
|
11
|
+
after { browser.quit }
|
12
|
+
|
13
|
+
it "finds Google" do
|
14
|
+
results_page = search_page.search "google"
|
15
|
+
results_page.should have(10).results
|
16
|
+
results_page.results[0].should =~ /google/i
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds Bing itself" do
|
20
|
+
results_page = search_page.search "bing"
|
21
|
+
results_page.results.should include("Bing")
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path("results_page", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class SearchPage < Test::Page
|
4
|
+
element { browser.div(:id => "sbox") }
|
5
|
+
|
6
|
+
def setup
|
7
|
+
browser.goto "http://bing.com"
|
8
|
+
end
|
9
|
+
|
10
|
+
def search(term)
|
11
|
+
text_field(:id => "sb_form_q").set term
|
12
|
+
button(:id => "sb_form_go").click
|
13
|
+
redirect_to ResultsPage, browser.ul(:id => "wg0")
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test/page"
|
2
|
+
require "watir"
|
3
|
+
require File.expand_path("search_page", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
describe "Bing" do
|
6
|
+
|
7
|
+
let(:browser) { Watir::Browser.new }
|
8
|
+
let(:search_page) { SearchPage.new }
|
9
|
+
|
10
|
+
before { Test::Page.browser = browser }
|
11
|
+
after { browser.close }
|
12
|
+
|
13
|
+
it "finds Google" do
|
14
|
+
results_page = search_page.search "google"
|
15
|
+
results_page.should have(10).results
|
16
|
+
results_page.results[0].should =~ /google/i
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds Bing itself" do
|
20
|
+
results_page = search_page.search "bing"
|
21
|
+
results_page.results.should include("Bing")
|
22
|
+
end
|
23
|
+
end
|
data/lib/test/page.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
require File.expand_path("page/version", File.dirname(__FILE__))
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Test
|
5
|
+
class Page
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :element, :present?, :p
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Set and get the browser object for {Page}.
|
12
|
+
#
|
13
|
+
# This makes it possible to reuse one global browser object between
|
14
|
+
# different {Page} objects. It will be also shared between sub-classes of {Page}
|
15
|
+
# class.
|
16
|
+
#
|
17
|
+
# @example Set Watir browser object as the global browser
|
18
|
+
# Test::Page.browser = Watir::Browser.new
|
19
|
+
attr_accessor :browser
|
20
|
+
|
21
|
+
# @private
|
22
|
+
attr_reader :element_block
|
23
|
+
|
24
|
+
# Set element for the {Page} via block.
|
25
|
+
# It will be evaluated lazily after {Page} has been instantiated.
|
26
|
+
#
|
27
|
+
# Element is like the container of the {Page} - everything outside of that element
|
28
|
+
# is not considered as part of the {Page}.
|
29
|
+
# Use as specific element as possible.
|
30
|
+
#
|
31
|
+
# @example Use Watir::Div as an {element}.
|
32
|
+
# class MyPage < Test::Page
|
33
|
+
# element { browser.div(:id => "search") }
|
34
|
+
# end
|
35
|
+
def element(&block)
|
36
|
+
@element_block = block
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_writer :browser
|
41
|
+
|
42
|
+
# Set and get the browser object for specific {Page} instance.
|
43
|
+
#
|
44
|
+
# This is useful if some specific {Page} instance needs a different browser
|
45
|
+
# than is set via {.browser} method. Popup browser windows might be
|
46
|
+
# one example.
|
47
|
+
#
|
48
|
+
# If browser is not set via {#browser} then browser set via
|
49
|
+
# {.browser} will be used.
|
50
|
+
def browser
|
51
|
+
@browser || parent_page_browser
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the element instance.
|
55
|
+
#
|
56
|
+
# When {#setup} is defined, it will be executed once per {Page} instance.
|
57
|
+
#
|
58
|
+
# @return [Object] if element is specified for {#initialize}.
|
59
|
+
# @return [Object] otherwise {.element} block is evaluated once per {Page} instance and its value will be returned.
|
60
|
+
def element
|
61
|
+
@setup_done ||= begin
|
62
|
+
setup if respond_to?(:setup)
|
63
|
+
true
|
64
|
+
end
|
65
|
+
@element ||= begin
|
66
|
+
element_proc = self.class.element_block
|
67
|
+
element_proc && instance_eval(&element_proc)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @param [Object] Element element for the {Page}. {.element} set via block will be used if not specified.
|
72
|
+
def initialize(element=nil)
|
73
|
+
@element = element
|
74
|
+
end
|
75
|
+
|
76
|
+
# Add or modify element instance methods.
|
77
|
+
#
|
78
|
+
# When element does not have the specified method then that method will be
|
79
|
+
# added to the specific element instance.
|
80
|
+
# When element has specified method it will be invoked before invoking the
|
81
|
+
# specified method.
|
82
|
+
#
|
83
|
+
# @example Add #png? method to Watir::Image
|
84
|
+
# class Gallery < Test::Page
|
85
|
+
# def thumbnail
|
86
|
+
# image = img(:id => "thumbnail")
|
87
|
+
# modify image,
|
88
|
+
# :png? => proc { File.extname(image.src).downcase == ".png" }
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# Gallery.new.thumbnail.png? # returns true for images, which have
|
93
|
+
# # the src attribute set to png.
|
94
|
+
#
|
95
|
+
# @example Modify Watir::Button#click to return new MainPage instance after click
|
96
|
+
# class LoginForm < Test::Page
|
97
|
+
# def login_button
|
98
|
+
# modify button(:id => "login"),
|
99
|
+
# :click => proc { redirect_to MainPage }
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# LoginForm.new.login_button.click # performs the click and returns
|
104
|
+
# # a new MainPage instance.
|
105
|
+
#
|
106
|
+
# @param [Object] Element element to modify.
|
107
|
+
# @param [Hash<Symbol,Proc>] Hash of method name as a Symbol and body as a Proc pairs.
|
108
|
+
#
|
109
|
+
# @return [Object] Modified Element instance.
|
110
|
+
def modify(element, methods)
|
111
|
+
methods.each_pair do |meth, return_value|
|
112
|
+
element.instance_eval do
|
113
|
+
singleton = class << self; self end
|
114
|
+
|
115
|
+
singleton.send :alias_method, "__#{meth}", meth if respond_to? meth
|
116
|
+
singleton.send :define_method, meth do |*args|
|
117
|
+
self.send("__#{meth}", *args) if respond_to? "__#{meth}"
|
118
|
+
return_value.call(*args)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
element
|
123
|
+
end
|
124
|
+
|
125
|
+
# Create new {Page} object conveniently on page actions.
|
126
|
+
#
|
127
|
+
# @param [Page] Page page class to make an instance of
|
128
|
+
# @param [Object] Element optional element instance. When not specified current {Page} element will be used.
|
129
|
+
def redirect_to(page, element=nil)
|
130
|
+
page.new element || self.element
|
131
|
+
end
|
132
|
+
|
133
|
+
# Proxies every method call not found on {Page} to element instance.
|
134
|
+
# Subsequent executions of the same method will be invoked on the {Page} object directly.
|
135
|
+
def method_missing(name, *args)
|
136
|
+
if element.respond_to?(name)
|
137
|
+
self.class.send :define_method, name do |*args|
|
138
|
+
element.send(name, *args) {yield}
|
139
|
+
end
|
140
|
+
self.send(name, *args) {yield}
|
141
|
+
else
|
142
|
+
super
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def parent_page_browser
|
149
|
+
page_with_browser = self.class.ancestors.find do |klass|
|
150
|
+
klass.respond_to?(:browser) && klass.browser
|
151
|
+
end
|
152
|
+
page_with_browser ? page_with_browser.browser : nil
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
require File.expand_path("../../lib/test/page", File.dirname(__FILE__))
|
3
|
+
|
4
|
+
describe Test::Page do
|
5
|
+
let(:page_class) { Class.new(Test::Page) }
|
6
|
+
|
7
|
+
context ".browser" do
|
8
|
+
before { Test::Page.browser = nil }
|
9
|
+
|
10
|
+
it "sets the browser object for page" do
|
11
|
+
Test::Page.browser = "my browser"
|
12
|
+
Test::Page.browser.should == "my browser"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "does not set the browser object for sub-page class" do
|
16
|
+
Test::Page.browser = "your browser"
|
17
|
+
page_class.browser.should be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "sets the browser object for sub-page instances" do
|
21
|
+
Test::Page.browser = "your browser"
|
22
|
+
page = page_class.new
|
23
|
+
page.browser.should == "your browser"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can be overridden by sub-page" do
|
27
|
+
Test::Page.browser = "their browser"
|
28
|
+
page_class.browser = "my page browser"
|
29
|
+
page_class.browser.should == "my page browser"
|
30
|
+
Test::Page.browser.should == "their browser"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context ".element" do
|
35
|
+
it "sets the element via block" do
|
36
|
+
page_class.element { "my element" }
|
37
|
+
page = page_class.new
|
38
|
+
page.element.should == "my element"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "#initialize" do
|
43
|
+
it "allows to set element" do
|
44
|
+
page = page_class.new "my special element"
|
45
|
+
page.element.should == "my special element"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "#element" do
|
50
|
+
it "evaluates element provided by the block only once per instance" do
|
51
|
+
block_called = false
|
52
|
+
page_class.element do
|
53
|
+
raise "block should have been called only once!" if block_called
|
54
|
+
block_called = true
|
55
|
+
"my element in block"
|
56
|
+
end
|
57
|
+
page = page_class.new
|
58
|
+
2.times { page.element.should == "my element in block" }
|
59
|
+
block_called.should be_true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "#setup" do
|
64
|
+
it "is called only once if page has method defined" do
|
65
|
+
block_called = false
|
66
|
+
page_class.send :define_method, :setup do
|
67
|
+
raise "block should have been called only once!" if block_called
|
68
|
+
block_called = true
|
69
|
+
@element = "element via setup"
|
70
|
+
end
|
71
|
+
page = page_class.new
|
72
|
+
2.times { page.element.should == "element via setup" }
|
73
|
+
block_called.should be_true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "#modify" do
|
78
|
+
let(:modified_page_class) do
|
79
|
+
page_class.send :define_method, :something do
|
80
|
+
modify Hash.new,
|
81
|
+
:action => proc { "hi" },
|
82
|
+
:store => proc { |a, b| a + b }
|
83
|
+
end
|
84
|
+
page_class
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns the instance of the original object" do
|
88
|
+
page = modified_page_class.new
|
89
|
+
page.something.should == {}
|
90
|
+
end
|
91
|
+
|
92
|
+
it "allows to modify default behavior of the instance's methods" do
|
93
|
+
page = modified_page_class.new
|
94
|
+
page.something.store(1, 2).should == 3
|
95
|
+
end
|
96
|
+
|
97
|
+
it "executes the original instance method too" do
|
98
|
+
page = modified_page_class.new
|
99
|
+
result = page.something
|
100
|
+
result.store 1, 2
|
101
|
+
result.should == {1 => 2}
|
102
|
+
end
|
103
|
+
|
104
|
+
it "modifies only singleton instance methods, leaving original class intact" do
|
105
|
+
page = modified_page_class.new
|
106
|
+
result = page.something
|
107
|
+
result.store(1, 2).should == 3
|
108
|
+
|
109
|
+
original_hash = Hash.new
|
110
|
+
original_hash.store(1, 2).should == 2
|
111
|
+
original_hash.should == {1 => 2}
|
112
|
+
end
|
113
|
+
|
114
|
+
it "allows to add new methods too" do
|
115
|
+
page = modified_page_class.new
|
116
|
+
page.something.action.should == "hi"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "#redirect_to" do
|
121
|
+
it "returns the new page instance" do
|
122
|
+
second_page = Class.new(Test::Page)
|
123
|
+
page_class.send(:define_method, :redirect_me) { redirect_to second_page }
|
124
|
+
page = page_class.new
|
125
|
+
page.redirect_me.should be_an_instance_of(second_page)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "reuses the existing page element" do
|
129
|
+
second_page = Class.new(Test::Page)
|
130
|
+
page_class.send(:define_method, :redirect_me) { redirect_to second_page }
|
131
|
+
page = page_class.new "provided element"
|
132
|
+
redirected_page = page.redirect_me
|
133
|
+
redirected_page.element.should == "provided element"
|
134
|
+
end
|
135
|
+
|
136
|
+
it "is possible to specify new element" do
|
137
|
+
second_page = Class.new(Test::Page)
|
138
|
+
page_class.send(:define_method, :redirect_me) { redirect_to second_page, "new element" }
|
139
|
+
page = page_class.new "provided element"
|
140
|
+
redirected_page = page.redirect_me
|
141
|
+
redirected_page.element.should == "new element"
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
context "#method_missing" do
|
147
|
+
it "calls all missing methods on element object" do
|
148
|
+
page = page_class.new "element"
|
149
|
+
page.should_not respond_to(:size)
|
150
|
+
page.size.should == "element".size
|
151
|
+
end
|
152
|
+
|
153
|
+
it "defines methods to the page class" do
|
154
|
+
page = page_class.new "element"
|
155
|
+
page.should_not respond_to(:size)
|
156
|
+
page.size
|
157
|
+
page.should respond_to(:size)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "will raise a NoMethodError if no method is found on element" do
|
161
|
+
expect { page_class.new("element").foo }.to raise_error(NoMethodError)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
data/test-page.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/test/page/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jarmo Pertman"]
|
6
|
+
gem.email = ["jarmo.p@gmail.com"]
|
7
|
+
gem.description = %q{Test::Page helps you to write easily maintainable integration tests by using Watir, Selenium or any other testing library.}
|
8
|
+
gem.summary = %q{Test::Page helps you to write easily maintainable integration tests by using Watir, Selenium or any other testing library.}
|
9
|
+
gem.homepage = "https://github.com/jarmo/test-page"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "test-page"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Test::Page::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency "rspec", "~>2.0"
|
19
|
+
gem.add_development_dependency "simplecov"
|
20
|
+
gem.add_development_dependency "yard"
|
21
|
+
gem.add_development_dependency "redcarpet"
|
22
|
+
gem.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test-page
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jarmo Pertman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-31 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: simplecov
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redcarpet
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rake
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Test::Page helps you to write easily maintainable integration tests by
|
95
|
+
using Watir, Selenium or any other testing library.
|
96
|
+
email:
|
97
|
+
- jarmo.p@gmail.com
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .rspec
|
104
|
+
- .travis.yml
|
105
|
+
- .yardopts
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- examples/selenium/results_page.rb
|
111
|
+
- examples/selenium/search_page.rb
|
112
|
+
- examples/selenium/search_spec.rb
|
113
|
+
- examples/watir/results_page.rb
|
114
|
+
- examples/watir/search_page.rb
|
115
|
+
- examples/watir/search_spec.rb
|
116
|
+
- lib/test/page.rb
|
117
|
+
- lib/test/page/version.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
- spec/test/page_spec.rb
|
120
|
+
- test-page.gemspec
|
121
|
+
homepage: https://github.com/jarmo/test-page
|
122
|
+
licenses: []
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 1.8.24
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: Test::Page helps you to write easily maintainable integration tests by using
|
145
|
+
Watir, Selenium or any other testing library.
|
146
|
+
test_files:
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
- spec/test/page_spec.rb
|
149
|
+
has_rdoc:
|