page_magic 0.10.0 → 0.11.0.alpha

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/spec/element_spec.rb CHANGED
@@ -1,9 +1,8 @@
1
- require 'spec_helper'
2
1
  require 'sinatra'
3
2
 
4
-
5
3
  describe 'Page elements' do
6
4
 
5
+
7
6
  before :each do
8
7
  Capybara.app = Class.new(Sinatra::Base) do
9
8
  get '/' do
@@ -12,6 +11,7 @@ describe 'Page elements' do
12
11
  <input id='field_id' name='field_name' class='input_class' type='text' value='filled in'/>
13
12
  </label>
14
13
  <a id=my_link href='#'>my link</a>
14
+ <button id=my_button href='#'>my button</button>
15
15
  HTML
16
16
  end
17
17
  end
@@ -19,6 +19,25 @@ describe 'Page elements' do
19
19
  Capybara.current_session.visit('/')
20
20
  end
21
21
 
22
+ describe 'construction' do
23
+
24
+ let(:page_section_class) do
25
+ Class.new(PageMagic::Element)
26
+ end
27
+
28
+ let(:selector) { {css: '.class_name'} }
29
+
30
+ let!(:browser) { double('browser', find: :browser_element) }
31
+ let!(:parent_page_element) { double('parent_page_element', browser_element: browser) }
32
+
33
+ end
34
+
35
+ describe 'browser_element' do
36
+ it 'should raise an error if a selector has not been specified' do
37
+ expect { PageMagic::Element.new(:name, Object.new, :type).browser_element }.to raise_error(PageMagic::UndefinedSelectorException)
38
+ end
39
+ end
40
+
22
41
  describe 'location' do
23
42
  let!(:browser) { double('browser') }
24
43
  let!(:page) do
@@ -28,53 +47,109 @@ describe 'Page elements' do
28
47
  page_class.new
29
48
  end
30
49
 
31
- it 'should locate an element using its id' do
32
- element = PageMagic::Element.new(:my_input,page, :text_field, id:'field_id').locate
50
+ it 'should find by xpath' do
51
+ element = PageMagic::Element.new(:my_input, page, :text_field, xpath: '//input').browser_element
33
52
  element.value == 'filled in'
34
53
  end
35
54
 
36
- it 'should locate an element using its name' do
37
- element = PageMagic::Element.new(:my_input,page, :text_field, name:'field_name').locate
38
- element.value == 'filled in'
55
+ it 'should locate an element using its id' do
56
+ element = PageMagic::Element.new(:my_input, page, :text_field, id: 'field_id').browser_element
57
+ element.value.should == 'filled in'
39
58
  end
40
59
 
41
- it 'should locate a link using its text' do
42
- element = PageMagic::Element.new(:my_link,page, :link, text: 'my link').locate
43
- element[:id].should == 'my_link'
60
+ it 'should locate an element using its name' do
61
+ element = PageMagic::Element.new(:my_input, page, :text_field, name: 'field_name').browser_element
62
+ element.value.should == 'filled in'
44
63
  end
45
64
 
65
+
46
66
  it 'should locate an element using its label' do
47
- element = PageMagic::Element.new(:my_link,page, :link, label: 'enter text').locate
67
+ element = PageMagic::Element.new(:my_link, page, :link, label: 'enter text').browser_element
48
68
  element[:id].should == 'field_id'
49
69
  end
50
70
 
51
71
  it 'should raise an exception when finding another element using its text' do
52
- expect{PageMagic::Element.new(:my_link,page, :text_field, text: 'my link').locate}.to raise_error(PageMagic::UnsupportedSelectorException)
72
+ expect { PageMagic::Element.new(:my_link, page, :text_field, text: 'my link').browser_element }.to raise_error(PageMagic::UnsupportedSelectorException)
53
73
  end
54
74
 
55
75
  it 'should locate an element using css' do
