site_prism 0.9

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/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2011, Nathaniel Ritmeyer
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name Nathaniel Ritmeyer nor the names of contributors to
15
+ this software may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
19
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
22
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/lib/site_prism.rb ADDED
@@ -0,0 +1,8 @@
1
+ module SitePrism
2
+
3
+ end
4
+
5
+ require 'site_prism/exceptions'
6
+ require 'site_prism/element_container'
7
+ require 'site_prism/page'
8
+ require 'site_prism/section'
@@ -0,0 +1,104 @@
1
+ # Contains methods applicable to both {SitePrism::Page}s and {SitePrism::Section}s. Note that they are mixed into the {SitePrism::Page}
2
+ # and {SitePrism::Section} classes so the methods below are used as class methods.
3
+ module SitePrism::ElementContainer
4
+
5
+ # Creates two methods; the first method has the same name as the element_name parameter and returns the capybara element
6
+ # located by the element_locator parameter when the method is called. The second method generated has a name with a format
7
+ # of: 'has_#\{element_name}?' which returns true if the element as located by the element_locator parameter exists, false
8
+ # if it doesn't
9
+ # @param [Symbol] element_name The name of the element
10
+ # @param [String] element_locator The CSS locator to find the element
11
+ # @example
12
+ # class HomePage < SitePrism::Page
13
+ # element :search_link, 'div.search > a'
14
+ # end
15
+ # home = HomePage.new
16
+ #
17
+ # #the element method created 2 methods...
18
+ # home.search_link #=> returns the capybara element located by the element_locator parameter
19
+ # home.has_search_link? #=> returns true if the capybara element as located by the element_locator exists, false if it doesn't
20
+ #
21
+ # #The has_search_link? method allows use of magic matchers in rspec/cucumber:
22
+ # home.should have_search_link
23
+ # home.should_not have_search_link
24
+ def element element_name, element_locator
25
+ create_existence_checker element_name, element_locator
26
+ define_method element_name.to_s do
27
+ find_one element_locator
28
+ end
29
+ end
30
+
31
+ # Works in the same way as {SitePrism::Page.element} in that it will generate two methods; one to check existence of
32
+ # the element (in the format 'has_#\{element_name}?'), and another to return not a single element, but an array of elements
33
+ # found by the css locator
34
+ # @param [Symbol] collection_name The name of the collection
35
+ # @param [String] collection_locator The CSS locator that returns the list of elements in the collection
36
+ # @example
37
+ # class HomePage < SitePrism::Page
38
+ # elements :app_links, '.title-links > a'
39
+ # end
40
+ # home = HomePage.new
41
+ #
42
+ # home.should have_app_links
43
+ # home.app_links #=> [#<Capybara::Element tag="a">, #<Capybara::Element tag="a">, #<Capybara::Element tag="a">]
44
+ # home.app_links.map {|link| link.text}.should == ['Finance', 'Maps', 'Blogs']
45
+ def elements collection_name, collection_locator
46
+ create_existence_checker collection_name, collection_locator
47
+ define_method collection_name.to_s do
48
+ find_all collection_locator
49
+ end
50
+ end
51
+ alias :collection :elements
52
+
53
+ # Creates a method that returns an instance of a {SitePrism::Section}. If a page contains a common section (eg: a search area) that
54
+ # appears on many pages, create a {SitePrism::Section} for it and then expose it in each {SitePrism::Page} that contains the section.
55
+ # Say a search engine website displays the search field and search button on each page and they always have the same IDs, they should
56
+ # be extracted into a {SitePrism::Section} that would look something like this:
57
+ #
58
+ # class SearchArea < SitePrism::Section
59
+ # element :search_field, '.q'
60
+ # element :search_button, '.btnK'
61
+ # end
62
+ #
63
+ # ...then that section could be added to any page as follows:
64
+ #
65
+ # class SearchPage < SitePrism::Page
66
+ # section :search_area, SearchArea, '.tsf-p'
67
+ # end
68
+ #
69
+ # class SearchResultsPage < SitePrism::Page
70
+ # section :search_again, SearchArea, '.tsf-p table'
71
+ # end
72
+ #
73
+ # The SearchArea section appears on both pages, but can be invoked by methods specific to the page (eg: 'search_area' and 'search_again')
74
+ # and the root element for the section can be different on the page (eg: '.tsf-p' and '.tsf-p table').
75
+ # @param [Symbol] the method name to be called against this page or section to return an instance of the {SitePrism::Section} class
76
+ # @param [Class] the class that models this area of the page
77
+ # @param [String] the CSS locator for the root element of the section on this page/section
78
+ def section section_name, section_class, section_locator
79
+ create_existence_checker section_name, section_locator
80
+ define_method section_name do
81
+ section_class.new find_one section_locator
82
+ end
83
+ end
84
+
85
+ # Works in the same way as {SitePrism::Page.section} but instead of it returning one section, it returns an array of them.
86
+ def sections section_collection_name, section_class, section_collection_locator
87
+ create_existence_checker section_collection_name, section_collection_locator
88
+ define_method section_collection_name do
89
+ find_all(section_collection_locator).collect do |element|
90
+ section_class.new element
91
+ end
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ # Creates a method used to check for the existence of the element whose details are passed to it
98
+ # @param
99
+ def create_existence_checker element_name, element_locator
100
+ define_method "has_#{element_name.to_s}?" do
101
+ element_exists? element_locator
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,7 @@
1
+ # SitePrism's exceptions...
2
+ module SitePrism
3
+ # Raised if you ask a page to load but it hasn't had its url set
4
+ class NoUrlForPage < StandardError; end
5
+ # Raised if you check to see if a page is displayed but it hasn't had its url matcher set
6
+ class NoUrlMatcherForPage < StandardError; end
7
+ end
@@ -0,0 +1,108 @@
1
+ module SitePrism
2
+ # Subclasses of {SitePrism::Page} represent pages in your app.
3
+ # class Home < SitePrism::Page
4
+ # end
5
+ #
6
+ # The above is an example of how to make a class representing the home page. There are a number of properties that can be
7
+ # set on a page - here is an example of a more fully spec'ed out page:
8
+ # class Home < SitePrism::Page
9
+ # set_url "/"
10
+ # set_url_matcher /\/home.htm$/
11
+ # end
12
+ class Page
13
+ include Capybara::DSL
14
+ extend ElementContainer
15
+
16
+ # Visits the url associated with this page
17
+ # @raise [SitePrism::NoUrlForPage] To load a page the url must be set using {.set_url}
18
+ def load
19
+ raise SitePrism::NoUrlForPage if url.nil?
20
+ visit url
21
+ end
22
+
23
+ # Checks to see if we're on this page or not
24
+ # @return true if the browser's current url matches the {.url_matcher} that has been set, false if it doesn't
25
+ # @raise [SitePrism::NoUrlMatcherForPage] To check whether we're on this page or not the url matcher must be set using {.set_url_matcher}
26
+ # @example
27
+ # class SearchPage < SitePrism::Page
28
+ # set_url_matcher /\/search.htm$/
29
+ # end
30
+ # search_page = SearchPage.new
31
+ # search_page.load
32
+ # puts "We're on the search page" if search_page.displayed?
33
+ # search_page.should be_displayed
34
+ def displayed?
35
+ raise SitePrism::NoUrlMatcherForPage if url_matcher.nil?
36
+ !(page.current_url =~ url_matcher).nil?
37
+ end
38
+
39
+ # Set the url associated with this page
40
+ # @param [String] page_url the portion of the url that identifies this page when appended onto Capybara's app_host. Calling {SitePrism::Page#load} causes Capybara to visit this page.
41
+ # @example
42
+ # class SearchPage < SitePrism::Page
43
+ # set_url "/search.htm"
44
+ # end
45
+ def self.set_url page_url
46
+ @url = page_url
47
+ end
48
+
49
+ # Set the url matcher associated with this page
50
+ # @param [Regexp] page_url_matcher a regular expression that when compared to the current browser url will match if we're on this page or not match if we're not on this page
51
+ # @example
52
+ # class SearchPage < SitePrism::Page
53
+ # set_url_matcher /\/search.htm$/
54
+ # end
55
+ def self.set_url_matcher page_url_matcher
56
+ @url_matcher = page_url_matcher
57
+ end
58
+
59
+ # Get the url associated with this page
60
+ # @see SitePrism::Page#url
61
+ # @return [String] the url originally set in {.set_url}
62
+ def self.url
63
+ @url
64
+ end
65
+
66
+ # Get the url matcher associated with this page
67
+ # @see SitePrism::Page#url_matcher
68
+ # @return [Regexp] the url matcher originally set in {.set_url_matcher}
69
+ def self.url_matcher
70
+ @url_matcher
71
+ end
72
+
73
+ # Get the url associated with this page
74
+ # @see SitePrism::Page.url
75
+ def url
76
+ self.class.url
77
+ end
78
+
79
+ # Get the url matcher associated with this page
80
+ # @see SitePrism::Page.url_matcher
81
+ def url_matcher
82
+ self.class.url_matcher
83
+ end
84
+
85
+ # Gets the title of the current page
86
+ # @return [String, nil] the text value of the title element within the page's head block
87
+ def title
88
+ title_selector = 'html > head > title'
89
+ using_wait_time(0) { page.find(title_selector).text if page.has_selector?(title_selector) }
90
+ end
91
+
92
+ private
93
+
94
+ # Page specific element finder
95
+ def find_one locator
96
+ find locator
97
+ end
98
+
99
+ # Page specific elements finder
100
+ def find_all locator
101
+ all locator
102
+ end
103
+
104
+ def element_exists? locator
105
+ has_selector? locator
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,25 @@
1
+ module SitePrism
2
+ class Section
3
+ extend ElementContainer
4
+
5
+ def initialize root_element
6
+ @root_element = root_element
7
+ end
8
+
9
+ private
10
+
11
+ # Section specific element finder
12
+ def find_one locator
13
+ @root_element.find locator
14
+ end
15
+
16
+ # Section specific elements finder
17
+ def find_all locator
18
+ @root_element.all locator
19
+ end
20
+
21
+ def element_exists? locator
22
+ @root_element.has_selector? locator
23
+ end
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: site_prism
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: "0.9"
6
+ platform: ruby
7
+ authors:
8
+ - Nat Ritmeyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-22 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: capybara
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.1.1
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ description: none just yet...
27
+ email:
28
+ - nat@natontesting.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files: []
34
+
35
+ files:
36
+ - lib/site_prism/element_container.rb
37
+ - lib/site_prism/exceptions.rb
38
+ - lib/site_prism/page.rb
39
+ - lib/site_prism/section.rb
40
+ - lib/site_prism.rb
41
+ - LICENSE
42
+ homepage: http://github.com/natritmeyer/site_prism
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.10
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: none just yet...
69
+ test_files: []
70
+
71
+ has_rdoc: