capybara 0.1.4 → 0.2.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.
@@ -1,7 +1,7 @@
1
1
  require 'nokogiri'
2
2
 
3
3
  module Capybara
4
- VERSION = '0.1.4'
4
+ VERSION = '0.2.0'
5
5
 
6
6
  class CapybaraError < StandardError; end
7
7
  class DriverNotFoundError < CapybaraError; end
@@ -55,7 +55,6 @@ class Capybara::Driver::Culerity < Capybara::Driver::Base
55
55
  def initialize(app)
56
56
  @app = app
57
57
  @rack_server = Capybara::Server.new(@app)
58
- @rack_server.boot
59
58
  end
60
59
 
61
60
  def visit(path)
@@ -66,7 +66,6 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
66
66
  def initialize(app)
67
67
  @app = app
68
68
  @rack_server = Capybara::Server.new(@app)
69
- @rack_server.boot
70
69
  end
71
70
 
72
71
  def visit(path)
@@ -50,7 +50,7 @@ module Capybara
50
50
  :visit, :body, :click_link, :click_button, :drag, :fill_in, :choose, :has_xpath?, :has_css?,
51
51
  :check, :uncheck, :attach_file, :select, :has_content?, :within, :within_fieldset,
52
52
  :within_table, :save_and_open_page, :find, :find_field, :find_link, :find_button,
53
- :field_labeled, :all, :wait_for, :evaluate_script
53
+ :field_labeled, :all, :wait_for, :evaluate_script, :click
54
54
  ]
55
55
  SESSION_METHODS.each do |method|
56
56
  class_eval <<-RUBY, __FILE__, __LINE__+1
@@ -4,14 +4,27 @@ require 'rack'
4
4
  require 'rack/handler/mongrel'
5
5
 
6
6
  class Capybara::Server
7
- attr_reader :app
8
-
7
+ class Identify
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ if env["REQUEST_PATH"] == "/__identify__"
14
+ [200, {}, @app.object_id.to_s]
15
+ else
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ attr_reader :app, :port
23
+
9
24
  def initialize(app)
10
25
  @app = app
11
- end
12
-
13
- def port
14
- 8080
26
+ find_available_port
27
+ boot
15
28
  end
16
29
 
17
30
  def host
@@ -22,34 +35,59 @@ class Capybara::Server
22
35
  path = URI.parse(path).request_uri if path =~ /^http/
23
36
  "http://#{host}:#{port}#{path}"
24
37
  end
25
-
38
+
39
+ def responsive?
40
+ is_running_on_port?(port)
41
+ end
42
+
43
+ private
44
+
26
45
  def boot
27
46
  Capybara.log "application has already booted" and return if responsive?
28
47
  Capybara.log "booting Rack applicartion on port #{port}"
29
- start_time = Time.now
30
- Thread.new do
31
- Rack::Handler::Mongrel.run @app, :Port => port
32
- end
33
- Capybara.log "checking if application has booted"
34
- loop do
35
- Capybara.log("application has booted") and break if responsive?
36
- if Time.now - start_time > 10
37
- Capybara.log "Rack application timed out during boot"
38
- exit
48
+
49
+ Timeout.timeout(10) do
50
+ Thread.new do
51
+ Rack::Handler::Mongrel.run Identify.new(@app), :Port => port
52
+ end
53
+ Capybara.log "checking if application has booted"
54
+
55
+ loop do
56
+ Capybara.log("application has booted") and break if responsive?
57
+ sleep 0.5
39
58
  end
40
-
41
- Capybara.log '.'
42
- sleep 1
43
59
  end
60
+ rescue Timeout::Error
61
+ Capybara.log "Rack application timed out during boot"
62
+ exit
44
63
  end
45
64
 
46
- def responsive?
47
- res = Net::HTTP.start(host, port) { |http| http.get('/') }
65
+ def find_available_port
66
+ @port = 9887
67
+ @port += 1 while is_port_open?(@port) and not is_running_on_port?(@port)
68
+ end
69
+
70
+ def is_running_on_port?(tested_port)
71
+ res = Net::HTTP.start(host, tested_port) { |http| http.get('/__identify__') }
48
72
 
49
73
  if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
50
- return true
74
+ return res.body == @app.object_id.to_s
75
+ end
76
+ rescue Errno::ECONNREFUSED
77
+ return false
78
+ end
79
+
80
+ def is_port_open?(tested_port)
81
+ Timeout::timeout(1) do
82
+ begin
83
+ s = TCPSocket.new(host, tested_port)
84
+ s.close
85
+ return true
86
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
87
+ return false
88
+ end
51
89
  end
52
- rescue Errno::ECONNREFUSED
90
+ rescue Timeout::Error
53
91
  return false
54
92
  end
55
93
 
@@ -25,6 +25,12 @@ module Capybara
25
25
  driver.visit(path)
26
26
  end
27
27
 
