steam 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/MIT-LICENSE +21 -0
  2. data/README.textile +91 -0
  3. data/Rakefile +23 -0
  4. data/TODO +7 -0
  5. data/lib/core_ext/ruby/array/flatten_once.rb +9 -0
  6. data/lib/core_ext/ruby/hash/except.rb +11 -0
  7. data/lib/core_ext/ruby/hash/slice.rb +14 -0
  8. data/lib/core_ext/ruby/kernel/silence_warnings.rb +8 -0
  9. data/lib/core_ext/ruby/process/daemon.rb +23 -0
  10. data/lib/core_ext/ruby/string/camelize.rb +5 -0
  11. data/lib/core_ext/ruby/string/underscore.rb +5 -0
  12. data/lib/steam.rb +43 -0
  13. data/lib/steam/browser.rb +24 -0
  14. data/lib/steam/browser/html_unit.rb +87 -0
  15. data/lib/steam/browser/html_unit/actions.rb +176 -0
  16. data/lib/steam/browser/html_unit/client.rb +74 -0
  17. data/lib/steam/browser/html_unit/connection.rb +79 -0
  18. data/lib/steam/browser/html_unit/drb.rb +45 -0
  19. data/lib/steam/browser/html_unit/matchers.rb +57 -0
  20. data/lib/steam/browser/html_unit/page.rb +51 -0
  21. data/lib/steam/browser/html_unit/web_response.rb +116 -0
  22. data/lib/steam/connection.rb +9 -0
  23. data/lib/steam/connection/mock.rb +57 -0
  24. data/lib/steam/connection/net_http.rb +42 -0
  25. data/lib/steam/connection/open_uri.rb +24 -0
  26. data/lib/steam/connection/rails.rb +20 -0
  27. data/lib/steam/connection/static.rb +33 -0
  28. data/lib/steam/java.rb +74 -0
  29. data/lib/steam/process.rb +53 -0
  30. data/lib/steam/request.rb +49 -0
  31. data/lib/steam/response.rb +13 -0
  32. data/lib/steam/session.rb +30 -0
  33. data/lib/steam/session/rails.rb +33 -0
  34. data/lib/steam/version.rb +3 -0
  35. data/test/all.rb +3 -0
  36. data/test/browser/html_unit/actions_test.rb +183 -0
  37. data/test/browser/html_unit/javascript_test.rb +60 -0
  38. data/test/browser/html_unit/rails_actions_test.rb +151 -0
  39. data/test/browser/html_unit_test.rb +97 -0
  40. data/test/connection/cascade_test.rb +42 -0
  41. data/test/connection/mock_test.rb +58 -0
  42. data/test/connection/rails_test.rb +16 -0
  43. data/test/connection/static_test.rb +14 -0
  44. data/test/fixtures/html_fakes.rb +191 -0
  45. data/test/java_test.rb +29 -0
  46. data/test/playground/connection.rb +19 -0
  47. data/test/playground/dragdrop_behavior.rb +60 -0
  48. data/test/playground/drb.rb +55 -0
  49. data/test/playground/java_signature.rb +22 -0
  50. data/test/playground/nokogiri.rb +15 -0
  51. data/test/playground/put_headers.rb +83 -0
  52. data/test/playground/rack.rb +11 -0
  53. data/test/playground/rjb_bind.rb +42 -0
  54. data/test/playground/stack_level_problem.rb +129 -0
  55. data/test/playground/thread_problem.rb +57 -0
  56. data/test/playground/web_response_data.rb +21 -0
  57. data/test/playground/webrat.rb +48 -0
  58. data/test/playground/xhr_accept_headers.rb +61 -0
  59. data/test/process_test.rb +55 -0
  60. data/test/session_test.rb +15 -0
  61. data/test/test_helper.rb +56 -0
  62. metadata +135 -0