56
- element = PageMagic::Element.new(:my_link,page, :link, css: "input[name='field_name']").locate
76
+ element = PageMagic::Element.new(:my_link, page, :link, css: "input[name='field_name']").browser_element
57
77
  element[:id].should == 'field_id'
58
78
  end
59
79
 
80
+
81
+ it 'should return a prefetched value' do
82
+ PageMagic::Element.new(:help, page, :link, :prefetched_object).browser_element.should == :prefetched_object
83
+ end
84
+
60
85
  it 'should raise errors for unsupported selectors' do
61
- expect{PageMagic::Element.new(:my_link,page, :link, unsupported:"").locate}.to raise_error(PageMagic::UnsupportedSelectorException)
86
+ expect { PageMagic::Element.new(:my_link, page, :link, unsupported: "").browser_element }.to raise_error(PageMagic::UnsupportedSelectorException)
62
87
  end
63
88
 
89
+ context 'text selector' do
90
+ it 'should locate a link' do
91
+ element = PageMagic::Element.new(:my_link, page, :link, text: 'my link').browser_element
92
+ element[:id].should == 'my_link'
93
+ end
64
94
 
95
+ it 'should locate a button' do
96
+ element = PageMagic::Element.new(:my_button, page, :button, text: 'my button').browser_element
97
+ element[:id].should == 'my_button'
98
+ end
99
+ end
100
+ end
101
+
102
+ describe 'session' do
103
+ it 'should have a handle to the session' do
104
+ page_class = Class.new do
105
+ include PageMagic
106
+ end
107
+ page = page_class.new
65
108
 
66
- it 'should return the browser element if a selector was not specified' do
67
- PageMagic::Element.new(:help, browser, :link, nil).locate.should == browser
109
+ PageMagic::Element.new(:help, page, :link, :selector).session.should == page.session
68
110
  end
111
+ end
69
112
 
70
- #TODO - Bug here, parent element reference is not available
71
- it 'should return a prefetched value' do
72
- PageMagic::Element.new(:help, "prefetched text", :link ).locate.should == "prefetched text"
113
+
114
+ context 'tests coppied in from section' do
115
+ include_context :webapp
116
+
117
+ before :each do
118
+ @elements_page = elements_page.new
119
+ @elements_page.visit
73
120
  end
74
121
 
75
- it 'should have a handle to the session' do
76
- PageMagic::Element.new(:help, page, :link, :selector ).session.should == page.session
122
+ let!(:elements_page) do
123
+
124
+ Class.new do
125
+ include PageMagic
126
+ url '/elements'
127
+ section :form_by_css do
128
+ selector css: '.form'
129
+ link(:link_in_form, text: 'a in a form')
130
+ end
131
+
132
+ section :form_by_id do
133
+ selector id: 'form'
134
+ link(:link_in_form, text: 'a in a form')
135
+ end
136
+ end
137
+ end
138
+
139
+ describe 'method_missing' do
140
+ it 'should delegate to capybara' do
141
+ @elements_page.form_by_css.visible?.should be(true)
142
+ end
143
+
144
+ it 'should throw default exception if the method does not exist on the capybara object' do
145
+ expect { @elements_page.form_by_css.bobbins }.to raise_exception NoMethodError
146
+ end
147
+ end
148
+
149
+ it 'can have elements' do
150
+ @elements_page.form_by_css.link_in_form.visible?.should be_true
77
151
  end
78
152
  end
79
153
 
154
+
80
155
  end
@@ -3,34 +3,12 @@ require 'page_magic'
3
3
 
4
4
  describe 'member methods' do
5
5
 
6
- let(:page_object_class) do
7
- Class.new do
8
- extend PageMagic::Elements
9
- end
10
- end
11
6
 
12
- it 'should say you have fields when you do' do
13
- page_object_class.elements?.should == false
14
- page_object_class.link(:link, :text => "text")
15
- page_object_class.elements?.should == true
16
- end
17
7
 
18
8
 
