Giter Club home page Giter Club logo

headless's Introduction

Headless Travis CI status

Buy Me a Coffee at ko-fi.com

Headless is the Ruby interface for Xvfb. It allows you to create a headless display straight from Ruby code, hiding the low-level action. It can also capture images and video from the virtual framebuffer. For example, you can record screenshots and screencasts of your failing integration specs.

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. Other possible uses include pdf generation with wkhtmltopdf, or screenshotting.

Documentation is available at rubydoc.info

Changelog

Note: Headless will NOT hide most applications on OS X. Here is a detailed explanation

Installation

On Debian/Ubuntu:

sudo apt-get install xvfb
gem install headless

Usage

Block mode:

require 'rubygems'
require 'headless'
require 'selenium-webdriver'

Headless.ly do
  driver = Selenium::WebDriver.for :firefox
  driver.navigate.to 'http://google.com'
  puts driver.title
end

Object mode:

require 'rubygems'
require 'headless'
require 'selenium-webdriver'

headless = Headless.new
headless.start

driver = Selenium::WebDriver.for :firefox
driver.navigate.to 'http://google.com'
puts driver.title

headless.destroy

Cucumber

Running cucumber headless is now as simple as adding a before and after hook in features/support/env.rb:

# change the condition to fit your setup
if Capybara.current_driver == :selenium
  require 'headless'

  headless = Headless.new
  headless.start
end

Running tests in parallel

If you have multiple threads running acceptance tests in parallel, you want to spawn Headless before forking, and then reuse that instance with destroy_at_exit: false. You can even spawn a Headless instance in one ruby script, and then reuse the same instance in other scripts by specifying the same display number and reuse: true.

# spawn_headless.rb
Headless.new(display: 100, destroy_at_exit: false).start

# test_suite_that_could_be_ran_multiple_times.rb
Headless.new(display: 100, reuse: true, destroy_at_exit: false).start

# reap_headless.rb
headless = Headless.new(display: 100, reuse: true)
headless.destroy

# kill_headless_without_waiting.rb
headless = Headless.new
headless.destroy_without_sync

There's also a different approach that creates a new virtual display for every parallel test process - see this implementation by @rosskevin.

Cucumber with wkhtmltopdf

Note: this is true for other programs which may use headless at the same time as cucumber is running

When wkhtmltopdf is using Headless, and cucumber is invoking a block of code which uses a headless session, make sure to override the default display of cucumber to retain browser focus. Assuming wkhtmltopdf is using the default display of 99, make sure to set the display to a value != 99 in features/support/env.rb file. This may be the cause of Connection refused - connect(2) (Errno::ECONNREFUSED).

headless = Headless.new(:display => '100')
headless.start

Capturing video

Video is captured using ffmpeg. You can install it on Debian/Ubuntu via sudo apt-get install ffmpeg or on OS X via brew install ffmpeg. You can capture video continuously or capture scenarios separately. Here is typical use case:

require 'headless'

headless = Headless.new
headless.start

Before do
  headless.video.start_capture
end

After do |scenario|
  if scenario.failed?
    headless.video.stop_and_save("/tmp/#{BUILD_ID}/#{scenario.name.split.join("_")}.mov")
  else
    headless.video.stop_and_discard
  end
end

Video options

When initiating Headless you may pass a hash with video options.

headless = Headless.new(:video => { :frame_rate => 12, :codec => 'libx264' })

Available options:

  • :codec - codec to be used by ffmpeg
  • :frame_rate - frame rate of video capture
  • :provider - ffmpeg provider - either :libav (default) or :ffmpeg
  • :provider_binary_path - Explicit path to avconv or ffmpeg. Only required when the binary cannot be discovered on the system $PATH.
  • :pidfile_path - path to ffmpeg pid file, default: "/tmp/.headless_ffmpeg#{@display}.pid"
  • :tmpfile_path - path to tmp video file, default: "/tmp/.headless_ffmpeg#{@display}.mov"
  • :log_file_path - ffmpeg log file, default: "/dev/null"
  • :extra - array of extra ffmpeg options, default: []

Taking screenshots

Call headless.take_screenshot to take a screenshot. It needs two arguments:

  • file_path - path where the image should be stored
  • options - options, that can be: :using - :imagemagick or :xwd, :imagemagick is default, if :imagemagick is used, image format is determined by file_path extension

Screenshots can be taken by either using import (part of imagemagick library) or xwd utility.

import captures a screenshot and saves it in the format of the specified file. It is convenient but not too fast as it has to do the encoding synchronously.

xwd will capture a screenshot very fast and store it in its own format, which can then be converted to one of other picture formats using, for example, netpbm utilities - xwdtopnm <xwd_file> | pnmtopng > capture.png.

To install the necessary libraries on ubuntu:

import - run sudo apt-get install imagemagick xwd - run sudo apt-get install X11-apps and if you are going to use netpbm utilities for image conversion - sudo apt-get install netpbm

Troubleshooting

/tmp/.X11-unix is missing

Xvfb requires this directory to exist. It cannot be created automatically, because the directory must be owned by the root user. (You will never get this error if running as root - for example, in a Docker container.)

