cohitre-caculo 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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