19
- describe 'the element types that you can define' do
20
- PageMagic::Elements::TYPES.each do |element_type|
21
9
 
22
- it "can have a #{element_type}" do
23
- parent_page_element = double('parent_page_object', browser_element: double('browser_element'))
24
- friendly_name = "#{element_type}_name".to_sym
25
10
 
26
- page_object_class.send(element_type, friendly_name,{})
27
11
 
28
12
 
29
- expected_element = PageMagic::Element.new(friendly_name,parent_page_element, element_type, {})
30
- page_object_class.element_definitions[friendly_name].call(parent_page_element) == expected_element
31
- end
32
- end
33
- end
34
-
35
13
 
36
14
  end
@@ -16,101 +16,55 @@ describe PageMagic::Elements do
16
16
  double('parent_page_element', browser_element: browser_element)
17
17
  end
18
18
 
19
-
20
19
  describe 'adding elements' do
21
20
 
22
21
  context 'using a selector' do
23
22
  it 'should add an element' do
23
+ expected_element = PageMagic::Element.new(:name, parent_page_element, :text_field, selector)
24
24
  page_elements.text_field :name, selector
25
- page_elements.element_definitions[:name].call(parent_page_element).should == PageMagic::Element.new(:name, parent_page_element, :text_field, selector)
26
- end
27
-
28
- it 'should return your a copy of the core definition' do
29
- page_elements.text_field :name, selector
30
- first = page_elements.element_definitions[:name].call(parent_page_element)
31
- second = page_elements.element_definitions[:name].call(parent_page_element)
32
- first.should_not equal(second)
33
- end
34
- end
35
-
36
- context 'passing in a prefetched watir object' do
37
- it 'should create a page element with the prefetched watir object as the core browser object' do
38
- watir_element = double('watir_element')
39
- page_elements.text_field :name, watir_element
40
- page_elements.elements(browser_element).first.locate.should == watir_element
41
- end
42
- end
43
-
44
- end
45
-
46
- context 'section' do
47
-
48
- let!(:section_class) do
49
- Class.new do
50
- extend PageMagic::Section
51
-
52
- def == object
53
- object.class.is_a?(PageMagic::Section) &&
54
- object.name == self.name &&
55
- object.browser_element == self.browser_element
56
- end
25
+ page_elements.element_definitions[:name].call(parent_page_element).should == expected_element
57
26
  end
58
27
  end
59
28
 
60
- context 'session handle' do
61
- it 'should be on instances created from a class' do
29
+ context 'complex elements' do
62
30
 
63
- browser_element = double(:browser_element, find: :browser_element)
64
- parent = double('parent', session: :current_session, browser_element: browser_element)
65
- page_elements.section section_class, :page_section, selector
66
31
 
67
- section = page_elements.element_definitions[:page_section].call(parent)
32
+ let!(:section_class) do
33
+ Class.new(PageMagic::Element) do
68
34
 
69
- section.session.should == :current_session
35
+ def == other
70
36
 
71
- end
72
-
73
- it 'should be on instances created dynamically using the section method' do
74
-
75
- browser_element = double('browser_element')
76
- browser_element.stub(:find)
77
- parent = double('parent', session: :current_session, browser_element: browser_element)
78
-
79
- page_elements.section :page_section, css: :selector do
37
+ other.name == self.name &&
38
+ other.browser_element == self.browser_element
39
+ end
80
40
 
81
41
  end
82
-
83
- section = page_elements.element_definitions[:page_section].call(parent)
84
- section.session.should == :current_session
85
42
  end
86
- end
87
-
88
- describe 'definition' do
89
43
 
90
-
91
- context 'using a class as a definition' do
44
+ context 'using a predefined class' do
92
45
  it 'should add a section' do
46
+ expected_section = section_class.new(:page_section, parent_page_element, :section, selector)
47
+
93
48
  page_elements.section section_class, :page_section, selector