On macOS, the directory will be created when you run XQuartz.app. But since /tmp is cleared on reboot, you will need to open XQuartz.app after a reboot before running Xvfb. (You don't need to leave it running.)

To create this directory manually, on either macOS or Linux:

mkdir /tmp/.X11-unix
sudo chmod 1777 /tmp/.X11-unix
sudo chown root /tmp/.X11-unix/

Note that you may need to run these commands after every reboot, too.

Display socket is taken but lock file is missing

This means that there is an X server that is taking up the chosen display number, but its lock file is missing. This is an exceptional situation. Please stop the server process manually (pkill Xvfb) and open an issue.

Video not recording

If video is not recording, and there are no visible exceptions, try passing the following option to Headless to figure out the reason: Headless.new(video: {log_file_path: STDERR}). In particular, there are some issues with the version of avconv packaged with Ubuntu 12.04 - an outdated release, but still in use on Travis.

##Contributors


© 2011-2015 Leonid Shevtsov, released under the MIT license

headless's People

Contributors

abotalov avatar alanshields avatar atzorvas avatar beezly avatar bitdeli-chef avatar blakemesdag avatar djanowski avatar evandrodp avatar gpavlidi avatar gshakhn avatar iafonov avatar johnhamelink avatar leonid-shevtsov avatar marxarelli avatar masatomo avatar mits87 avatar natritmeyer avatar patrickfranken avatar recursive avatar reiz avatar samnissen avatar shockwavenn avatar ynagorny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

headless's Issues

read_nonblock issue

Hi,

When I'm trying to execute a simple script, I get the following error :

/usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:193:in read_nonblock': end of file reached (EOFError) from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:193:inensure_xvfb_is_running'
from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:184:in launch_xvfb' from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:172:inblock in pick_available_display'
from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:168:in each' from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:168:inpick_available_display'
from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:164:in attach_xvfb' from /usr/local/share/gems/gems/headless-2.2.0/lib/headless.rb:88:ininitialize'
from record.rb:5:in new' from record.rb:5:in

'

My script :

require 'rubygems'
require 'headless'
require 'selenium-webdriver'

headless = Headless.new(:dimensions => '1280x720', :video => { :frame_rate => 30, :codec => 'libx264', :provider => 'ffmpeg', :provider_binary_path => 'ffmpeg' })
headless.start

driver = Selenium::WebDriver.for :firefox
driver.manage().window().maximize()
driver.navigate.to 'https://www.livewebinar.com/BotAccess/47'
puts driver.title

headless.video.start_capture

sleep(60)

headless.video.stop_and_save("/root/videos/video.mov")
headless.destroy

OSX support?

On ubuntu you can install xvfb by apt-get install. On OSX, the xvfb is inclued in XQuartz. Though I have installed XQuartz, the headless gem still doesn't work:

Headless::Exception: Xvfb not found on your system

How to tell Headless where is my xvfb?

Question: how do you anticipate headless to work with Docker Selenium

Thanks for the wonderful gem.

I am trying to see how this can work with Selenium Docker images. If I understand correctly, Docker selenium exposes a selenium server running already on port 4444

Do we just change headless to always use that selenium server or is there a better way to do this without having to write a lot of Dockerfile to install browsers/ruby/selenium etc?

Thanks
Rajat Jindal

"Cannot establish any listening sockets" error precludes autopick: true

Suppose I invoke Headless.run(display: pick-a-display(), autopick: true) do ... end, so that I specify both an initial guess for a display, and ask Headless to handle the rest. My server, for whatever the reason, currently has a particular display that consistently responds with "Cannot establish any listening sockets". (I don't know why; there are no Xvfb processes running at all. But that's beside the point right now...) So if pick-a-display() happens to hit that bad number, then this call to Headless.run will always fail, even though I've asked Headless to autopick a working display.

It seems to me that ensure_xvfb_launched is overly aggressive about terminating the call to :run. It would be nice for pick_available_display do something like

  def pick_available_display(display_set, can_reuse)
    @pending_exception = nil
    display_set.each do |display_number|
      @display = display_number

      return true if xvfb_running? && can_reuse && (xvfb_mine? || !@autopick_display)
      begin
        return true if !xvfb_running? && launch_xvfb
      rescue Headless::Exception => e
        @pending_Exception = e
      end
    end
    raise @pending_exception || Headless::Exception.new("Could not find an available display")
  end

so that if other display options were available, the call would still succeed...

Display socket is taken but lock file is missing

When I run my tests in parallel I am getting the following error:
"Failure/Error: Unable to find matching line from backtrace
Headless::Exception:
Display socket is taken but lock file is missing - check the Headless troubleshooting guide

Click() undefined when executing JS through Webdriver running Firefox via Headless

This may honestly not be an issue with Headless or XVFB at all. However, there is an utter dearth of information, and I figured you might know better than others since you were kind enough (and wise enough) to grace us with this awesome gem that let's us use XVFB.

To summarize, I'm trying to execute the click() function on an element through webdriver. Roughly, this looks like:

@driver.execute_script("document.findElementsByName('Foo')[0].click();")

I haven't had any issues executing arbitrary amounts of JS through Webdriver while running XVFB before (although I never was using the click() function).

Further, the scripts execute fine when running on plain, vanilla Firefox.

I know, I know - why not just click the element using the methods provided by WebDriver? Truthfully, I've been commenting on the webdriver backlog regarding my specific case. I finally decided today to stop attempting to mess around using webdriver to do a man's business, and put in this very hacky JS to click() the element. It was working fine, but right when I batched off a system-test, I noticed that XVFB was not having it. Which brings me here....

Any insight you have would be greatly appreciated. I'll admit - I'm no JS guru, and I'm certainly new to XVFB.

Thanks,
wokkaflokka
(waka flokka flame)

fatal IO error 11

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":99"  
after 908 requests (908 known processed) with 0 events remaining.

Video can't close & save properly because of this.
I'm able to run the same script with success in archlinux, but not with an ubuntu setup.
allthough I haven't setup the ubuntu machine, so maybe there is something getting in the way.

and idea?

Not working on CircleCI

My hunch is that it's a similar reason to the the travis issues hinted at in the readme. Which I'm guessing is an ffmpeg bug. A thread on a similar issue suggests that executing xeyes will "prime" the x11 server and work around the bug, I had no success with it.

I've got headless setup like this. As a tag for my selenium

Around('@movie') do |scenario, block|
  previous = Capybara.javascript_driver
  Capybara.javascript_driver = :selenium

  headless = Headless.new(video: { log_file_path: STDERR })
  headless.start

  # prime x server because of ffmpeg bug?
 # require 'timeout'
 # begin
 #   Timeout.timeout(0.1) { `nohup xeyes&` }
 # rescue Timeout::Error
 #   "we're good"
 # end

  headless.video.start_capture
  block.call
  filename = scenario.name.gsub(' ', '-').gsub(/[^\w\-]/, '') + '.mov'
  temp_dir = ENV['CIRCLE_ARTIFACTS'] || Capybara.save_and_open_page_path
  filepath = File.join(temp_dir, filename)
  puts "Saving movie to #{filepath}"
  headless.video.stop_and_save(filepath)
  Capybara.javascript_driver = previous
end

The output in circle ci is as follows

 @javascript @movie
  Scenario: As a user I need to be able to edit and delete an order and its items       # features/orders.feature:44
avconv version 0.8.17-4:0.8.17-0ubuntu0.12.04.1, Copyright (c) 2000-2014 the Libav developers
  built on Mar 16 2015 13:26:50 with gcc 4.6.3
[x11grab @ 0xd84be0] device: :100 -> display: :100 x: 0 y: 0 width: 1280 height: 1024
[x11grab @ 0xd84be0] shared memory extension  found
X Error of failed request:  BadCursor (invalid Cursor parameter)
  Major opcode of failed request:  142 (XFIXES)
  Minor opcode of failed request:  25 (XFixesGetCursorImageAndName)
  Resource id in failed request:  0x400001
  Serial number of failed request:  14
  Current serial number in output stream:  14
    When I do things that should be recorded   

And no file is created.

I'm happy to keep testing to sus out more info.

Thanks!

After upgrading rails to 3.2.9 headless can`t focus input

I am using headless (0.3.1) after upgrading to lastest version of rails, i cant anymore use jquery focus function.

          $('#password-clear').focus(function() {
              $('#password-clear').hide();
              $('#password-password').show();
              $('#password-password').focus();
          });

Give the dimensions parameter but got a error message

I use headless gem in my cucumber-ruby code.

require 'headless'    
headless = Headless.new(dimensions: "1400*900*24")
puts headless
puts headless.display
puts headless.dimensions
headless.start
......
headless.destroy

But I got the error message on line 2.

/home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:156:in `ensure_xvfb_is_running': Xvfb is frozen (Headless::Exception)
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:148:in `launch_xvfb'
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:136:in `block in pick_available_display'
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:132:in `each'
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:132:in `pick_available_display'
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:128:in `attach_xvfb'
     from /home/andy/.rvm/gems/ruby-1.9.3-p448@global/gems/headless-1.0.1/lib/headless.rb:78:in `initialize'
     from headless.rb:12:in `new'
     from headless.rb:12:in `<main>'

My OS is Ubuntu 13.04, and it's a virtual machine.

How can I fix this problem?

Thanks.

Error: no display specified using headless in separate scripts

Taking a cue from the docs for testing in parallel I spawn a headless instance on display 100, and in a separate script I try launching firefox but it fails.

I get an unable to obtain stable firefox connection in 60 seconds error. But after further debugging it turns out the underlying cause is Error: no display specified.

I've written a script to reproduce this, and it can be found here. Basically it implements the example in the docs.

When combining the scripts into one, it works.

Thanks!

Intermittently unable to obtain stable firefox connection using ruby and headless gem

I have intermittently seen that running Selenium ruby tests using Firefox and the headless gem, I get a unable to obtain stable firefox connection in 60 seconds message.

A bug was filed with the Selenium team at http://code.google.com/p/selenium/issues/detail?id=4967 , and they requested debug output.

I was able to gather the debug logging output requested (can be accessed here at the bug thread mentioned above).

The response from the selenium ruby bindings team was that:

The problem in the attached log is that the browser has no display to connect to, as seen from the output "Error: cannot open display: :99".

This looks like a bug in the headless gem, not in selenium-webdriver. Perhaps it doesn't > wait properly for the display to launch? If you file a bug with them, please link to it here > for future reference.

Any ideas on how to address this intermittent issue?

Thanks!

Dimension problem

i am trying to video capture. There is a black area padding right of video. I tried resize_to but it doesnt work. can you help me?

Running headless with flash

Hi

Not sure if this is the best place for this if not apologies. When using headless I can run chrome fine, take screenshots etc. I face an issue though when I try to open a page that needs flash to run.

The page opens but with the message "please restart chrome to run above flash". Has anyone got this to run successfully on flash based sites?

I am doing this on a Linux box ( EC2 instance ), all via the command line

Error with the way headless ends Xvfb process?

I have two apps running on a single server that perform headless browsing tasks. Each time one browses, the Xvfb process is not dying and instead becomes a zombie. I can confirm this with the following script.

require 'headless'
require 'watir-webdriver'
require 'yaml'

zombies_at_start = `ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'`.split("\n").count

5.times do
  begin
    d = YAML.load_file("/path/to/config/headless.yml")['build_number'] #=> "98"
    h = Headless.new(:display => d) 
    h.start
    b = Watir::Browser.new :firefox
    b.goto 'http://google.com'
    sleep(0.5)
  ensure
    b.close
    h.destroy
  end
  sleep(0.5)
end

zombies_at_end = `ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'`.split("\n").count

puts "Created #{zombies_at_end - zombies_at_start} more zombies." 
#=> Created 5 more zombies.

Version info:

  • xorg-x11-server-Xvfb-1.15.0-26.el6.centos.i686
  • CentOS release 6.5 (Final)
  • ruby-2.0.0-p353
  • rvm 1.25.25
  • selenium-webdriver (2.45.0, 2.44.0)
  • watir-webdriver (0.7.0)
  • headless (2.1.0)

Free StackOverflow points if this is me doing something dumb rather than a bug.

cant require file

I get the error of
/Library/Ruby/Site/2.0.0/rubygems/core_ext/kernel_require.rb:126:in require': cannot load such file -- headless (LoadError) from /Library/Ruby/Site/2.0.0/rubygems/core_ext/kernel_require.rb:126:inrescue in require'
from /Library/Ruby/Site/2.0.0/rubygems/core_ext/kernel_require.rb:39:in require' from test.rb:10:in

'

When I require it like so require 'headless'

When i do gem list it shows up. I don't know what Im doing wrong. Help would be greatly appreciated!

GOP option in the Video Recorder

Hi,

I'm trying to record a video with Headless. I'm on FreeBSD 10.
When I use the video recorder, I have this error :
"Codec AVOption g (set the group of picture (GOP) size) specified for input file #0 (:99) is not a decoding option.
Conversion failed!"

I asked to the ffmpeg community why this line doesn't work : "ffmpeg -y -r 30 -g 600 -f x11grab -s 1024x768 -i :1 -vcodec libx264 /path/of/my/file" (which is line 27 in video_recorder.rb).

It seems that -g option is an output option.
And ffmpeg works like this : "ffmpeg [input options] -i input [output options] output"
If I put the -g option after -i option, it works well.

Anyone else had this problem ?

audio problem

i added extra but video doesnt have sound

headless = Headless.new(dimensions: '1080x1920x24' ,video: {log_file_path: STDERR, frame_rate: 30, codec: 'libx264', devices: ["-draw_mouse 0"], extra: %w(-acodec libmp3lame -ar 44100 -ab 128k -threads 0) })

Race condition when starting Xvfb

Here's what can happen:

  • Two processes, A and B, try to use Headless.new().
  • Process A "wins" and gains the lock on /tmp/.X-#{display}-lock
  • Process B loses. Xvfb errors and exits immediately.
  • ensure_xvfb_is_running calls xvfb_running?
  • xvfb_running? finds a display lock file, and thinks it's ours. It
    erroneously reports that our process is running.

Then, Headless goes on using that display number, even though it's not the process we started. Even if we set resuse: false.
When process A destroys its Xvfb, all of process B's X11 programs die unexpectedly.

When using Selenium, this usually expresses itself as an EOFError. The Selenium web driver loses its connection to the web browser when it's killed.

Headless gem lacks global read permissions

When I 'gem install headless', I get a gem that's installed that only has root with read/write permissions.

See:

root@vagrant-ubuntu-trusty-64:/usr/local/rvm/gems/ruby-2.1.2/gems# find headless* -name "*.rb" -exec ls -lh {} ";"
-rw-r--r-- 1 root rvm 1.7K Dec 23 11:59 headless-1.0.2/lib/headless/video/video_recorder.rb
-rw-r--r-- 1 root rvm 1.5K Dec 23 11:59 headless-1.0.2/lib/headless/cli_util.rb
-rw-r--r-- 1 root rvm 5.1K Dec 23 11:59 headless-1.0.2/lib/headless.rb
-rw-r--r-- 1 root rvm 5.1K Dec 23 11:59 headless-1.0.2/spec/headless_spec.rb
-rw-r--r-- 1 root rvm 2.4K Dec 23 11:59 headless-1.0.2/spec/video_recorder_spec.rb

# vs:
-rw-r--r-- 1 root rvm 2.7K Dec 23 12:00 headless-2.2.0/lib/headless/video/video_recorder.rb
-rw------- 1 root rvm 1.6K Dec 23 12:00 headless-2.2.0/lib/headless/cli_util.rb
-rw------- 1 root rvm 7.0K Dec 23 12:00 headless-2.2.0/lib/headless.rb
-rw-r--r-- 1 root rvm 1.3K Dec 23 12:00 headless-2.2.0/spec/integration_spec.rb
-rw------- 1 root rvm 8.8K Dec 23 12:00 headless-2.2.0/spec/headless_spec.rb
-rw-r--r-- 1 root rvm 3.8K Dec 23 12:00 headless-2.2.0/spec/video_recorder_spec.rb

When I try to require 'headless', I get the error:

LoadError: cannot load such file -- headless

If I add read permissions to the file, I am able to load the module without error.

Error in after hook

An error occurred in an after hook: NoMethodError: undefined method `quit' for nil:NilClass

This error is being thrown on the first line of the after(:each) do block.

require 'headless'
require "selenium-webdriver"
require "rspec"
include RSpec::Expectations
Headless.new(display: 99, destroy_at_exit: true).start

Headless.ly do
   before(:each) do
      @driver = Selenium::WebDriver.for :firefox
      @base_url = "thingy.magic.com"
      @accept_next_alert = true
      @driver.manage.timeouts.implicit_wait = 30
      @verification_errors = []
    end

    after(:each) do
      @driver.quit
      @verification_errors.should == []
    end
  # test code
end

Any help would be useful.

ubuntu 12.04 and ffmpeg

Hi,
Just noticied that ffmpeg is deprecated on ubuntu 12.04. It will be replaced by avconv in upcoming releases. avconv seems to be a fork of ffmpeg but curently using the same command line interface. Is it possible to give the choice between ffmpeg and avconv ?

Thank's

exits 1

So when I use this with xvfb-run, it exits 1. Any ideas as to why?

Problem if xvfb pid file gets orphaned...

We had a problem on our CI box where it looks like the xvfb process died (or got killed) but left the pidfile around.

Here is the error:
20 scenarios (20 passed)
486 steps (486 passed)
1m33.746s
/opt/ruby-ee/lib/ruby/gems/1.8/gems/headless-0.1.0/lib/headless.rb:89:in 'kill': No such process (Errno::ESRCH)
from /opt/ruby-ee/lib/ruby/gems/1.8/gems/headless-0.1.0/lib/headless.rb:89:in `destroy'
from /mnt/cruise-data/.cruise/projects/ph/work/features/support/env.rb:48
rake aborted!
Command failed with status (1): [/opt/ruby-ee/bin/ruby -I "/opt/ruby-ee/lib...]

Going in and removing the pidfile fixed the problem.

I'm thinking that a fix is the if the Process.kill doesn't succeed then the pidfile should get deleted.

Occasional 'unable to obtain stable firefox connection' Error

When attempting to run selenium webdriver tests with the headless gem (v1.0.1) on CentOS, we are seeing tests fail with the following message around ~5% of the time on our CI server:
unable to obtain stable firefox connection in 60 seconds

This seems very similar to the issue detailed in this closed ticket, and the more recent comments indicate that other people are seeing this problem as well. #33

When running with debug output we also see this error occur before the firefox timeout:
The application 'firefox' lost its connection to the display :1785.0; most likely the X server was shut down or you killed/destroyed the application.

Our tests should not be doing anything that would stop or restart the X server directly, as they are only accessing Xvfb through the headless gem. We are out of ideas to debug this issue, any information you might be able to provide would be greatly appreciated.

Full debug output can be seen here:
https://gist.github.com/tfillmore-ck/fcb534384752193ad4bd

consistently 'Unable to Obtain a Stable firefox connection in 60 seconds' on Debian 8

Currently setting up some CI runner on Debian 8, the following test fails (both with Debian's iceweasel and Mint's firefox):

require 'headless'
require 'selenium-webdriver'

Headless.ly do
  driver = Selenium::WebDriver.for :firefox
  driver.navigate.to 'http://google.com'
  puts driver.title 
end

The same works on OS X. Using ruby 2.2, selenium-webdriver 2.47.1, headless 2.2, firefox 39 and 40. Firefox has been tested to work by itself by running it manually in Xvfb and capturing screen with imagemagick's import.

Run Concurrently (using different ports?)

First off, thanks for the awesome gem.

I want to use headless to run concurrent selenium builds using this gem, and I see that xvfb should allow being passed an --auto-servernum flag at runtime. This will presumably prevent the following collision error I'm seeing currently when running concurrent builds:

Errno::ECONNREFUSED: Failed to open TCP connection to 127.0.0.1:7057 (Connection refused - connect(2) for "127.0.0.1" port 7057)

I've tried invoking headless using a random display each time inside a sidekiq worker with concurrency of 3, but I get similar errors

headless = Headless.new(display: rand(100))
headless.start

How to just capture screenshot of the window?

Right now, headless.take_screenshot('./somefile.jpg') works great!

But the saved file has all the Menubar, address bar, scrollbar attached.

Is there any other function call or params that can be passed to just capture the content window only without the Menubars,status bar, scroll bar, ..etc.??

Audio Video recording

Hello,

I saw the issue: #66
and I saw the video_recorder.rb

In line 97 is a small bug because probably variable @Devices should be 1 line below:

"-s #{dimensions}",
"-f x11grab",
"-i :#{@display}",
@devices,
group_of_pic_size_option,
"-vcodec #{@codec}",

could you check it and fix?
Thank you!

ffmpeg issue on Mac

I'm getting the following error with the video: { log_file_path: STDERR} option

Unknown input format: 'x11grab'

This page seems to suggest that avfoundation should be used instead on mac.
Homebrew/legacy-homebrew#17641

Any ideas on how to fix this?

Allow to use Xvfb started as root

I see from spec that if Xvfb is started by another user, headless won't use this connection and wonder why. In my case, Xvfb is started as service and I'd like headless to just use it. Are there any pitfalls I'm not aware of?

Using headless in a multithreaded program

I am trying to use headless in a program with SuckerPunch were each job independently accesses different websites using watir/selenium/chrome. Kicking off a single job works fine, but I begin to experience reliability issues if I try to run more than one job concurrently. Is headless able to be used in this manner? I followed your instructions for shared use via "forking", but if by that you meant creating separate processes, then that might explain my issue. In any event, can headless be used by multiple threads withing the same process, and if so, what is the proper usage pattern?

Thanks.

Few ideas

Hello,

I have a few things about the headless gem and video recording.

  1. How can I hide the mouse cursor?
  2. In method stop_and_save in VideoRecorder class good option is add mkdir_p before mv
def stop_and_save(path)
  Recorder::CliUtil.kill_process(@pid_file_path, :wait => true)
  if File.exists? @tmp_file_path
    begin
      **FileUtils.mkdir_p(File.dirname(path))**
      FileUtils.mv(@tmp_file_path, path)
    rescue Errno::EINVAL
      nil
    end
  end
end

what do you think?

  1. In method command_line_for_capture in VideoRecorder class is a small bug:

Before (look on @Devices position in array):

[
 CliUtil.path_to(provider_binary_path),
 "-y",
 "-r #{@frame_rate}",
 "-s #{dimensions}",
 "-f x11grab",
@devices,
 "-i :#{@display}",
 group_of_pic_size_option,
 "-vcodec #{@codec}",
 @extra,
 @tmp_file_path
].flatten.compact.join(' ')

After:

[
 CliUtil.path_to(provider_binary_path),
 "-y",
 "-r #{@frame_rate}",
 "-s #{dimensions}",
 "-f x11grab",
 "-i :#{@display}",
 @devices,
 group_of_pic_size_option,
 "-vcodec #{@codec}",
 @extra,
 @tmp_file_path
].flatten.compact.join(' ')

Could you fix it?

  1. Good idea is add something like post_processing_video method or yield that will be triggered in method stop_and_save before FileUtils.mv(@tmp_file_path, path) command. For instance:
def stop_and_save(path, &block)
  Recorder::CliUtil.kill_process(@pid_file_path, :wait => true)
  if File.exists? @tmp_file_path
    begin
      FileUtils.mkdir_p(File.dirname(path))
      yield(@tmp_file_path) if block_given?
      FileUtils.mv(@tmp_file_path, path)
    rescue Errno::EINVAL
      nil
    end
  end
end

This solution will be very helpful for add watermark or other operation after recording.
What do you think?

  1. Last one question: how can I stop recording from bash or external script if I know screen number?

Best Regards
Peter

Xvfb is frozen

Sometimes I receive this message when running rspec. And the only fix is to restart the computer.

I don't know the root cause yet, but running the Xvfb command headless runs without redirection, I get the following error:

➜ /opt/X11/bin/Xvfb :66636 -screen 0 1280x1024x24 -ac
_XSERVTransMakeAllCOTSServerListeners: failed to create listener for inet6
_XSERVTransMakeAllCOTSServerListeners: failed to create listener for inet
_XSERVTransmkdir: ERROR: euid != 0,directory /tmp/.X11-unix will not be created.
_XSERVTransSocketUNIXCreateListener: mkdir(/tmp/.X11-unix) failed, errno = 2
_XSERVTransMakeAllCOTSServerListeners: failed to create listener for local
(EE)
Fatal server error:
(EE) Cannot establish any listening sockets - Make sure an X server isn't already running(EE)

The manual solution is to run the following:

mkdir /tmp/.X11-unix
sudo chmod 1777 /tmp/.X11-unix
sudo chown root /tmp/.X11-unix/

Robust Cleanup

Headless should call headless.destroy in an ensure block within the run method so that it still cleans up if the yielded code raises an exception. Headless could also register an at_exit hook when a new Headless instance is instantiated to cleanup the process if it is still running when the Ruby process exits. Right now it's very easy for the Headless gem to leave Xvfb running.

dimensions not the same as what I've set

I'm using headless gem on a Debian Jessie 64bit machine and when I set the dimensions and take a screenshot with Capybara-screenshot the dimensions in the screenshot are vastly different to what I've set in the headless gem.

  headless = Headless.new(dimensions: '1920x1200x24',
                          display: xvfb_port,
                          video: {
                            frame_rate: 12,
                            provider: :ffmpeg
                          })

Here are my results.

|     headless | screenshot |
|   dimensions |     result |
|--------------+------------|
| 1920x1200x24 |   1424x941 |
| 1920x1024x24 |   1424x941 |
| 1600x1200x42 |   1225x989 |

Headless Video not saving.

I'm not able to save the video created by the headless gem. I'm including the relative snippets of my code and the output.

Code
$LOGGER.info("----------Starting test: #{@test_name}----------")

if Utilities.linux? && ENV['DRIVER'] != 'sauce'
  @headless = Headless.new ({dimension: '1600x1200x16',
                    pid_file_path: "#{Utilities.get_root_directory}/tmp/headless_ffmpeg_#{@display}.pid",
                    tmp_file_path: "#{Utilities.get_root_directory}/tmp/headless_ffmpeg_#{@display}.mov",
                    log_file_path: "#{Utilities.get_root_directory}/tmp/headless_ffmpeg_#{@display}.txt"})
  @headless.start
  @headless.video.start_capture
  $LOGGER.info 'Creating headless session.'
end
$browser = DefaultWatir.initiate_browser(@test_name)

if Utilities.linux? && ENV['DRIVER'] != 'sauce'
  $LOGGER.info "Starting video recording"
  @headless.video.start_capture
end

.........          .........
......... TEST RUN .........
.........          .........

$LOGGER.info "----------Ending test: #{@test_name}----------"
 puts "\n\n"

$browser.close if $browser
save_video if @headless

def video_path
  return "#{Utilities.get_root_directory}/video/#{@test_name}_#{Time.now.to_s.gsub(' ', '-')}"
end

def save_video
  if Utilities.linux?  && ENV['DRIVER'] != 'sauce'
    unless self.instance_variable_get(:@exception).nil? && !$has_errors
      saved_video_path = video_path
      Dir.mkdir("#{Utilities.get_root_directory}/video") unless Dir.exists?("#{Utilities.get_root_directory}/video")
      $LOGGER.info "Video path = #{saved_video_path}"
      begin
        $LOGGER.info 'before save'
        @headless.video.stop_and_save(saved_video_path)
        $LOGGER.info 'after save'
      rescue ex
        $LOGGER.info 'Video save had exception.'
        puts ex.message
        puts ex.backtrace.join("\n\t")
      end
      $LOGGER.info "Video saved at: #{saved_video_path}"
    else
      @headless.video.stop_and_discard
    end
    @headless.destroy
  end
end
Output

[INFO - 2015-03-06 21:58:37 +0000] - ----------Starting test: Example Test----------
[INFO - 2015-03-06 21:58:37 +0000] - Creating headless session.
[INFO - 2015-03-06 21:58:40 +0000] - Starting video recording
[INFO - 2015-03-06 22:02:04 +0000] - ----------Ending test: Example Test----------
INFO - 2015-03-06 22:02:05 +0000] - Video path = /var/lib/jenkins/workspace/end_to_end_firefox/selenium-tests/video/PoolPlayToSingleEliminationOneDivision_2015-03-06-22:02:05-+0000
[INFO - 2015-03-06 22:02:05 +0000] - before save
[INFO - 2015-03-06 22:02:05 +0000] - after save
[INFO - 2015-03-06 22:02:05 +0000] - Video saved at: /var/lib/jenkins/workspace/end_to_end_firefox/selenium-tests/video/PoolPlayToSingleEliminationOneDivision_2015-03-06-22:02:05-+0000

Headless.new causing warning: unsupported spawn option: err

I'm having an issue using version 2.1.0 when running:

Headless.new

Gives me this error:

file:/var/lib/jenkins/.rvm/rubies/jruby-1.7.9/lib/jruby.jar!/jruby/kernel19/process.rb:14 warning: unsupported spawn option: err
Initializing built-in extension Generic Event Extension
Initializing built-in extension SHAPE
Initializing built-in extension MIT-SHM
Initializing built-in extension XInputExtension
Initializing built-in extension XTEST
Initializing built-in extension BIG-REQUESTS
Initializing built-in extension SYNC
Initializing built-in extension XKEYBOARD
Initializing built-in extension XC-MISC
Initializing built-in extension SECURITY
Initializing built-in extension XINERAMA
Initializing built-in extension XFIXES
Initializing built-in extension RENDER
Initializing built-in extension RANDR
Initializing built-in extension COMPOSITE
Initializing built-in extension DAMAGE
Initializing built-in extension MIT-SCREEN-SAVER
Initializing built-in extension DOUBLE-BUFFER
Initializing built-in extension RECORD
Initializing built-in extension DPMS
Initializing built-in extension X-Resource
Initializing built-in extension XVideo
Initializing built-in extension XVideo-MotionCompensation
Initializing built-in extension SELinux
Initializing built-in extension GLX
End of file reached (EOFError)
org/jruby/RubyIO.java:2856:in `read_nonblock'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:183:in `ensure_xvfb_is_running'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:174:in `launch_xvfb'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:159:in `pick_available_display'
org/jruby/RubyRange.java:479:in `each'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/activesupport-4.1.10/lib/active_support/core_ext/range/each.rb:7:in `each_with_time_with_zone'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:155:in `pick_available_display'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:151:in `attach_xvfb'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/headless-2.1.0/lib/headless.rb:88:in `initialize'
/var/lib/jenkins/jobs/_umv/jobs/_tests/jobs/umv-admin-functional-tests/workspace/admin_tests/features/support/env.rb:113:in `(root)'
org/jruby/RubyKernel.java:1099:in `load'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/rb_support/rb_language.rb:1:in `(root)'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/rb_support/rb_language.rb:129:in `load_code_file'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/runtime/support_code.rb:171:in `load_file'
org/jruby/RubyArray.java:1613:in `each'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/runtime/support_code.rb:83:in `load_files!'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/runtime/support_code.rb:82:in `load_files!'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/runtime.rb:175:in `load_step_definitions'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/runtime.rb:40:in `run!'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/cli/main.rb:43:in `execute!'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/../lib/cucumber/cli/main.rb:20:in `execute'
org/jruby/RubyKernel.java:1099:in `load'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/gems/cucumber-1.2.0/bin/cucumber:14:in `(root)'
org/jruby/RubyKernel.java:1119:in `eval'
/var/lib/jenkins/.rvm/gems/jruby-1.7.9@cirrus-new/bin/jruby_executable_hooks:15:in `(root)'

ChildProcess::TimeoutError

headless 1.0.2
selenium-webdriver 2.42.0

What other information can I provide? I am running headless via the instructions in the readme.

     ChildProcess::TimeoutError:
       process still alive after 90 seconds
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/childprocess-0.5.3/lib/childprocess/abstract_process.rb:152:in `poll_for_exit'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/binary.rb:47:in `wait'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/launcher.rb:71:in `start_silent_and_wait'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/launcher.rb:35:in `block in launch'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/socket_lock.rb:20:in `locked'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/launcher.rb:32:in `launch'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/firefox/bridge.rb:24:in `initialize'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/common/driver.rb:31:in `new'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver/common/driver.rb:31:in `for'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/selenium-webdriver-2.42.0/lib/selenium/webdriver.rb:67:in `for'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-1.1.4/lib/capybara/selenium/driver.rb:15:in `browser'
     # ./spec/acceptance/acceptance_helper.rb:23:in `block (2 levels) in <top (required)>'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_exec'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_eval_with_args'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:246:in `instance_eval_with_args'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:21:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:85:in `block in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:85:in `each'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:85:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:446:in `run_hook'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:467:in `run_before_each_hooks'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:293:in `run_before_each'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:115:in `block in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:183:in `call'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:183:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_exec'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_eval_with_args'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:246:in `instance_eval_with_args'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:106:in `block (2 levels) in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:108:in `call'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:108:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/hooks.rb:446:in `run_hook'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:462:in `run_around_each_hooks'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:255:in `with_around_each_hooks'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example.rb:113:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:514:in `block in run_examples'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:510:in `map'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:510:in `run_examples'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:495:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:496:in `block in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:496:in `map'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/example_group.rb:496:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/command_line.rb:24:in `block (2 levels) in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/command_line.rb:24:in `map'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/command_line.rb:24:in `block in run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/reporter.rb:58:in `report'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/command_line.rb:21:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/runner.rb:89:in `run'
     # /home/jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-2.99.0/lib/rspec/core/runner.rb:17:in `block in autorun'

How could I produce a fragmented mp4?

I've found that I can use the headless gem to create an mp4 like so:

  headless = Headless.new(video: {frame_rate: 12, codec: 'libx264'})
  headless.start
  headess.video.start_capture
  headless.stop_and_save("test.mp4")

And the mp4 file produces is playable.

How could I make this a fragmented mp4?

The readme shows that the following options are supported for the videos hash in Headless.new's options, but I'm not sure how to set them up:

:codec - codec to be used by ffmpeg
:frame_rate - frame rate of video capture
:provider - ffmpeg provider - either :libav (default) or :ffmpeg
:provider_binary_path - Explicit path to avconv or ffmpeg. Only required when the binary cannot be discovered on the system $PATH.
:pid_file_path - path to ffmpeg pid file, default: "/tmp/.headless_ffmpeg_#{@display}.pid"
:tmp_file_path - path to tmp video file, default: "/tmp/.headless_ffmpeg_#{@display}.mov"
:log_file_path - ffmpeg log file, default: "/dev/null"
:extra - array of extra ffmpeg options, default: []

The reason I want to make a fragmented mp4 is that it's streamable.

Argument list too long

I am having this bug every day morning. my delayed_job workers are stopping to proccess.
any idias with this, Why does this issue come?

shared/bundle/ruby/2.0.0/gems/activesupport-3.2.21/lib/active_support/core_ext/kernel/agnostics.rb:7:in ``'
shared/bundle/ruby/2.0.0/gems/activesupport-3.2.21/lib/active_support/core_ext/kernel/agnostics.rb:7:in ``'
shared/bundle/ruby/2.0.0/gems/headless-1.0.2/lib/headless/cli_util.rb:4:in `application_exists?'
shared/bundle/ruby/2.0.0/gems/headless-1.0.2/lib/headless/cli_util.rb:8:in `ensure_application_exists!'
shared/bundle/ruby/2.0.0/gems/headless-1.0.2/lib/headless.rb:68:in `initialize'
/lib/flight_parser/common/selenium_helper.rb:160:in `new'
/lib/flight_parser/common/selenium_helper.rb:160:in `headless'
/lib/flight_parser/asp/booking_base.rb:13:in `run'
/lib/flight_parser/flight_parser.rb:74:in `run_and_save'
/lib/jobs/datafile_base_parsing_job.rb:27:in `start_parser'
/lib/jobs/datafile_base_parsing_job.rb:10:in `perform'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/backend/base.rb:94:in `block in invoke_job'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `block in initialize'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `execute'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:38:in `run_callbacks'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/backend/base.rb:91:in `invoke_job'
(eval):3:in `block in invoke_job_with_newrelic_transaction_trace'
shared/bundle/ruby/2.0.0/gems/newrelic_rpm-3.5.8.72/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:268:in `block in perform_action_with_newrelic_trace'
shared/bundle/ruby/2.0.0/gems/newrelic_rpm-3.5.8.72/lib/new_relic/agent/method_tracer.rb:240:in `trace_execution_scoped'
shared/bundle/ruby/2.0.0/gems/newrelic_rpm-3.5.8.72/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:263:in `perform_action_with_newrelic_trace'
(eval):2:in `invoke_job_with_newrelic_transaction_trace'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:182:in `block (2 levels) in run'
/home/capistrano/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/timeout.rb:66:in `timeout'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:182:in `block in run'
/home/capistrano/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:181:in `run'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:238:in `block in reserve_and_run_one_job'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `block in initialize'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `execute'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:38:in `run_callbacks'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:238:in `reserve_and_run_one_job'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:166:in `block in work_off'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:165:in `times'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:165:in `work_off'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:133:in `block (4 levels) in start'
/home/capistrano/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:132:in `block (3 levels) in start'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `block in initialize'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `execute'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:38:in `run_callbacks'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:129:in `block (2 levels) in start'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:128:in `loop'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:128:in `block in start'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/plugins/clear_locks.rb:7:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/plugins/clear_locks.rb:7:in `block (2 levels) in '
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:78:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:78:in `block (2 levels) in add'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:60:in `block in initialize'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:78:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:78:in `block in add'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `call'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:65:in `execute'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/lifecycle.rb:38:in `run_callbacks'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/worker.rb:127:in `start'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/command.rb:101:in `run'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/command.rb:89:in `block in run_process'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/application.rb:255:in `call'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/application.rb:255:in `block in start_proc'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/daemonize.rb:82:in `call'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/daemonize.rb:82:in `call_as_daemon'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/application.rb:259:in `start_proc'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/application.rb:296:in `start'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/controller.rb:70:in `run'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons.rb:197:in `block in run_proc'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/cmdline.rb:109:in `call'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons/cmdline.rb:109:in `catch_exceptions'
shared/bundle/ruby/2.0.0/gems/daemons-1.1.9/lib/daemons.rb:196:in `run_proc'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/command.rb:87:in `run_process'
shared/bundle/ruby/2.0.0/gems/delayed_job-3.0.3/lib/delayed/command.rb:76:in `daemonize'
script/delayed_job:5:in `

draw_mouse 0 not working

Hi,

I would like to hide the mouse, but this seems "hard".
"draw_mouse 0" doesn't work as an option

any idea?

ffmpeg version 2.7.2 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
  libavutil      54. 27.100 / 54. 27.100
  libavcodec     56. 41.100 / 56. 41.100
  libavformat    56. 36.100 / 56. 36.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 16.101 /  5. 16.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.100 /  1.  2.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, x11grab, from ':99':
  Duration: N/A, start: 1439194295.218890, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1280x1024, 30 fps, 30 tbr, 1000k tbn, 30 tbc
[NULL @ 0x55ebccdeff20] Unable to find a suitable output format for 'draw_mouse'
draw_mouse: Invalid argument

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.