@@ -0,0 +1,60 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+ require 'fixtures/html_fakes'
3
+
4
+ class HtmlUnitJavascriptTest < Test::Unit::TestCase
5
+ include Steam, HtmlFakes
6
+
7
+ def setup
8
+ @app = Steam::Connection::Mock.new
9
+ static = Steam::Connection::Static.new(:root => FIXTURES_PATH)
10
+ @browser = Steam::Browser::HtmlUnit.new(Rack::Cascade.new([static, @app]))
11
+ end
12
+
13
+ test "jquery: div:not([id]) selector" do
14
+ html = <<-html
15
+ <html>
16
+ <head>
17
+ <script src="/javascripts/jquery.js" type="text/javascript"></script>
18
+ <script>
19
+ $(document).ready(function() {
20
+ $('div:not([id])').each(function() {
21
+ document.title = $(this).html();
22
+ });
23
+ });
24
+ </script>
25
+ </head>
26
+ <body>
27
+ <div id="foo">foo</div>
28
+ <div>bar</div>
29
+ </body>
30
+ </html>
31
+ html
32
+
33
+ perform(:get, 'http://localhost:3000/', html)
34
+ assert_equal 'bar', @browser.page.getTitleText
35
+ end
36
+
37
+ test "jquery: div[id*=bar] selector" do
38
+ html = <<-html
39
+ <html>
40
+ <head>
41
+ <script src="/javascripts/jquery.js" type="text/javascript"></script>
42
+ <script>
43
+ $(document).ready(function() {
44
+ $('div[id*=bar]').each(function() {
45
+ document.title = $(this).html();
46
+ });
47
+ });
48
+ </script>
49
+ </head>
50
+ <body>
51
+ <div id="sidebar">foobar</div>
52
+ </body>
53
+ </html>
54
+ html
55
+
56
+ perform(:get, 'http://localhost:3000/', html)
57
+ assert_equal 'foobar', @browser.page.getTitleText
58
+ end
59
+
60
+ end
@@ -0,0 +1,151 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+ require 'fixtures/html_fakes'
3
+
4
+ class HtmlUnitRailsActionsTest < Test::Unit::TestCase
5
+ include Steam, HtmlFakes
6
+
7
+ def setup
8
+ @app = Steam::Connection::Mock.new
9
+ static = Steam::Connection::Static.new(:root => FIXTURES_PATH)
10
+ @browser = Steam::Browser::HtmlUnit.new(Rack::Cascade.new([static, @app]))
11
+
12
+ @app.mock :get, "http://localhost:3000/form?event_date(1i)=2009&event_date(2i)=11&event_date(3i)=7", 'DATE'
13
+ @app.mock :get, "http://localhost:3000/form?event_datetime(1i)=2009&event_datetime(2i)=11&event_datetime(3i)=7&event_datetime(4i)=19&event_datetime(5i)=0", 'DATETIME'
14
+ @app.mock :get, "http://localhost:3000/form?event_time(4i)=19&event_time(5i)=0", 'TIME'
15
+ end
16
+
17
+ def test_select_date
18
+ perform :get, 'http://localhost:3000/', html(:fields => :date)
19
+
20
+ assert_response_contains('DATE') do
21
+ @browser.select_date('7 November 2009', :from => 'event_date')
22
+ @browser.submit_form('form')
23
+ end
24
+ end
25
+
26
+ def test_select_date_works_with_date_object
27
+ perform :get, 'http://localhost:3000/', html(:fields => :date)
28
+
29
+ assert_response_contains('DATE') do
30
+ @browser.select_date(Date.parse('7 November 2009'), :from => 'event_date')
31
+ @browser.submit_form('form')
32
+ end
33
+ end
34
+
35
+ def test_select_date_works_with_label
36
+ perform :get, 'http://localhost:3000/', html(:fields => :date)
37
+
38
+ assert_response_contains('DATE') do
39
+ @browser.select_date('7 November 2009', :from => 'Date')
40
+ @browser.submit_form('form')
41
+ end
42
+ end
43
+
44
+ def test_select_date_works_without_from_option
45
+ perform :get, 'http://localhost:3000/', html(:fields => :date)
46
+
47
+ assert_response_contains('DATE') do
48
+ @browser.select_date('7 November 2009')
49
+ @browser.submit_form('form')
50
+ end
51
+ end
52
+
53
+ def test_select_date_works_with_id_prefix_option
54
+ perform :get, 'http://localhost:3000/', html(:fields => :date)
55
+
56
+ assert_response_contains('DATE') do
57
+ @browser.select_date('7 November 2009', :id_prefix => 'event_date')
58
+ @browser.submit_form('form')
59
+ end
60
+ end
61
+
62
+ def test_select_datetime
63
+ perform :get, 'http://localhost:3000/', html(:fields => :datetime)
64
+
65
+ assert_response_contains('DATETIME') do
66
+ @browser.select_datetime('7 November 2009, 19:00', :from => 'event_datetime')
67
+ @browser.submit_form('form')
68
+ end
69
+ end
70
+
71
+ def test_select_datetime_works_with_datetime_object
72
+ perform :get, 'http://localhost:3000/', html(:fields => :datetime)
73
+
74
+ assert_response_contains('DATETIME') do
75
+ @browser.select_datetime(Time.parse('7 November 2009, 19:00'), :from => 'event_datetime')
76
+ @browser.submit_form('form')
77
+ end
78
+ end
79
+
80
+ def test_select_datetime_works_with_label
81
+ perform :get, 'http://localhost:3000/', html(:fields => :datetime)
82
+
83
+ assert_response_contains('DATETIME') do
84
+ @browser.select_datetime('7 November 2009, 19:00', :from => 'Datetime')
85
+ @browser.submit_form('form')
86
+ end
87
+ end
88
+
89
+ def test_select_datetime_works_without_from_option
90
+ perform :get, 'http://localhost:3000/', html(:fields => :datetime)
91
+
92
+ assert_response_contains('DATETIME') do
93
+ @browser.select_datetime('7 November 2009, 19:00')
94
+ @browser.submit_form('form')
95
+ end
96
+ end
97
+
98
+ def test_select_datetime_works_with_id_prefix_option
99
+ perform :get, 'http://localhost:3000/', html(:fields => :datetime)
100
+
101
+ assert_response_contains('DATETIME') do
102
+ @browser.select_datetime('7 November 2009, 19:00', :id_prefix => 'event_datetime')
103
+ @browser.submit_form('form')
104
+ end
105
+ end
106
+
107
+ def test_select_time
108
+ perform :get, 'http://localhost:3000/', html(:fields => :time)
109
+
110
+ assert_response_contains('TIME') do
111
+ @browser.select_time('19:00', :from => 'event_time')
112
+ @browser.submit_form('form')
113
+ end
114
+ end
115
+
116
+ def test_select_time_works_with_time_object
117
+ perform :get, 'http://localhost:3000/', html(:fields => :time)
118
+
119
+ assert_response_contains('TIME') do
120
+ @browser.select_time(Time.parse('19:00'), :from => 'event_time')
121
+ @browser.submit_form('form')
122
+ end
123
+ end
124
+
125
+ def test_select_time_works_with_label
126
+ perform :get, 'http://localhost:3000/', html(:fields => :time)
127
+
128
+ assert_response_contains('TIME') do
129
+ @browser.select_time('19:00', :from => 'Time')
130
+ @browser.submit_form('form')
131
+ end
132
+ end
133
+
134
+ def test_select_time_works_without_from_option
135
+ perform :get, 'http://localhost:3000/', html(:fields => :time)
136
+
137
+ assert_response_contains('TIME') do
138
+ @browser.select_time('19:00')
139
+ @browser.submit_form('form')
140
+ end
141
+ end
142
+
143
+ def test_select_time_works_with_id_prefix_option
144
+ perform :get, 'http://localhost:3000/', html(:fields => :time)
145
+
146
+ assert_response_contains('TIME') do
147
+ @browser.select_time('19:00', :id_prefix => 'event_time')
148
+ @browser.submit_form('form')
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,97 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+ require 'fixtures/html_fakes'
3
+ require 'locator'
4
+
5
+ module HtmlUnitTests
6
+ def init
7
+ @app = Steam::Connection::Mock.new
8
+ static = Steam::Connection::Static.new(:root => FIXTURES_PATH)
9
+ @browser = Steam::Browser::HtmlUnit.new(Rack::Cascade.new([static, @app]))
10
+ perform(:get, 'http://localhost:3000/', '<div id="foo"><div id="bar"><a id="buz" href="">bar!</a></div></div>')
11
+ end
12
+
13
+ def locate(*args, &block)
14
+ @browser.locate(*args, &block)
15
+ end
16
+
17
+ def within(*args, &block)
18
+ @browser.within(*args, &block)
19
+ end
20
+
21
+ test 'locate with node type' do
22
+ element = locate(:a)
23
+ assert_equal 'a', element.name
24
+ end
25
+
26
+ test 'locate with attributes' do
27
+ element = locate(:id => 'buz')
28
+ assert_equal 'a', element.name
29
+ end
30
+
31
+ test 'locate with search text' do
32
+ element = locate(:a, 'bar!')
33
+ assert_equal 'a', element.name
34
+ end
35
+
36
+ test 'locate with xpath' do
37
+ element = locate(:xpath => '//div/div/a')
38
+ assert_equal 'a', element.name
39
+ end
40
+
41
+ test 'locate with css' do
42
+ element = locate(:css => '#foo #bar a')
43
+ assert_equal 'a', element.name
44
+ end
45
+
46
+ test 'within with node type' do
47
+ element = within(:div) { within(:div) { locate(:a) } }
48
+ assert_equal 'a', element.name
49
+ end
50
+
51
+ test 'within with attributes' do
52
+ element = within(:id => 'foo') { within(:id => 'bar') { locate(:a) } }
53
+ assert_equal 'a', element.name
54
+ end
55
+
56
+ test 'within with xpath' do
57
+ element = within('//div/div') { locate(:a) }
58
+ assert_equal 'a', element.name
59
+ end
60
+
61
+ test 'within with css' do
62
+ element = within('#foo #bar') { locate(:a) }
63
+ assert_equal 'a', element.name
64
+ end
65
+
66
+ test 'nesting locate' do
67
+ element = locate(:id => 'foo') { locate(:id => 'bar') { locate(:a) } }
68
+ assert_equal 'a', element.name
69
+ end
70
+
71
+ test 'nesting within' do
72
+ element = within(:id => 'foo') { within(:id => 'bar') { locate(:a) } }
73
+ assert_equal 'a', element.name
74
+ end
75
+ end
76
+
77
+ class HtmlUnitWithNokogiriAdapterTest < Test::Unit::TestCase
78
+ include Steam, HtmlUnitTests
79
+
80
+ def setup
81
+ init
82
+ end
83
+ end
84
+
85
+ class HtmlUnitWithHtmlUnitAdapterTest < Test::Unit::TestCase
86
+ include Steam, HtmlUnitTests
87
+
88
+ def setup
89
+ @old_adapter, Locator::Dom.adapter = Locator::Dom.adapter, Locator::Dom::Htmlunit
90
+ init
91
+ end
92
+
93
+ def teardown
94
+ Locator::Dom.adapter = @old_adapter
95
+ end
96
+ end
97
+
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+ require 'rack/cascade'
3
+
4
+ class ConnectionCascadeTest < Test::Unit::TestCase
5
+ include Steam
6
+
7
+ def setup
8
+ connections = []
9
+ @urls = []
10
+ @bodies = []
11
+
12
+ @root = File.expand_path(File.dirname(__FILE__) + '/../fixtures')
13
+ connections << Connection::Static.new(:root => @root)
14
+ @urls << 'http://localhost:3000/javascripts/foo.js'
15
+ @bodies << File.read(@root + '/javascripts/foo.js')
16
+
17
+ @mock_url = 'http://localhost:3000/mock'
18
+ mock = Connection::Mock.new
19
+ mock.mock :get, @mock_url, 'mock body'
20
+ connections << mock
21
+ @urls << @mock_url
22
+ @bodies << 'mock body'
23
+
24
+ if Gem.available?('patron')
25
+ patron = Connection::Patron.new
26
+ patron_body = 'patron body'
27
+ patron.stubs(:handle_request).returns(patron_response(patron_body)) # FIXME .with(...)
28
+ connections << patron
29
+ @urls << 'http://localhost:3000/patron'
30
+ @bodies << patron_body
31
+ end
32
+
33
+ @connection = Rack::Cascade.new(connections)
34
+ end
35
+
36
+ def test_cascade
37
+ @urls.each_with_index do |url, index|
38
+ status, headers, response = @connection.call(Request.env_for(url))
39
+ assert_equal @bodies[index], response.body.join
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class ConnectionMockTest < Test::Unit::TestCase
4
+ include Steam
5
+
6
+ def setup
7
+ @connection = Connection::Mock.new
8
+ @url = 'http://localhost:3000/'
9
+ @body = <<-body
10
+ <html>
11
+ <head>
12
+ <script src="/javascripts/script.js" type="text/javascript"></script>
13
+ </head>
14
+ </html>
15
+ body
16
+ end
17
+
18
+ def test_call
19
+ @connection.mock(:get, @url, @body)
20
+ status, headers, response = @connection.call(Request.env_for(@url))
21
+ assert_equal [@body], response.body
22
+ end
23
+
24
+ def test_mock_with_response
25
+ @connection.mock(:get, @url, Rack::Response.new(@body, 200, { 'Content-Type' => 'text/css' }))
26
+ assert_response('Content-Type' => 'text/css')
27
+ end
28
+
29
+ def test_mock_with_string
30
+ @connection.mock(:get, @url, @body)
31
+ assert_response
32
+ end
33
+
34
+ def test_mock_with_array_without_content_type
35
+ @connection.mock(:get, @url, [@body, 201, { 'foo' => 'bar' }])
36
+ assert_response(201, 'foo' => 'bar')
37
+ end
38
+
39
+ def test_mock_with_array_with_content_type
40
+ @connection.mock(:get, @url, [@body, 201, { 'Content-Type' => 'text/css' }])
41
+ assert_response(201, 'Content-Type' => 'text/css')
42
+ end
43
+
44
+ protected
45
+
46
+ def assert_response(*args)
47
+ headers = args.last.is_a?(Hash) ? args.pop : {}
48
+ headers = { 'Content-Type' => 'text/html' }.merge(headers)
49
+ status = args.pop || 200
50
+
51
+ response = @connection.response('GET', @url)
52
+
53
+ assert response.is_a?(Rack::Response)
54
+ assert_equal [@body], response.body
55
+ assert_equal status, response.status
56
+ assert_equal headers['Content-Type'], response.header['Content-Type']
57
+ end
58
+ end
@@ -0,0 +1,16 @@
1
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+ #
3
+ # class ConnectionRailsTest < Test::Unit::TestCase
4
+ # include Steam
5
+ #
6
+ # def test_rails
7
+ # rails_root = File.expand_path(File.dirname(__FILE__) + '/../fixtures/rails')
8
+ # require rails_root + '/config/environment.rb'
9
+ #
10
+ # url = 'http://localhost:3000/users'
11
+ # connection = Connection::Rails.new
12
+ #
13
+ # status, headers, response = connection.call(Request.env_for(url))
14
+ # # assert !response.body.empty?
15
+ # end
16
+ # end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class ConnectionStaticTest < Test::Unit::TestCase
4
+ include Steam
5
+
6
+ def test_static
7
+ url = 'http://localhost:3000/javascripts/foo.js'
8
+ root = File.expand_path(File.dirname(__FILE__) + '/../fixtures')
9
+ connection = Connection::Static.new(:root => root)
10
+
11
+ status, headers, response = connection.call(Request.env_for(url))
12
+ assert_equal File.read(root + '/javascripts/foo.js'), response.body.join
13
+ end
14
+ end
@@ -0,0 +1,191 @@
1
+ module HtmlFakes
2
+ def html(options = {})
3
+ fields = Array(options[:fields]).map { |field| self.send(field) }
4
+ scripts = Array(options[:scripts]).map { |script| self.send(script) }
5
+ ERB.new(layout).result(binding)
6
+ end
7
+
8
+ def text
9
+ <<-html
10
+ <label for="field">Label for field</label>
11
+ <input type="text" id="field" name="field" />
12
+ html
13
+ end
14
+
15
+ def textarea
16
+ <<-html
17
+ <label for="textarea">Label for textarea</label>
18
+ <textarea id="textarea" name="textarea"></textarea>
19
+ html
20
+ end
21
+
22
+ def checkbox
23
+ <<-html
24
+ <label for="checkbox">Label for checkbox</label>
25
+ <input id="checkbox" type="checkbox" name="checkbox" value="1" />
26
+ html
27
+ end
28
+
29
+ def radio
30
+ <<-html
31
+ <label for="radio1">Label for radio</label>
32
+ <input id="radio1" type="radio" name="radio" value="radio" />
33
+ <label for="radio2">Label for tv</label>
34
+ <input id="radio2" type="radio" name="radio" value="tv" />
35
+ html
36
+ end
37
+
38
+ def select
39
+ <<-html
40
+ <label for="select">Label for select</label>
41
+ <select id="select" name="select">
42
+ <option value=""></option>
43
+ <option value="foo">foo</option>
44
+ </select>
45
+ html
46
+ end
47
+
48
+ def hidden
49
+ <<-html
50
+ <input id="hidden" type="hidden" name="hidden" value="bar" />
51
+ html
52
+ end
53
+
54
+ def file
55
+ <<-html
56
+ <label for="file">Label for file</label><input id="file" type="file" name="file" />
57
+ html
58
+ end
59
+
60
+ def date
61
+ <<-html
62
+ <label for="event_date">Date</label>
63
+ <select id="event_date_1i" name="event_date(1i)">
64
+ <option value="2008">2008</option>
65
+ <option value="2009">2009</option>
66
+ <option value="2010">2010</option>
67
+ </select>
68
+ <select id="event_date_2i" name="event_date(2i)">
69
+ <option value="10">October</option>
70
+ <option value="11">November</option>
71
+ <option value="12">December</option>
72
+ </select>
73
+ <select id="event_date_3i" name="event_date(3i)">
74
+ <option value="6">6</option>
75
+ <option value="7">7</option>
76
+ <option value="8">8</option>
77
+ </select>
78
+ html
79
+ end
80
+
81
+ def datetime
82
+ <<-html
83
+ <label for="event_datetime">Datetime</label>
84
+ <select id="event_datetime_1i" name="event_datetime(1i)">
85
+ <option value="2008">2008</option>
86
+ <option value="2009">2009</option>
87
+ <option value="2010">2010</option>
88
+ </select>
89
+ <select id="event_datetime_2i" name="event_datetime(2i)">
90
+ <option value="10">October</option>
91
+ <option value="11">November</option>
92
+ <option value="12">December</option>
93
+ </select>
94
+ <select id="event_datetime_3i" name="event_datetime(3i)">
95
+ <option value="6">6</option>
96
+ <option value="7">7</option>
97
+ <option value="8">8</option>
98
+ </select> :
99
+ <select id="event_datetime_4i" name="event_datetime(4i)">
100
+ <option value="18">18</option>
101
+ <option value="19">19</option>
102
+ <option value="20">20</option>
103
+ </select>
104
+ <select id="event_datetime_5i" name="event_datetime(5i)">
105
+ <option value="0">00</option>
106
+ <option value="1">01</option>
107
+ <option value="2">02</option>
108
+ </select>
109
+ html
110
+ end
111
+
112
+ def time
113
+ <<-html
114
+ <label for="event_time">Time</label>
115
+ <select id="event_time_4i" name="event_time(4i)">
116
+ <option value="18">18</option>
117
+ <option value="19">19</option>
118
+ <option value="20">20</option>
119
+ </select>
120
+ <select id="event_time_5i" name="event_time(5i)">
121
+ <option value="0">00</option>
122
+ <option value="1">01</option>
123
+ <option value="2">02</option>
124
+ </select>
125
+ html
126
+ end
127
+
128
+ def jquery
129
+ <<-html
130
+ <script src="/javascripts/jquery.js" type="text/javascript"></script>
131
+ html
132
+ end
133
+
134
+ def jquery_ui
135
+ <<-html
136
+ <script src="/javascripts/jquery-ui.js" type="text/javascript"></script>
137
+ html
138
+ end
139
+
140
+ def foo
141
+ <<-html
142
+ <script src="/javascripts/foo.js" type="text/javascript"></script>
143
+ html
144
+ end
145
+
146
+ def hover
147
+ <<-html
148
+ <script src="/javascripts/hover.js" type="text/javascript"></script>
149
+ html
150
+ end
151
+
152
+ def blur
153
+ <<-html
154
+ <script src="/javascripts/blur.js" type="text/javascript"></script>
155
+ html
156
+ end
157
+
158
+ def focus
159
+ <<-html
160
+ <script src="/javascripts/focus.js" type="text/javascript"></script>
161
+ html
162
+ end
163
+
164
+ def double_click
165
+ <<-html
166
+ <script src="/javascripts/double_click.js" type="text/javascript"></script>
167
+ html
168
+ end
169
+
170
+ def drag
171
+ <<-html
172
+ <script src="/javascripts/drag.js" type="text/javascript"></script>
173
+ html
174
+ end
175
+
176
+ def layout
177
+ <<-erb
178
+ <html>
179
+ <head><%= scripts %></head>
180
+ <body>
181
+ <p id="paragraph"></p>
182
+ <p><a href="/link" id="link">link</a></p>
183
+ <form action="/form" method="get" id="form" enctype="multipart/form-data">
184
+ <%= fields %>
185
+ <input type="submit" value="button" />
186
+ </form>
187
+ </body>
188
+ </html>
189
+ erb
190
+ end
191
+ end