28
+ def click(locator)
29
+ link = wait_for(XPath.link(locator).button(locator))
30
+ raise Capybara::ElementNotFound, "no link or button '#{locator}' found" unless link
31
+ link.click
32
+ end
33
+
28
34
  def click_link(locator)
29
35
  link = wait_for(XPath.link(locator))
30
36
  raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
@@ -91,6 +91,14 @@ module Capybara
91
91
  def to_s
92
92
  @paths.join(' | ')
93
93
  end
94
+
95
+ def append(path)
96
+ XPath.new(*[@paths, XPath.wrap(path).paths].flatten)
97
+ end
98
+
99
+ def prepend(path)
100
+ XPath.new(*[XPath.wrap(path).paths, @paths].flatten)
101
+ end
94
102
 
95
103
  protected
96
104
 
@@ -111,14 +119,6 @@ module Capybara
111
119
  "'#{string}'"
112
120
  end
113
121
  end
114
-
115
- def prepend(path)
116
- XPath.new(*[path, @paths].flatten)
117
- end
118
-
119
- def append(path)
120
- XPath.new(*[@paths, path].flatten)
121
- end
122
122
 
123
123
  end
124
124
  end
@@ -21,6 +21,29 @@ shared_examples_for "session" do
21
21
  @session.body.should include('Another World')
22
22
  end
23
23
  end
24
+
25
+ describe '#click' do
26
+ it "should click on a link" do
27
+ @session.visit('/with_html')
28
+ @session.click('labore')
29
+ @session.body.should include('<h1>Bar</h1>')
30
+ end
31
+
32
+ it "should click on a button" do
33
+ @session.visit('/form')
34
+ @session.click('awe123')
35
+ extract_results(@session)['first_name'].should == 'John'
36
+ end
37
+
38
+ context "with a locator that doesn't exist" do
39
+ it "should raise an error" do
40
+ @session.visit('/with_html')
41
+ running do
42
+ @session.click('does not exist')
43
+ end.should raise_error(Capybara::ElementNotFound)
44
+ end
45
+ end
46
+ end
24
47
 
25
48
  describe '#click_link' do
26
49
  before do
@@ -538,6 +561,7 @@ shared_examples_for "session" do
538
561
 
539
562
  it "should not break if no file is submitted" do
540
563
  @session.click_button('Upload')
564
+ @session.body.should include('No file uploaded')
541
565
  end
542
566
  end
543
567
 
@@ -871,6 +895,14 @@ shared_examples_for "session with javascript support" do
871
895
  end
872
896
  end
873
897
 
898
+ describe '#click' do
899
+ it "should wait for asynchronous load" do
900
+ @session.visit('/with_js')
901
+ @session.click_link('Click me')
902
+ @session.click('Has been clicked')
903
+ end
904
+ end
905
+
874
906
  describe '#click_link' do
875
907
  it "should wait for asynchronous load" do
876
908
  @session.visit('/with_js')
@@ -50,7 +50,7 @@ class TestApp < Sinatra::Base
50
50
  end
51
51
 
52
52
  post '/upload' do
53
- params[:form][:document][:tempfile].read rescue ''
53
+ params[:form][:document][:tempfile].read rescue 'No file uploaded'
54
54
  end
55
55
  end
56
56
 
@@ -29,6 +29,34 @@ describe Capybara::XPath do
29
29
  end
30
30
  end
31
31
 
32
+ describe '#append' do
33
+ it "should append an XPath's paths" do
34
+ @xpath = Capybara::XPath.wrap('//test')
35
+ @xpath = @xpath.append(Capybara::XPath.wrap('//foo/bar'))
36
+ @xpath.paths.should == ['//test', '//foo/bar']
37
+ end
38
+
39
+ it "should append an String as a new path" do
40
+ @xpath = Capybara::XPath.wrap('//test')
41
+ @xpath = @xpath.append('//foo/bar')
42
+ @xpath.paths.should == ['//test', '//foo/bar']
43
+ end
44
+ end
45
+
46
+ describe '#prepend' do
47
+ it "should prepend an XPath's paths" do
48
+ @xpath = Capybara::XPath.wrap('//test')
49
+ @xpath = @xpath.prepend(Capybara::XPath.wrap('//foo/bar'))
50
+ @xpath.paths.should == ['//foo/bar', '//test']
51
+ end
52
+
53
+ it "should prepend an String as a new path" do
54
+ @xpath = Capybara::XPath.wrap('//test')
55
+ @xpath = @xpath.prepend('//foo/bar')
56
+ @xpath.paths.should == ['//foo/bar', '//test']
57
+ end
58
+ end
59
+
32
60
  describe '#scope' do
33
61
  it "should prepend the given scope to all paths" do
34
62
  @xpath = Capybara::XPath.new('//foo/bar', '//test[@blah=foo]').scope('//quox')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-12 00:00:00 +01:00
12
+ date: 2009-12-13 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency