headless 0.0.1

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.
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
+