94
- page_elements.elements(parent_page_element).first.should == section_class.new(parent_page_element, :page_section, selector)
49
+ page_elements.elements(parent_page_element).first.should == expected_section
95
50
  end
96
- end
97
51
 
98
- it 'should not require a block' do
99
- expect { page_elements.section :page_section, :object }.not_to raise_exception
100
- end
52
+ context 'name' do
53
+ it 'should default to the name of the class if one is not supplied' do
54
+ section_class.stub(:name).and_return('PageSection')
55
+ page_elements.section section_class, selector
56
+ page_elements.elements(parent_page_element).first.name.should == :page_section
101
57
 
102
- context 'an object that has already been found' do
103
- it 'should add a section' do
104
- page_elements.section :page_section, :object
58
+ end
59
+ end
105
60
 
106
- section_class.browser_element = :object
107
- expected_section = section_class.new(parent_page_element, :page_section, nil)
108
- expected_section.should == page_elements.elements(parent_page_element).first
61
+ it 'does not require a block' do
62
+ expect { page_elements.section :page_section, :object }.not_to raise_exception
109
63
  end
110
64
  end
111
65
 
112
66
 
113
- context 'using a block to define a section inline' do
67
+ context 'using a block' do
114
68
 
115
69
  context 'browser_element' do
116
70
  before :each do
@@ -134,7 +88,6 @@ describe PageMagic::Elements do
134
88
  element = @element
135
89
 
136
90
  page_elements.section :page_section do
137
- browser_element.should == nil
138
91
  selector css: :selector
139
92
  browser_element.should == element
140
93
  end
@@ -143,16 +96,6 @@ describe PageMagic::Elements do
143
96
  end
144
97
  end
145
98
 
146
- it 'should raise an exception if the selector is not passed' do
147
-
148
- arg, browser, element = {}, double('browser'), double('element')
149
- parent_page_element = double('parent_browser_element', browser_element: browser)
150
-
151
- page_elements.section :page_section, nil
152
-
153
- expect { page_elements.elements(parent_page_element, arg) }.to raise_error(PageMagic::Section::UndefinedSelectorException)
154
- end
155
-
156
99
 
157
100
  it 'should pass args through to the block' do
158
101
  page_elements.section :page_section, css: '.blah' do |arg|
@@ -165,17 +108,65 @@ describe PageMagic::Elements do
165
108
  arg[:passed_through].should be_true
166
109
  end
167
110
 
111
+
112
+ it 'should return your a copy of the core definition' do
113
+ page_elements.section section_class, :page_section, selector
114
+ first = page_elements.element_definitions[:page_section].call(parent_page_element)
115
+ second = page_elements.element_definitions[:page_section].call(parent_page_element)
116
+ first.should_not equal(second)
117
+ end
118
+
168
119
  end
169
120
 
170
- it 'should return your a copy of the core definition' do
171
- page_elements.section section_class, :page_section, selector
172
- first = page_elements.element_definitions[:page_section].call(parent_page_element)
173
- second = page_elements.element_definitions[:page_section].call(parent_page_element)
174
- first.should_not equal(second)
121
+ describe 'location' do
122
+ context 'a prefetched object' do
123
+ it 'should add a section' do
124
+ expected_section = section_class.new(:page_section, parent_page_element, :section, :object)
125
+ page_elements.section :page_section, :object
126
+ expected_section.should == page_elements.elements(parent_page_element).first
127
+ end
128
+ end
129
+ end
130
+
131
+ describe 'session handle' do
132
+ it 'should be on instances created from a class' do
133
+ browser_element = double(:browser_element, find: :browser_element)
134
+ parent = double('parent', session: :current_session, browser_element: browser_element)
135
+ page_elements.section section_class, :page_section, selector
136
+
137
+ section = page_elements.element_definitions[:page_section].call(parent)
138
+
139
+ section.session.should == :current_session
140
+
141
+ end
142
+
143
+ it 'should be on instances created dynamically using the section method' do
144
+
145
+ browser_element = double('browser_element')
146
+ browser_element.stub(:find)
147
+ parent = double('parent', session: :current_session, browser_element: browser_element)
148
+
149
+ page_elements.section :page_section, css: :selector do
150
+
151
+ end
152
+
153
+ section = page_elements.element_definitions[:page_section].call(parent)
154
+ section.session.should == :current_session
155
+ end
175
156
  end
