page-object 0.9.8 → 1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a30377dc0af7ba09c90456f8e21a54a59f55f43f
4
- data.tar.gz: 23f24c2b8aecef31248f0316f68d6fe523bd2598
3
+ metadata.gz: 7c96b938e70722ef3112ed42848c96a2fd3dbf39
4
+ data.tar.gz: 15af3e8cc3af7f269dcacecf24d6f1b38fcb9f9e
5
5
  SHA512:
6
- metadata.gz: 4b9fe63e3d0c4d464b92aed01b9cf33caf9db545c0df3ee5e989a85579bc4093ebc7336ad2a25d5af699fdac667cc7580442e7ea2f3bb4f81aa8e69ed97463c1
7
- data.tar.gz: 70c3f5da44e5b37fcfca5cac3388793ce1a156dceb5cc02706a6abf1406601b95c4a33f79359f15cedafb3d83f68bf457c2564e032a4dc1df4638ce674bcfdb5
6
+ metadata.gz: 99435b3c59bac3889037dca32b76ef15c3f90472855e06e7ea06b816a91e0d7ea82c07edd8f026f3514b1e15739b15f5a6363df9d8bca7fc834eb104243b4df5
7
+ data.tar.gz: e760b232a4f41f862a719585061513902f3b345dd4cd40dba732dd77d4b427bf634fe85059fdcb3c38f150de65063d8d537d595695414b9c96cb1b59eb3e72da
data/ChangeLog CHANGED
@@ -1,3 +1,13 @@
1
+ === Version 1.0 / 2014-6-1
2
+ * Enhancements
3
+ * Better support for using Regexp
4
+ * Added new page_url_value method that is created when you define page_url to return the value
5
+ * Added better error message when nil is passed to the constructor of a PageObject
6
+ * Updated to use the latest watir-webdriver 0.6.9
7
+ * Updated to use the latest selenium-webdriver 2.42.0
8
+ * Fixes
9
+ * Improved handling of index locator
10
+
1
11
  === Version 0.9.8 / 2014-3-16
2
12
  * Enhancements
3
13
  * populate_page_with not supports radio groups
@@ -318,6 +318,5 @@ Feature: Elements
318
318
  When I search for the paragraph by "id"
319
319
  Then I should know the paragraph class is "p_class"
320
320
 
321
- @focus
322
321
  Scenario: Selecting the text for an element
323
322
  Then I should be able to select "Elements" from the paragraph
@@ -19,6 +19,7 @@
19
19
  <select name="sel_list_name" id="sel_list_id" class="sel_list_class">
20
20
  <option value="option1">Test 1</option>
21
21
  <option value="option2">Test 2</option>
22
+ <option value="option3">Test/Test 3</option>
22
23
  </select>
23
24
 
24
25
  <select multiple="multiple" id="sel_list_multiple">
@@ -46,3 +46,7 @@ Feature: Links
46
46
  Scenario: Getting the href for a link
47
47
  When I get the href for the link
48
48
  Then I should know it was "success.html"
49
+
50
+ Scenario: Locating a link using a partial href
51
+ When I get the link using the href success
52
+ Then I should be able to click the link
@@ -9,6 +9,10 @@ Feature: Select List
9
9
  Scenario: Selecting an element on the select list
10
10
  When I select "Test 2" from the select list
11
11
  Then the current item should be "Test 2"
12
+
13
+ Scenario: Selecting an element when there is a forward slash
14
+ When I select "Test/Test 3" from the select list
15
+ Then the current item should be "Test/Test 3"
12
16
 
13
17
  Scenario Outline: Locating select lists on the Page
14
18
  When I search for the select list by "<search_by>"
@@ -30,3 +30,11 @@ end
30
30
  Then(/^I should know it was "(.*?)"$/) do |href|
31
31
  @href.should include href
32
32
  end
