cohitre-caculo 0.0.4

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.
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-04-16
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Carlos Rodriguez
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ lib/caculo.rb
6
+ lib/caculo/version.rb
7
+ lib/caculo/firefox.rb
8
+ lib/caculo/internet_explorer.rb
9
+ lib/caculo/javascript.rb
10
+ lib/caculo/jquery.rb
11
+ lib/caculo/safari.rb
12
+ lib/caculo/unit.rb
13
+ lib/caculo/version.rb
@@ -0,0 +1,72 @@
1
+ = caculo
2
+
3
+ * http://caculo.cohitre.com
4
+
5
+
6
+ == The Succinct Summary:
7
+
8
+ Caculo lets you simulate interaction with a browser via Ruby. It has the option to load a Javascript Library and call Javascript functions on the document. This allows for simple code that takes advantage of exisiting libraries.
9
+
10
+ Caculo is inspired by the Watir/FireWatir/SafariWatir trio, However, by simplifying the way of communicating with the browser it tries to offer an integrated cross-browser solution. It also extends the Test/Unit framework to provide some abbreviations to common functions.
11
+
12
+
13
+ == The Polite Apology
14
+
15
+ I haven't really tested Caculo outside of my computer, so things may not work as expected out of the box.
16
+
17
+ == The Descriptive Example:
18
+
19
+ browser = Caculo.open :safari
20
+ browser.libraries = [:jquery]
21
+
22
+ browser.visit( 'http://google.com' )
23
+
24
+ browser["input[@name='q']"].val! 'cohitre'
25
+ browser["form[@name='f']"].submit!
26
+
27
+ browser.wait
28
+ browser.load_libraries
29
+
30
+ browser.visit browser['#res .g:eq(1) h2.r a'].attr('href').execute
31
+
32
+
33
+ == The Required Requirements
34
+
35
+ For testing in Firefox you will need the JSSh plugin. After the plugin has been installed and turned on, you need to call firefox with:
36
+
37
+ $ firefox -jssh
38
+
39
+ For testing in Safari you will need rbosa. It is available through rubygems, so it should be enough to write:
40
+
41
+ $ sudo gem install rubyosa
42
+
43
+
44
+ == The Daunting Installation:
45
+
46
+ $ gem install caculo
47
+
48
+
49
+ == The Permissive License
50
+
51
+ (The MIT License)
52
+
53
+ Copyright (c) 2008 Carlos Rodriguez
54
+
55
+ Permission is hereby granted, free of charge, to any person obtaining
56
+ a copy of this software and associated documentation files (the
57
+ 'Software'), to deal in the Software without restriction, including
58
+ without limitation the rights to use, copy, modify, merge, publish,
59
+ distribute, sublicense, and/or sell copies of the Software, and to
60
+ permit persons to whom the Software is furnished to do so, subject to
61
+ the following conditions:
62
+
63
+ The above copyright notice and this permission notice shall be
64
+ included in all copies or substantial portions of the Software.
65
+
66
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
67
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
69
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
70
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
71
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
72
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,145 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+
5
+ require "#{File.dirname(__FILE__)}/caculo/jquery"
6
+ require "#{File.dirname(__FILE__)}/caculo/unit"
7
+ require "#{File.dirname(__FILE__)}/caculo/javascript"
8
+ require 'open-uri'
9
+
10
+ module Caculo
11
+ class Browser
12
+ attr_reader :libraries
13
+
14
+ # Creates a new browser window instance.
15
+ def self.open name
16
+ if ( name.to_s == 'firefox' )
17
+ require "#{File.dirname(__FILE__)}/caculo/firefox"
18
+ return Firefox.new
19
+ elsif ( name.to_s == 'safari')
20
+ require "#{File.dirname(__FILE__)}/caculo/safari"
21
+ return Safari.new
22
+ elsif ( name.to_s == 'explorer')
23
+ require "#{File.dirname(__FILE__)}/caculo/internet_explorer"
24
+ return InternetExplorer.new
25
+ end
26
+ end
27
+
28
+ def initialize
29
+ @libraries = []
30
+ self.use( "#{File.dirname(__FILE__)}/assets/jquery-1.2.3.min.js" )
31
+ end
32
+
33
+ def use library
34
+ @libraries.push( open( library ).read )
35
+ end
36
+
37
+ def << script
38
+ self.send_command( script )
39
+ end
40
+
41
+ def script cmd
42
+ c = %Q[
43
+ ( function() {
44
+ var doc = window.document;
45
+ var s = doc.createElement("script");
46
+ s.appendChild( doc.createTextNode( #{cmd.to_js} ) );
47
+ doc.body.appendChild( s );
48
+ } )()]
49
+ send_command( c )
50
+ end
51
+
52
+ def load_libraries!
53
+ @libraries.each { |l| self.script(l) }
54
+ end
55
+
56
+ def [] selector=nil
57
+ if selector.nil?
58
+ self << JQueryObject.new()
59
+ elsif selector.is_a? String
60
+ self << JQueryObject.new( selector )
61
+ elsif selector.is_a? JQueryObject
62
+ self << selector
63
+ end
64
+ end
65
+
66
+ def visit url
67
+ if ( url.is_a? JQueryObject )
68
+ url = self << url
69
+ end
70
+ self << "window.document.location.href = #{url.to_js}"
71
+
72
+ self.wait_until {|p| p.page_loaded? }
73
+ load_libraries!
74
+ url
75
+ end
76
+
77
+ def interval secs=0 , &block
78
+ if block_given?
79
+ block_result = yield self
80
+ self << "window.setInterval( function(){ #{block_result}} , #{secs*1000} );"
81
+ end
82
+ end
83
+
84
+ def timeout secs=0 , &block
85
+ if block_given?
86
+ block_result = yield self
87
+ self << "window.setTimeout( function(){ #{block_result}} , #{secs*1000} );"
88
+ end
89
+ end
90
+
91
+ def wait_until num=nil , &block
92
+ if num.nil? && block_given?
93
+ sleep 0.2
94
+ sleep 0.2 while( !yield self )
95
+ elsif num.nil? && block_given?
96
+ sleep num
97
+ sleep 0.2 while( !yield self )
98
+ elsif !num.nil?
99
+
100
+ end
101
+ end
102
+
103
+ def error message
104
+ jQuery("div#caculo-results ul").append( jQuery( "<li />" ).addClass("error").text( message ) )
105
+ end
106
+
107
+ def close
108
+ send_command( "window.close()")
109
+ end
110
+
111
+ def pathname
112
+ send_command( "window.location.pathname")
113
+ end
114
+
115
+ def back
116
+ send_command("window.history.back()")
117
+ end
118
+
119
+ def forward
120
+ send_command("window.history.forward()")
121
+ end
122
+
123
+ def close
124
+ send_command("window.close()")
125
+ end
126
+ end
127
+ end
128
+
129
+ class String
130
+ def to_js
131
+ "'" + escape_javascript( self ) + "'"
132
+ end
133
+ end
134
+
135
+ def escape_javascript(javascript)
136
+ (javascript || '').gsub('\\','\0\0').gsub('</','<\/').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
137
+ end
138
+
139
+ def jQuery selector=nil
140
+ return Caculo::JQueryObject.new( selector )
141
+ end
142
+
143
+ def js_function( body , params=[] )
144
+ return "function(#{params.join(' , ')}){ #{body} }"
145
+ end
@@ -0,0 +1,40 @@
1
+ require 'net/telnet'
2
+
3
+ module Caculo
4
+ class Firefox < Browser
5
+
6
+ def initialize
7
+ super
8
+ @telnet = Net::Telnet::new("Host" => "localhost","Port" => 9997,
9
+ "Prompt" => /[$%#>] /n)
10
+ 10.times { socket_send "\n" }
11
+ socket_send 'window = getWindows()[getWindows().length-1].getBrowser().contentWindow.window'
12
+ socket_send( "window.location = 'about:blank'" )
13
+ wait_until { page_loaded? }
14
+ end
15
+
16
+ def send_command cmd
17
+ socket_send( cmd )
18
+ end
19
+
20
+ def page_loaded?
21
+ result = socket_send( "#{browser}.webProgress.isLoadingDocument" )
22
+ return result =~ /false/
23
+ end
24
+
25
+ private
26
+
27
+ def browser
28
+ "getWindows()[getWindows().length-1].getBrowser()"
29
+ end
30
+
31
+ def window
32
+ browser+".contentWindow"
33
+ end
34
+
35
+ def socket_send cmd
36
+ @telnet.cmd( " " )
37
+ @telnet.cmd( cmd.to_s ).gsub( /\n> $/,"" )
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ require 'win32ole'
2
+
3
+ module Caculo
4
+ class InternetExplorer < Browser
5
+
6
+ def initialize
7
+ @ie = WIN32OLE.new('InternetExplorer.Application')
8
+ @ie.visible = true
9
+ end
10
+
11
+ def read
12
+ @ie.Document.parentWindow.caculoResult;
13
+ end
14
+
15
+ def send_command cmd
16
+ @ie.Document.parentWindow.execScript( "window.caculoResult = ''");
17
+ @ie.Document.parentWindow.execScript( "window.caculoResult = #{cmd};\n")
18
+ read
19
+ end
20
+
21
+ def location= url
22
+ sleep 0.2
23
+ @ie.navigate( url )
24
+ end
25
+
26
+ def location
27
+ @ie.locationURL
28
+ end
29
+
30
+ def page_loaded?
31
+ !@ie.Busy
32
+ end
33
+
34
+ def current_window
35
+ "window"
36
+ end
37
+
38
+ def back
39
+ @ie.goback
40
+ end
41
+
42
+ def forward
43
+ @ie.goforward
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,56 @@
1
+ module Caculo
2
+ class JavascriptObject
3
+ attr_accessor :javascript
4
+
5
+ def initialize connection , name
6
+ @connection = connection
7
+ @javascript = "#{connection.caculo_object}.#{name}"
8
+ end
9
+
10
+ def val name
11
+ obj = JavascriptObject.new( @connection , "" )
12
+ obj.javascript = "#{@javascript}.#{name}"
13
+ return obj
14
+ end
15
+
16
+ def val! name
17
+ obj = JavascriptObject.new( @connection , "" )
18
+ obj.javascript = "#{@javascript}.#{name}"
19
+ return obj.execute
20
+ end
21
+
22
+ def method_missing name , *params
23
+ obj = JavascriptObject.new( @connection , "" )
24
+
25
+ js_parameters = params.map do |p|
26
+ if p.kind_of? String
27
+ "'#{p}'"
28
+ else
29
+ p.to_s
30
+ end
31
+ end
32
+
33
+ obj.javascript = "#{@javascript}.#{name.to_s.gsub('!','').to_s}( #{js_parameters.join(',')} )"
34
+ if name.to_s.match('!')
35
+ return obj.execute
36
+ else
37
+ return obj
38
+ end
39
+ end
40
+
41
+ def length
42
+ obj = JavascriptObject.new( @connection , "" )
43
+ obj.javascript = "#{@javascript}.length"
44
+ return obj
45
+ end
46
+
47
+ def execute
48
+ return @connection.send_command( "#{@javascript};" )
49
+ end
50
+
51
+ def to_s
52
+ return @javascript
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,44 @@
1
+ module Caculo
2
+ class JQueryObject
3
+ attr_accessor :javascript
4
+
5
+ def self.method_missing name , *params
6
+ obj = JQueryObject.new("")
7
+ obj.javascript = "jQuery.#{name}(#{params.join(" , ").to_js} , function(content){ jQuery(document.body).append( content ); } )"
8
+ obj
9
+ end
10
+
11
+ def self.to_param obj
12
+ if obj.is_a? String
13
+ return obj.to_js
14
+ elsif obj.is_a? Array
15
+ return obj.collect{|o| self.to_param( o ) }.join(" , ")
16
+ else
17
+ return obj.to_s
18
+ end
19
+ end
20
+
21
+ def initialize selector=nil
22
+ if selector.nil?
23
+ @javascript = "window.jQuery(window.document)"
24
+ elsif selector.kind_of?( String )
25
+ @javascript = "window.jQuery(#{selector.to_js})"
26
+ else
27
+ @javascript = "window.jQuery(#{selector})"
28
+ end
29
+
30
+ def method_missing name , *params
31
+ obj = JQueryObject.new( "" )
32
+
33
+ js_parameters = JQueryObject.to_param( params )
34
+
35
+ obj.javascript = "#{@javascript}.#{name.to_s}( #{js_parameters} )"
36
+ return obj
37
+ end
38
+
39
+ def to_s
40
+ return @javascript
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rbosa'
3
+
4
+
5
+ module Caculo
6
+ class Safari < Browser
7
+
8
+ def page_loaded?
9
+ result = @application.do_javascript( 'document.readyState' , @window.document )
10
+ return result == "complete"
11
+ end
12
+
13
+ def initialize
14
+ super
15
+ @application = OSA.app('safari')
16
+ # puts @application
17
+ @application.make(OSA::Safari::Document)
18
+ @window = @application.windows[-1]
19
+
20
+ @application.do_javascript( 'window.location=\'about:config\'' , @window.document )
21
+ wait_until { page_loaded? }
22
+ end
23
+
24
+ def send_command( cmd )
25
+ @application.do_javascript( cmd , @window.document ).to_s
26
+ end
27
+
28
+ def location= url
29
+ @window.document.url = url
30
+ end
31
+
32
+ def location
33
+ @window.document.url
34
+ end
35
+
36
+ def current_window
37
+ "window"
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,55 @@
1
+ module Test
2
+ module Unit
3
+ class TestCase
4
+ def self.use_browsers *browsers
5
+ @@browsers = browsers
6
+ end
7
+
8
+ def browsers &block
9
+ for browser in @@browsers
10
+ @@browser = Caculo::Browser.open browser
11
+ @@browser.libraries = @@libraries
12
+ yield @@browser
13
+ @@browser.close
14
+ end
15
+ end
16
+
17
+ def self.use_libraries *libraries
18
+ @@libraries = libraries
19
+ end
20
+
21
+ def browser
22
+ return @@browser
23
+ end
24
+
25
+ def get name
26
+ browser.get name
27
+ end
28
+
29
+ def store name , object
30
+ browser.store name , object
31
+ end
32
+
33
+ def visit url
34
+ browser.visit url
35
+ end
36
+
37
+ def wait
38
+ browser.wait
39
+ end
40
+
41
+ def assert_location url
42
+ assert_equal url , browser.location
43
+ end
44
+
45
+ def back
46
+ browser.back
47
+ end
48
+
49
+ def forward
50
+ browser.forward
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,9 @@
1
+ module Caculo #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../lib/caculo'
2
+ require File.dirname(__FILE__) + '/../server/server'
3
+
4
+ include Caculo
5
+
6
+ start_server
7
+
8
+ page = Caculo::Browser.open(:safari)
9
+
10
+ page.visit( "http://localhost:3000".to_js )
11
+
12
+ page[ JQueryObject.get("_finished.html") ]
13
+
14
+ center_column = jQuery("<div />").attr("id", "center-column").css("margin" , "0 auto").width( 500 ).css("border" , "1px solid black").text("")
15
+ left_column = jQuery("<div />").attr("id" , "left-column").css("float","left").css("width" , 100 )
16
+
17
+ links_list = ["http://yahoo.com" , "http://cohitre.com" ].map { |url| jQuery("<li />").append( jQuery("<a />").attr("href", url ).text(url) ) }
18
+
19
+ page[ jQuery("body").append( left_column.text("left column") , center_column ) ]
20
+ page[ jQuery('#center-column').append( jQuery("<ul />").append( links_list ) ) ]
21
+ page[ jQuery("body").append( jQuery("<div />").attr('id','element').text("This is the caculo test sandbox") ) ]
22
+ page[jQuery("<div />").css( "position" , "absolute" ).css( "background-color" , "purple").appendTo( jQuery("body") ).text("dododo")]
23
+ page.timeout( 3 ) { jQuery("#element").text('Done') }
24
+
25
+ page.wait_until { page[jQuery("#element").text] == "Done" }
26
+
27
+ page << "(#{js_function( "window.alert( 'a' )" )})()"
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/caculo'
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cohitre-caculo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - carlos rodriguez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-20 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.0
23
+ version:
24
+ description: Caculo lets you simulate interaction with a browser via Ruby. It has the option to load a Javascript Library and call Javascript functions on the document. This allows for simple code that takes advantage of exisiting libraries.
25
+ email:
26
+ - carlosrr@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - History.txt
33
+ - License.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - License.txt
39
+ - Manifest.txt
40
+ - README.txt
41
+ - lib/caculo.rb
42
+ - lib/caculo/version.rb
43
+ - lib/caculo/firefox.rb
44
+ - lib/caculo/internet_explorer.rb
45
+ - lib/caculo/javascript.rb
46
+ - lib/caculo/jquery.rb
47
+ - lib/caculo/safari.rb
48
+ - lib/caculo/unit.rb
49
+ - test/test_caculo.rb
50
+ - test/test_helper.rb
51
+ has_rdoc: true
52
+ homepage: http://caculo.cohitre.com
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --main
56
+ - README.txt
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: caculo
74
+ rubygems_version: 1.2.0
75
+ signing_key:
76
+ specification_version: 2
77
+ summary: Caculo lets you simulate interaction with a browser via Ruby. It has the option to load a Javascript Library and call Javascript functions on the document. This allows for simple code that takes advantage of exisiting libraries.
78
+ test_files:
79
+ - test/test_caculo.rb
80
+ - test/test_helper.rb