headless 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +62 -0
  3. data/lib/headless.rb +117 -0
  4. metadata +69 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Leonid Shevtsov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Headless
2
+
3
+ Headless is a Ruby interface for Xvfb. It allows you to create a headless display straight from Ruby code, hiding some low-level action.
4
+
5
+ I created it so I can run Selenium tests in Cucumber without any shell scripting. Even more, you can go headless only when you run tests against Selenium.
6
+
7
+ ## Installation
8
+
9
+ On Debian/Ubuntu:
10
+
11
+ sudo apt-get install xvfb
12
+ gem install headless
13
+
14
+ ## Usage
15
+
16
+ Block mode:
17
+
18
+ require 'rubygems'
19
+ require 'headless'
20
+ require 'selenium-webdriver'
21
+
22
+ Headless.ly do
23
+ driver = Selenium::WebDriver.for :firefox
24
+ driver.navigate.to 'http://google.com'
25
+ puts driver.title
26
+ end
27
+
28
+ Object mode:
29
+
30
+ require 'rubygems'
31
+ require 'headless'
32
+ require 'selenium-webdriver'
33
+
34
+ headless = Headless.new
35
+ headless.start
36
+
37
+ driver = Selenium::WebDriver.for :firefox
38
+ driver.navigate.to 'http://google.com'
39
+ puts driver.title
40
+
41
+ headless.destroy
42
+
43
+ ## Cucumber
44
+
45
+ Running cucumber headless is now as simple as adding a before and after hook in `features/support/env.rb`:
46
+
47
+
48
+ # change the condition to fit your setup
49
+ if Capybara.current_driver == :selenium
50
+ require 'headless'
51
+
52
+ headless = Headless.new
53
+ headless.start
54
+
55
+ at_exit do
56
+ headless.destroy
57
+ end
58
+ end
59
+
60
+ ---
61
+
62
+ © 2010 Leonid Shevtsov, released under the MIT license
data/lib/headless.rb ADDED
@@ -0,0 +1,117 @@
1
+ # A class incapsulating the creation and usage of a headless X server
2
+ #
3
+ # == Prerequisites
4
+ #
5
+ # * X Window System
6
+ # * Xvfb[http://en.wikipedia.org/wiki/Xvfb]
7
+ #
8
+ # == Usage
9
+ #
10
+ # Block mode:
11
+ #
12
+ # require 'rubygems'
13
+ # require 'headless'
14
+ # require 'selenium-webdriver'
15
+ #
16
+ # Headless.ly do
17
+ # driver = Selenium::WebDriver.for :firefox
18
+ # driver.navigate.to 'http://google.com'
19
+ # puts driver.title
20
+ # end
21
+ #
22
+ # Object mode:
23
+ #
24
+ # require 'rubygems'
25
+ # require 'headless'
26
+ # require 'selenium-webdriver'
27
+ #
28
+ # headless = Headless.new
29
+ # headless.start
30
+ #
31
+ # driver = Selenium::WebDriver.for :firefox
32
+ # driver.navigate.to 'http://google.com'
33
+ # puts driver.title
34
+ #
35
+ # headless.destroy
36
+ #--
37
+ # TODO test that reuse actually works with an existing xvfb session
38
+ # TODO maybe write a command-line wrapper like
39
+ # headlessly firefox
40
+ #++
41
+ class Headless
42
+
43
+ class Exception < ::Exception
44
+ end
45
+
46
+ # The display number
47
+ attr_reader :display
48
+
49
+ # Creates a new headless server, but NOT switches to it immediately. Call #start for that
50
+ def initialize(options = {})
51
+ @xvfb = `which Xvfb`.strip
52
+ raise Exception.new('Xvfb not found on your system') if @xvfb == ''
53
+
54
+ # TODO more options, like display dimensions and depth; set up default dimensions and depth
55
+ @display = options.fetch(:display, 99).to_i
56
+ @reuse_display = options.fetch(:reuse, true)
57
+
58
+ #TODO more logic here, autopicking the display number
59
+ if @reuse_display
60
+ launch_xvfb unless read_pid
61
+ elsif read_pid
62
+ raise Exception.neW("Display :#{display} is already taken and reuse=false")
63
+ else
64
+ launch_xvfb
65
+ end
66
+
67
+ raise Exception.new("Xvfb did not launch - something's wrong") unless read_pid
68
+ end
69
+
70
+ # Switches to the headless server
71
+ def start
72
+ @old_display = ENV['DISPLAY']
73
+ ENV['DISPLAY'] = ":#{display}"
74
+ end
75
+
76
+ # Switches back from the headless server
77
+ def stop
78
+ ENV['DISPLAY'] = @old_display
79
+ end
80
+
81
+ # Switches back from the headless server and terminates the headless session
82
+ def destroy
83
+ stop
84
+ Process.kill('TERM', xvfb_pid) if read_pid
85
+ end
86
+
87
+ # Block syntax:
88
+ #
89
+ # Headless.run do
90
+ # # perform operations in headless mode
91
+ # end
92
+ #
93
+ # Alias: #ly (Headless.ly)
94
+ def self.run(options={}, &block)
95
+ headless = Headless.new(options)
96
+ headless.start
97
+ yield headless
98
+ headless.destroy
99
+ end
100
+
101
+ class <<self; alias_method :ly, :run; end
102
+
103
+ private
104
+ attr_reader :xvfb_pid
105
+
106
+ def launch_xvfb
107
+ system "#{@xvfb} :#{display} -ac >/dev/null 2>&1 &"
108
+ sleep 1
109
+ end
110
+
111
+ def read_pid
112
+ @xvfb_pid=(File.read("/tmp/.X#{display}-lock") rescue "").strip.to_i
113
+ @xvfb_pid=nil if @xvfb_pid==0
114
+ @xvfb_pid
115
+ #TODO maybe check that the process still exists
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: headless
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Leonid Shevtsov
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-06 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: " Headless is a Ruby interface for Xvfb. It allows you to create a headless display straight from Ruby code, hiding some low-level action.\n"
23
+ email: leonid@shevtsov.me
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/headless.rb
32
+ - README.md
33
+ - LICENSE
34
+ has_rdoc: true
35
+ homepage: http://github.com/leonid-shevtsov/headless
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ hash: 3
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements:
62
+ - Xvfb
63
+ rubyforge_project:
64
+ rubygems_version: 1.3.7
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Ruby headless display interface
68
+ test_files: []
69
+