33
+
34
+ When(/^I get the link using the href success$/) do
35
+ @link = @page.link_element(:href => /succ.*html/)
36
+ end
37
+
38
+ Then(/^I should be able to click the link$/) do
39
+ @link.click
40
+ end
@@ -39,11 +39,15 @@ module PageObject
39
39
  #
40
40
  def page_url(url)
41
41
  define_method("goto") do
42
+ platform.navigate_to self.page_url_value
43
+ end
44
+
45
+ define_method('page_url_value') do
42
46
  lookup = url.kind_of?(Symbol) ? self.send(url) : url
43
47
  erb = ERB.new(%Q{#{lookup}})
44
48
  merged_params = self.class.instance_variable_get("@merged_params")
45
49
  params = merged_params ? merged_params : self.class.params
46
- platform.navigate_to erb.result(binding)
50
+ erb.result(binding)
47
51
  end
48
52
  end
49
53
  alias_method :direct_url, :page_url
@@ -122,14 +122,14 @@ module PageObject
122
122
  end
123
123
  xpath = ".//button"
124
124
  xpath << "[#{attribute_expression(btn_ident)}]" unless btn_ident.empty?
125
- xpath << "[#{idx+1}]" if idx
125
+ xpath = "(#{xpath})[#{idx+1}]" if idx
126
126
  identifier[:type] = %w[button reset submit image]
127
127
  xpath << " | .//input"
128
128
  else
129
129
  xpath = ".//#{tag_locator}"
130
130
  end
131
131
  xpath << "[#{attribute_expression(identifier)}]" unless identifier.empty?
132
- xpath << "[#{idx+1}]" if idx
132
+ xpath = "(#{xpath})[#{idx+1}]" if idx
133
133
  xpath
134
134
  end
135
135
 
@@ -18,7 +18,9 @@ module PageObject
18
18
  adapters.each_value { |adapter|
19
19
  return adapter.create_page_object(browser) if adapter.is_for?(browser)
20
20
  }
21
- raise 'Unable to pick a platform for the provided browser'
21
+ message = 'Unable to pick a platform for the provided browser.'
22
+ message += "\nnil was passed to the PageObject constructor instead of a valid browser object." if browser.nil?
23
+ raise message
22
24
  end
23
25
  end
24
26
  end
@@ -114,7 +114,7 @@ module PageObject
114
114
  def execute_script(script, *args)
115
115
  @browser.execute_script(script, *args)
116
116
  end
117
-
117
+
118
118
  #
119
119
  # platform method to handle attaching to a running window
120
120
  # See PageObject#attach_to_window
@@ -151,7 +151,7 @@ module PageObject
151
151
  block.call(nil)
152
152
  @browser.switch_to.default_content
153
153
  end
154
-
154
+
155
155
  #
156
156
  # platform method to switch to an iframe and execute a block
157
157
  # See PageObject#in_frame
@@ -161,7 +161,7 @@ module PageObject
161
161
  block.call(nil)
162
162
  @browser.switch_to.default_content
163
163
  end
164
-
164
+
165
165
  #
166
166
  # platform method to refresh the page
167
167
  # See PageObject#refresh
@@ -185,7 +185,7 @@ module PageObject
185
185
  def forward
186
186
  @browser.navigate.forward
187
187
  end
188
-
188
+
189
189
  #
190
190
  # platform method to clear the cookies from the browser
191
191
  # See PageObject#clear_cookies
@@ -193,7 +193,7 @@ module PageObject
193
193
  def clear_cookies
194
194
  @browser.manage.delete_all_cookies
195
195
  end
196
-
196
+
197
197
  #
198
198
  # platform method to save the current screenshot to a file
199
199
  # See PageObject#save_screenshot
@@ -534,7 +534,7 @@ module PageObject
534
534
  def buttons_for(identifier)
535
535
  find_selenium_elements(identifier, Elements::Button, 'input', :type => 'submit')
536
536
  end
537
-
537
+
538
538
  #
539
539
  # platform method to return the text for a table
540
540
  # See PageObject::Accessors#table
@@ -682,7 +682,7 @@ module PageObject
682
682
  def ordered_list_for(identifier)
683
683
  find_selenium_element(identifier, Elements::OrderedList, 'ol')
684
684
  end
685
-
685
+
686
686
  #
687
687
  # platform method to retrieve all ordered lists
688
688
  #
@@ -699,7 +699,7 @@ module PageObject
699
699
  @browser.find_element(how, what).text
700
700
  end
701
701
  end
702
-
702
+
703
703
  #
704
704
  # platform method to retrieve the h1 element
705
705
  # See PageObject::Accessors#h1
@@ -724,7 +724,7 @@ module PageObject
724
724
  @browser.find_element(how, what).text
725
725
  end
726
726
  end
727
-
727
+
728
728
  #
729
729
  # platform method to retrieve the h2 element
730
730
  # See PageObject::Accessors#h2
@@ -749,7 +749,7 @@ module PageObject
749
749
  @browser.find_element(how, what).text
750
750
  end
751
751
  end
752
-
752
+
753
753
  #
754
754
  # platform method to retrieve the h3 element
755
755
  # See PageObject::Accessors#h3
@@ -774,7 +774,7 @@ module PageObject
774
774
  @browser.find_element(how, what).text
775
775
  end
776
776
  end
777
-
777
+
778
778
  #
779
779
  # platform method to retrieve the h4 element
780
780
  # See PageObject::Accessors#h4
@@ -799,7 +799,7 @@ module PageObject
799
799
  @browser.find_element(how, what).text
800
800
  end
801
801
  end
802
-
802
+
803
803
  #
804
804
  # platform method to retrieve the h5 element
805
805
  # See PageObject::Accessors#h5
@@ -824,7 +824,7 @@ module PageObject
824
824
  @browser.find_element(how, what).text
825
825
  end
826
826
  end
827
-
827
+
828
828
  #
829
829
  # platform method to retrieve the h6 element
830
830
  # See PageObject::Accessors#h6
@@ -849,7 +849,7 @@ module PageObject
849
849
  @browser.find_element(how, what).text
850
850
  end
851
851
  end
852
-
852
+
853
853
  #
854
854
  # platform method to retrieve the paragraph element
855
855
  # See PageObject::Accessors#paragraph
@@ -953,7 +953,7 @@ module PageObject
953
953
  def canvass_for(identifier)
954
954
  find_selenium_elements(identifier, Elements::Canvas, 'canvas')
955
955
  end
956
-
956
+
957
957
  #
958
958
  # platform method to retrieve an audio element
959
959
  #
@@ -967,7 +967,7 @@ module PageObject
967
967
  def audios_for(identifier)
968
968
  find_selenium_elements(identifier, Elements::Audio, 'audio')
969
969
  end
970
-
970
+
971
971
  #
972
972
  # platform method to retrieve a video element
973
973
  #
@@ -981,7 +981,7 @@ module PageObject
981
981
  def videos_for(identifier)
982
982
  find_selenium_elements(identifier, Elements::Video, 'video')
983
983
  end
984
-
984
+
985
985
  #
986
986
  # platform method to retrieve a generic element
987
987
  # See PageObject::Accessors#element
@@ -1004,16 +1004,16 @@ module PageObject
1004
1004
  def svg_for(identifier)
1005
1005
  find_selenium_element(identifier, Elements::Element, 'svg')
1006
1006
  end
1007
-
1007
+
1008
1008
  #
1009
1009
  # platform method to return an array of svg elements
1010
1010
  #
1011
1011
  def svgs_for(identifier)
1012
1012
  find_selenium_elements(identifier, Elements::Element, 'svg')
1013
1013
  end
1014
-
1014
+
1015
1015
  private
1016
-
1016
+
1017
1017
  def process_selenium_call(identifier, type, tag, other=nil)
1018
1018
  how, what, frame_identifiers = parse_identifiers(identifier, type, tag, other)
1019
1019
  switch_to_frame(frame_identifiers)
@@ -1023,10 +1023,16 @@ module PageObject
1023
1023
  end
1024
1024
 
1025
1025
  def find_selenium_element(identifier, type, tag, other=nil)
1026
+ regexp = delete_regexp(identifier)
1026
1027
  how, what, frame_identifiers = parse_identifiers(identifier, type, tag, other)
1027
1028
  switch_to_frame(frame_identifiers)
1028
1029
  begin
1029
- element = @browser.find_element(how, what)
1030
+ unless regexp
1031
+ element = @browser.find_element(how, what)
1032
+ else
1033
+ elements = @browser.find_elements(how, what)
1034
+ element = elements.find {|ele| matches_selector?(ele, regexp[0], regexp[1])}
1035
+ end
1030
1036
  rescue Selenium::WebDriver::Error::NoSuchElementError
1031
1037
  @browser.switch_to.default_content unless frame_identifiers.nil?
1032
1038
  return build_null_object(identifier, type, tag, other)
@@ -1036,9 +1042,15 @@ module PageObject
1036
1042
  end
1037
1043
 
1038
1044
  def find_selenium_elements(identifier, type, tag, other=nil)
1045
+ regexp = delete_regexp(identifier)
1039
1046
  how, what, frame_identifiers = parse_identifiers(identifier, type, tag, other)
1040
1047
  switch_to_frame(frame_identifiers)
1041
- elements = @browser.find_elements(how, what)
1048
+ unless regexp
1049
+ elements = @browser.find_elements(how, what)
1050
+ else
1051
+ eles = @browser.find_elements(how, what)
1052
+ elements = eles.find_all {|ele| matches_selector?(ele, regexp[0], regexp[1])}
1053
+ end
1042
1054
  @browser.switch_to.default_content unless frame_identifiers.nil?
1043
1055
  elements.map { |element| type.new(element, :platform => :selenium_webdriver) }
1044
1056
  end
@@ -1053,6 +1065,12 @@ module PageObject
1053
1065
  Elements::Element.new(null_element, :platform => :selenium_webdriver)
1054
1066
  end
1055
1067
 
1068
+ def delete_regexp(identifier)
1069
+ regexp = identifier.find {|ident| ident[1].is_a?(Regexp)}
1070
+ identifier.delete(regexp[0]) if regexp
1071
+ regexp
1072
+ end
1073
+
1056
1074
  def parse_identifiers(identifier, element, tag_name=nil, additional=nil)
1057
1075
  frame_identifiers = identifier.delete(:frame)
1058
1076
  identifier = add_tagname_if_needed identifier, tag_name, additional if tag_name
@@ -1096,6 +1114,23 @@ module PageObject
1096
1114
  true
1097
1115
  end
1098
1116
 
1117
+ def matches_selector?(element, how, what)
1118
+ what === fetch_value(element, how)
1119
+ end
1120
+
1121
+ def fetch_value(element, how)
1122
+ case how
1123
+ when :text
1124
+ element.text
1125
+ when :tag_name
1126
+ element.tag_name.downcase
1127
+ when :href
1128
+ (href = element.attribute(:href)) && href.strip
1129
+ else
1130
+ element.attribute(how.to_s.gsub("_", "-").to_sym)
1131
+ end
1132
+ end
1133
+
1099
1134
  def switch_to_frame(frame_identifiers)
1100
1135
  unless frame_identifiers.nil?
1101
1136
  frame_identifiers.each do |frame|
@@ -1103,7 +1138,7 @@ module PageObject
1103
1138
  value = frame_id.values.first
1104
1139
  @browser.switch_to.frame(value)
1105
1140
  end
1106
- end
1141
+ end
1107
1142
  end
1108
1143
  end
1109
1144
  end
@@ -1,4 +1,4 @@
1
1
  module PageObject
2
2
  # @private
3
- VERSION = "0.9.8"
3
+ VERSION = "1.0"
4
4
  end
data/page-object.gemspec CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
 
23
- s.add_dependency 'watir-webdriver', '>= 0.6.8'
24
- s.add_dependency 'selenium-webdriver', '>= 2.40.0'
23
+ s.add_dependency 'watir-webdriver', '>= 0.6.9'
24
+ s.add_dependency 'selenium-webdriver', '>= 2.42.0'
25
25
  s.add_dependency 'page_navigation', '>= 0.9'
26
26
 
27
27
  s.add_development_dependency 'rspec', '>= 2.14.0'
@@ -1003,7 +1003,7 @@ describe PageObject::ElementLocators do
1003
1003
  end
1004
1004
 
1005
1005
  it "should find an area element using a default identifier" do
1006
- selenium_browser.should_receive(:find_element).with(:xpath, './/area[1]').and_return(selenium_browser)
1006
+ selenium_browser.should_receive(:find_element).with(:xpath, '(.//area)[1]').and_return(selenium_browser)
1007
1007
  selenium_page_object.area_element
1008
1008
  end
1009
1009
 
@@ -1025,7 +1025,7 @@ describe PageObject::ElementLocators do
1025
1025
  end
1026
1026
 
1027
1027
  it "should find a canvas element using a default identifier" do
1028
- selenium_browser.should_receive(:find_element).with(:xpath, './/canvas[1]').and_return(selenium_browser)
1028
+ selenium_browser.should_receive(:find_element).with(:xpath, '(.//canvas)[1]').and_return(selenium_browser)
1029
1029
  selenium_page_object.canvas_element
1030
1030
  end
1031
1031
 
@@ -1047,7 +1047,7 @@ describe PageObject::ElementLocators do
1047
1047
  end
1048
1048
 
1049
1049
  it "should find an audio element using a default identifier" do
1050
- selenium_browser.should_receive(:find_element).with(:xpath, './/audio[1]').and_return(selenium_browser)
1050
+ selenium_browser.should_receive(:find_element).with(:xpath, '(.//audio)[1]').and_return(selenium_browser)
1051
1051
  selenium_page_object.audio_element
1052
1052
  end
1053
1053
 
@@ -28,7 +28,7 @@ describe "Element" do
28
28
  identifier = {:tag_name => tag, :index => 1}
29
29
  how, what = PageObject::Elements::Element.selenium_identifier_for identifier
30
30
  how.should == :xpath
31
- what.should == ".//#{tag}[2]"
31
+ what.should == "(.//#{tag})[2]"
32
32
  end
33
33
  end
34
34
 
@@ -37,7 +37,7 @@ describe "Element" do
37
37
  identifier = {:tag_name => 'input', :type => tag, :index => 1}
38
38
  how, what = PageObject::Elements::Element.selenium_identifier_for identifier
39
39
  how.should == :xpath
40
- what.should include ".//input[@type='#{tag}'][2]"
40
+ what.should include "(.//input[@type='#{tag}'])[2]"
41
41
  end
42
42
  end
43
43
 
@@ -46,7 +46,7 @@ describe "Element" do
46
46
  identifier = {:tag_name => tag, :name => 'blah', :index => 0}
47
47
  how, what = PageObject::Elements::Element.selenium_identifier_for identifier
48
48
  how.should == :xpath
49
- what.should == ".//#{tag}[@name='blah'][1]"
49
+ what.should == "(.//#{tag}[@name='blah'])[1]"
50
50
  end
51
51
  end
52
52
 
@@ -55,7 +55,7 @@ describe "Element" do
55
55
  identifier = {:tag_name => 'input', :type => "#{type}", :name => 'blah', :index => 0}
56
56
  how, what = PageObject::Elements::Element.selenium_identifier_for identifier
57
57
  how.should == :xpath
58
- what.should include ".//input[@type='#{type}' and @name='blah'][1]"
58
+ what.should include "(.//input[@type='#{type}' and @name='blah'])[1]"
59
59
  end
60
60
  end
61
61
 
@@ -5,6 +5,7 @@ end
5
5
  describe TestLoadsPlatform do
6
6
  let(:subject) { TestLoadsPlatform.new }
7
7
  let(:adapters) { {} }
8
+
8
9
  context "when browser x is registered with platform nom_nom_nom" do
9
10
  let(:browser_x) { double('browser') }
10
11
  before { adapters[:browser_x] = mock_adapter(browser_x, :nom_nom_nom) }
@@ -12,27 +13,41 @@ describe TestLoadsPlatform do
12
13
  it "returns platform nom_nom_nom when asked about browser_x" do
13
14
  subject.load_platform(browser_x, adapters).should == :nom_nom_nom
14
15
  end
16
+
15
17
  context "when browser a is registered with platform boom_boom_boom" do
16
18
  let(:browser_a) { double('browser') }
17
19
  before { adapters[:browser_a] = mock_adapter(browser_a, :boom_boom_boom) }
20
+
18
21
  it "should return platform nom_nom_nom when asked about browser_x" do
19
22
  subject.load_platform(browser_x, adapters).should == :nom_nom_nom
20
23
  end
21
24
  end
22
25
  end
26
+
23
27
  context "when browser a is registered with platform boom_boom_boom" do
24
28
  let(:browser_n) { double('browser') }
25
29
  before { adapters[:browser_n] = mock_adapter(browser_n, :boom_boom_boom) }
30
+
26
31
  it "should return platform boom_boom_boom" do
27
32
  subject.load_platform(browser_n, adapters).should == :boom_boom_boom
28
33
  end
29
34
  end
30
35
 
31
36
  context "When an unknow object is passed in" do
37
+ let(:basic_message) { 'Unable to pick a platform for the provided browser.' }
38
+
32
39
  it "should throw an exception" do
33
40
  expect {
34
- subject.load_platform("browser")
35
- }.to raise_error
41
+ subject.load_platform("browser", {})
42
+ }.to raise_error(basic_message)
43
+ end
44
+
45
+ it "should notify when the browser is nil" do
46
+ begin
47
+ subject.load_platform(nil, {})
48
+ rescue Exception => e
49
+ e.message.should == "#{basic_message}\nnil was passed to the PageObject constructor instead of a valid browser object."
50
+ end
36
51
  end
37
52
  end
38
53
  end
@@ -158,7 +158,7 @@ describe PageObject::Accessors do
158
158
  SymbolPageUrl.new(watir_browser, true, 'custom')
159
159
 
160
160
  watir_browser.should_receive(:goto).with('different')
161
- SymbolPageUrl.new(watir_browser, true, 'different')
161
+ SymbolPageUrl.new(watir_browser, true, 'different')
162
162
  end
163
163
 
164
164
  it "should not navigate to a page when not requested" do
@@ -170,6 +170,10 @@ describe PageObject::Accessors do
170
170
  watir_browser.should_not_receive(:goto)
171
171
  WatirBlockPageObject.new(watir_browser, true)
172
172
  end
173
+
174
+ it "should provide the page url" do
175
+ watir_page_object.page_url_value.should == 'http://apple.com'
176
+ end
173
177
  end
174
178
 
175
179
  context "validating the page title" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: page-object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Morgan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-16 00:00:00.000000000 Z
11
+ date: 2014-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: watir-webdriver
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.8
19
+ version: 0.6.9
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.6.8
26
+ version: 0.6.9
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: selenium-webdriver
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 2.40.0
33
+ version: 2.42.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 2.40.0
40
+ version: 2.42.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: page_navigation
43
43
  requirement: !ruby/object:Gem::Requirement