lackie 0.1.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.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem 'bundler', '~> 1.0.7'
5
+ end
6
+
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,57 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lackie (0.1.0)
5
+ rack (~> 1.2.1)
6
+ rest-client (~> 1.4.2)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ builder (2.1.2)
12
+ cgi_multipart_eof_fix (2.5.0)
13
+ cucumber (0.10.0)
14
+ builder (>= 2.1.2)
15
+ diff-lcs (~> 1.1.2)
16
+ gherkin (~> 2.3.2)
17
+ json (~> 1.4.6)
18
+ term-ansicolor (~> 1.0.5)
19
+ daemons (1.0.10)
20
+ diff-lcs (1.1.2)
21
+ fastthread (1.0.1)
22
+ gem_plugin (0.2.3)
23
+ gherkin (2.3.3)
24
+ json (~> 1.4.6)
25
+ json (1.4.6)
26
+ mime-types (1.16)
27
+ mongrel (1.1.5)
28
+ cgi_multipart_eof_fix (>= 2.4)
29
+ daemons (>= 1.0.3)
30
+ fastthread (>= 1.0.1)
31
+ gem_plugin (>= 0.2.3)
32
+ rack (1.2.1)
33
+ relevance-rcov (0.9.2.1)
34
+ rest-client (1.4.2)
35
+ mime-types (>= 1.16)
36
+ rspec (2.2.0)
37
+ rspec-core (~> 2.2)
38
+ rspec-expectations (~> 2.2)
39
+ rspec-mocks (~> 2.2)
40
+ rspec-core (2.3.1)
41
+ rspec-expectations (2.3.0)
42
+ diff-lcs (~> 1.1.2)
43
+ rspec-mocks (2.3.0)
44
+ term-ansicolor (1.0.5)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ bundler (~> 1.0.7)
51
+ cucumber (~> 0.10.0)
52
+ lackie!
53
+ mongrel (~> 1.1.5)
54
+ rack (~> 1.2.1)
55
+ relevance-rcov (~> 0.9.2.1)
56
+ rest-client (~> 1.4.2)
57
+ rspec (~> 2.2.0)
data/README.rdoc ADDED
@@ -0,0 +1,65 @@
1
+ = Lackie
2
+
3
+ == Warning
4
+
5
+ I haven't used Lackie to develop an application yet. But I have used it in
6
+ various browsers including firefox, chrome and the samsung maple emulator.
7
+
8
+ == About
9
+
10
+ Lackie enables automation of remote applications using an HTTP middleman:
11
+
12
+ Ruby Client -> Lackie Service <- Remote App
13
+
14
+ Lackie automates applications running in environments that are difficult to
15
+ control remotely. Lackie requires minimal support in target environments:
16
+ scheduling (e.g. window.setInterval) and HTTP client capabilities (e.g. ajax).
17
+
18
+ Where it's difficult to programmatically launch the remote application, it can
19
+ be started manually before the automation begins. Lackie effectively "attaches"
20
+ itself to the running "zombie" application.
21
+
22
+ Lackie uses an HTTP service as a proxy for application automation commands:
23
+
24
+ 1. application surrenders control to automation
25
+ 2. the surrendered application polls Lackie for commands
26
+ 3. the automator sends a command to Lackie
27
+ 4. the application executes the command and sends the result to Lackie
28
+ 5. the automator polls Lackie and receives the result (or error)
29
+
30
+ == Usage
31
+
32
+ Lackie is implemented as rack middleware, so:
33
+
34
+ require 'rack'
35
+ require 'lackie'
36
+ require 'lackie/rack'
37
+
38
+ Rack::Builder.app do
39
+ use Lackie::Rack::Middleware
40
+ run MyApp
41
+ end
42
+
43
+ It will intercept all requests where the path starts with /lackie/
44
+
45
+ Lackie expects remote applications to:
46
+
47
+ 1. poll the middleware for commands expressed as strings
48
+ 2. execute those commands when they appear
49
+ 3. send string results back to the middleware
50
+
51
+ == Example
52
+
53
+ The source code includes an example rack app:
54
+
55
+ rackup features/support/config.ru
56
+
57
+ Open this URL in your browser of choice:
58
+
59
+ http://localhost:9292/example_app/app.html
60
+
61
+ Now you can execute commands in the remote application:
62
+
63
+ require 'rubygems'
64
+ require 'lackie'
65
+ Lackie::RemoteControl.new("localhost", 9292).exec("1 + 2") # => "3"
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "Run all specs with rcov"
5
+ RSpec::Core::RakeTask.new(:rcov) do |t|
6
+ t.rcov = true
7
+ t.rcov_opts = %w{--exclude gems\/,spec\/,features\/}
8
+ end
9
+
10
+ desc "Run all specs, then all features"
11
+ task :default do
12
+ system("rspec spec && cucumber features")
13
+ end
@@ -0,0 +1,19 @@
1
+ Feature: Remote Control
2
+ In order to automate remote applications with HTTP client capabilities
3
+ As a client
4
+ I want to surrender applications as javascript lackies
5
+
6
+ Scenario: Remote Execution
7
+ Given I have surrendered my web page as a lackie
8
+ When I tell the lackie to execute "1 + 1"
9
+ Then I should see a result with the value "2"
10
+
11
+ Scenario: Remote Execution Error
12
+ Given I have surrendered my web page as a lackie
13
+ When I tell the lackie to execute "(function() { throw 'whoopsie'; })()"
14
+ Then I should see an error with the message "whoopsie"
15
+
16
+ Scenario: Remote Log
17
+ Given I have surrendered my web page as a lackie
18
+ When I tell the lackie to log "yipee"
19
+ Then I should see a result with the value "yipee"
@@ -0,0 +1,23 @@
1
+ Given /^I have surrendered my web page as a lackie$/ do
2
+ browse_example_app
3
+ end
4
+
5
+ When /^I tell the lackie to log "([^\"]*)"$/ do |message|
6
+ @response = remote_control.log(message)
7
+ end
8
+
9
+ When /^I tell the lackie to execute "([^\"]*)"$/ do |script|
10
+ begin
11
+ @response = remote_control.exec(script)
12
+ rescue => e
13
+ @error = e
14
+ end
15
+ end
16
+
17
+ Then /^I should see a result with the value "([^\"]*)"$/ do |value|
18
+ @response.to_s.should == value
19
+ end
20
+
21
+ Then /^I should see an error with the message "([^\"]*)"$/ do |message|
22
+ @error.message.should == message
23
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'lackie/rack'
5
+ require 'example_app'
6
+
7
+ run ExampleApp.build
@@ -0,0 +1,54 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rack'
5
+ require 'mongrel'
6
+ require 'selenium-webdriver'
7
+ require 'lackie'
8
+ require 'lackie/rack'
9
+ require 'example_app'
10
+
11
+ module LackieWorld
12
+ def remote_control
13
+ Lackie::RemoteControl.new(host, port)
14
+ end
15
+
16
+ def browse_example_app
17
+ web_driver.get "http://#{host}:#{port}/example_app/app.html"
18
+ end
19
+
20
+ private
21
+
22
+ def host
23
+ "localhost"
24
+ end
25
+
26
+ def port
27
+ 6663
28
+ end
29
+
30
+ def web_driver
31
+ @@web_driver ||= begin
32
+ start_server
33
+ driver = Selenium::WebDriver.for :firefox
34
+ at_exit { driver.close }
35
+ driver
36
+ end
37
+ end
38
+
39
+ def start_server
40
+ rack_server = nil
41
+ rack_thread = Thread.new do
42
+ ::Rack::Handler::Mongrel.run(ExampleApp.build, :Host => host, :Port => port) do |server|
43
+ rack_server = server
44
+ end
45
+ end
46
+ at_exit do
47
+ rack_server.stop
48
+ rack_thread.kill
49
+ end
50
+ sleep 0.05 while rack_server.nil?
51
+ end
52
+ end
53
+
54
+ World(LackieWorld)
@@ -0,0 +1,13 @@
1
+ <html>
2
+ <head>
3
+ <title>Lackie: Surrendered Web Page Example</title>
4
+ </head>
5
+ <body>
6
+
7
+ <!-- Lackie::RemoteControl#log creates elements under #LackieLog, if it exists -->
8
+ <div id="LackieLog" style="background-color:#ffffff"></div>
9
+
10
+ <script type="text/javascript" src="/lackie/surrender"></script>
11
+
12
+ </body>
13
+ </html>
@@ -0,0 +1,9 @@
1
+ class ExampleApp
2
+ def self.build
3
+ ::Rack::Builder.app do
4
+ use Lackie::Rack::Middleware
5
+ use Rack::Static, :urls => ["/example_app"], :root => File.dirname(__FILE__)
6
+ run lambda { |e| [404, {'Content-Type' => 'text/html'}, ['Not Found']] }
7
+ end
8
+ end
9
+ end
data/lackie.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
+ require "lackie"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'lackie'
7
+ s.version = Lackie::VERSION
8
+ s.authors = ['Josh Chisholm']
9
+ s.description = 'Automates remote applications using an HTTP middleman'
10
+ s.summary = "lackie-#{s.version}"
11
+ s.email = 'joshuachisholm@gmail.com'
12
+ s.homepage = 'http://github.com/joshski/lackie'
13
+
14
+ s.add_dependency 'rack', '~> 1.2.1'
15
+ s.add_dependency 'rest-client', '~> 1.4.2'
16
+
17
+ s.add_development_dependency 'rspec', '~> 2.2.0'
18
+ s.add_development_dependency 'cucumber', '~> 0.10.0'
19
+ s.add_development_dependency 'mongrel', '~> 1.1.5'
20
+ s.add_development_dependency 'relevance-rcov', '~> 0.9.2.1'
21
+
22
+ s.rubygems_version = "1.3.7"
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
25
+ s.extra_rdoc_files = ["README.rdoc"]
26
+ s.require_path = "lib"
27
+ end