176
157
  end
177
158
  end
178
159
 
160
+ describe 'retrieving element definitions' do
161
+ it 'should return your a copy of the core definition' do
162
+ page_elements.text_field :name, selector
163
+ first = page_elements.element_definitions[:name].call(parent_page_element)
164
+ second = page_elements.element_definitions[:name].call(parent_page_element)
165
+ first.should_not equal(second)
166
+ end
167
+ end
168
+
169
+
179
170
 
180
171
  describe 'restrictions' do
181
172
  it 'should not allow method names that match element names' do
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ describe 'The Elements of a Page' do
3
+ include Capybara::DSL
4
+
5
+ describe 'a Page Class' do
6
+
7
+ end
8
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'sinatra/base'
3
+
4
+ describe 'The Elements of a Page' do
5
+
6
+ describe 'instances' do
7
+
8
+ include_context :webapp
9
+
10
+ let(:my_page_class) do
11
+ Class.new do
12
+ include PageMagic
13
+ url '/page1'
14
+ link(:next, :text => "next page")
15
+ end
16
+ end
17
+
18
+ let(:another_page_class) do
19
+ Class.new do
20
+ include PageMagic
21
+ url '/another_page1'
22
+ end
23
+ end
24
+
25
+ before :each do
26
+ @page = my_page_class.new
27
+ end
28
+
29
+
30
+ describe 'browser integration' do
31
+ it "should use capybara's default session if a one is not supplied" do
32
+ Capybara.default_driver = :rack_test
33
+ my_page_class.new.browser.mode.should == :rack_test
34
+ end
35
+ end
36
+
37
+
38
+ it 'should copy fields on to element' do
39
+ new_page = my_page_class.new
40
+ @page.element_definitions[:next].call(@page).should_not equal(new_page.element_definitions[:next].call(new_page))
41
+ end
42
+
43
+ it 'gives access to the page text' do
44
+ @page.visit.text.should == 'next page'
45
+ end
46
+
47
+ it 'should access a field' do
48
+ @page.visit
49
+ @page.click_next
50
+ @page.text.should == 'page 2 content'
51
+ end
52
+
53
+ it 'are registered at class level' do
54
+ PageMagic.instance_variable_set(:@pages, nil)
55
+
56
+ page = Class.new { include PageMagic }
57
+ PageMagic.pages.should == [page]
58
+ end
59
+ end
60
+
61
+ describe 'inheritance' do
62
+ let(:parent_page) do
63
+ Class.new do
64
+ include PageMagic
65
+ link(:next, :text => "next page")
66
+ end
67
+ end
68
+
69
+ let(:child_page) do
70
+ Class.new(parent_page)
71
+ end
72
+
73
+ context 'children' do
74
+ it 'should inherit elements defined on the parent class' do
75
+ child_page.element_definitions.should include(:next)
76
+ end
77
+
78
+ it 'are added to PageMagic.pages list' do
79
+ PageMagic.pages.should include(child_page)
80
+ end
81
+
82
+ it 'should pass on element definitions to their children' do
83
+ grand_child_class = Class.new(child_page)
84
+ grand_child_class.element_definitions.should include(:next)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'including PageMagic' do
4
+ include Capybara::DSL
5
+
6
+ context 'lets you define pages' do
7
+ let :page_class do
8
+ Class.new{include PageMagic}
9
+ end
10
+
11
+ it 'gives a method for defining the url' do
12
+ page_class.url :url
13
+ page_class.url.should == :url
14
+ end
15
+
16
+ it 'lets you define elements' do
17
+ page_class.is_a?(PageMagic::Elements).should be_true
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,56 @@
1
+ describe 'interacting with pages' do
2
+ include_context :webapp
3
+
4
+ let :page do
5
+ Class.new do
6
+ include PageMagic
7
+ link(:next_page, text: 'next page')
8
+ url '/page1'
9
+ end.new
10
+ end
11
+
12
+ before(:each) { page.visit }
13
+
14
+ describe 'visit' do
15
+ it 'goes to the class define url' do
16
+ page.visit
17
+ page.session.current_path.should == '/page1'
18
+ end
19
+ end
20
+
21
+ describe 'session' do
22
+ it 'gives access to the page magic object wrapping the user session' do
23
+ page.session.raw_session.should == Capybara.current_session
24
+ end
25
+ end
26
+
27
+ describe 'text_on_page?' do
28
+ it 'returns true if the text is present' do
29
+ page.text_on_page?('next page').should be_true
30
+ end
31
+
32
+ it 'returns false if the text is not present' do
33
+ page.text_on_page?('not on page').should be_false
34
+ end
35
+ end
36
+
37
+ describe 'title' do
38
+ it 'returns the title' do
39
+ page.title.should == 'page1'
40
+ end
41
+ end
42
+
43
+ describe 'text' do
44
+ it 'returns the text on the page' do
45
+ page.text.should == 'next page'
46
+ end
47
+ end
48
+
49
+ describe 'method_missing' do
50
+ it 'gives access to the elements defined on your page classes' do
51
+ page.next_page.tag_name.should == 'a'
52
+ end
53
+ end
54
+
55
+ end
56
+
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ describe 'PageMagic.session' do
3
+ let(:app_class) do
4
+ Class.new do
5
+ def call env
6
+ [200, {}, ["hello world!!"]]
7
+ end
8
+ end
9
+ end
10
+
11
+ def registered_driver browser
12
+ Capybara.drivers[browser].call(nil)
13
+ end
14
+
15
+ context 'using a symbol as a parameter' do
16
+ it 'sets up a session using the specified browser' do
17
+ Capybara::Session.should_receive(:new).with(:chrome, nil).and_return(:chrome_session)
18
+
19
+ session = PageMagic.session(:chrome)
20
+
21
+ registered_driver(:chrome).should == Capybara::Selenium::Driver.new(nil, browser: :chrome)
22
+
23
+ session.raw_session.should == :chrome_session
24
+ end
25
+
26
+ context 'browsers' do
27
+ it 'supports poltergeist' do
28
+ session = PageMagic.session(:poltergeist, application: app_class.new)
29
+ session.raw_session.driver.is_a?(Capybara::Poltergeist::Driver).should be_true
30
+ end
31
+
32
+ it 'supports selenium' do
33
+ session = PageMagic.session(:firefox, application: app_class.new)
34
+ session.raw_session.driver.is_a?(Capybara::Selenium::Driver).should be_true
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'defaulting the browser used from PageMagic sessions' do
40
+ it "uses what ever Capybara's default_driver is set to" do
41
+ Capybara.default_driver = :rack_test
42
+ session = PageMagic.session
43
+ session.raw_session.mode.should == :rack_test
44
+ end
45
+ end
46
+
47
+ context 'testing against rack applications' do
48
+
49
+ it 'requires the app to be supplied' do
50
+ session = PageMagic.session(application: app_class.new)
51
+ session.raw_session.visit('/')
52
+ session.raw_session.text.should == 'hello world!!'
53
+ end
54
+
55
+ it 'can run against an rack application using a particular browser' do
56
+ session = PageMagic.session(:rack_test, application: app_class.new)
57
+ session.raw_session.mode.should == :rack_test
58
+ session.raw_session.visit('/')
59
+ session.raw_session.text.should == 'hello world!!'
60
+ end
61
+ end
62
+
63
+ end