In ruby, I can't get byebug to work with selenium - ruby

require 'selenium-webdriver'
require 'byebug'
byebug
driver = Selenium::WebDriver.for:chrome
driver.navigate.to "http://google.com"
puts driver.find_element(:tag_name, 'input');
puts driver.find_element(:name, 'q');
driver.find_element(:name, 'q').send_keys("asdf");
#sleep 20
When I run the program, it goes straight to driver = Selenium::WebDriver.for:chrome
I hit 'n', then it loads Chrome, and goes to google and sends those keys into the input box and exits the program.
What I'd like to happen is that I hit 'n' it goes to driver.navigate.to "http://google.com". I hit 'n' again, it goes to puts driver.find_element(:tag_name, 'input');. And I would like from the console to run commands like driver.find_element.... But I can't because byebug isn't tracing through the program after the driver = Selenium::WebDriver.for:chrome line.
I want to be able to check out the DOM with Selenium from the console / irb / byebug
Added
A comment suggests using pry
So I tried require 'pry' and binding.pry. And 'next' rather than 'n'(as pry uses 'next'). Same problem.
And I tried require 'pry-byebug' and 'binding.pry' and 'next' rather than 'n'(as pry-byebug uses 'next'). Also same problem.
On rs's suggestion, I tried require 'pry' and require 'pry-byebug' and binding.pry(to halt). And tried step rather than next. Also, same problem. I have now added output of this.
Added Further
Apples-MBP:rubyselenium1 apple$ cat selenium12.rb
# https://stackoverflow.com/questions/53962313/in-ruby-i-cant-get-byebug-to-work-with-selenium?noredirect=1#comment94763217_53962313
require 'selenium-webdriver'
require 'pry'
require 'pry-byebug'
binding.pry
driver = Selenium::WebDriver.for:chrome
driver.navigate.to "http://google.com"
puts driver.find_element(:tag_name, 'input');
puts driver.find_element(:name, 'q');
driver.find_element(:name, 'q').send_keys("asdf");
#sleep 20
Apples-MBP:rubyselenium1 apple$ ruby selenium12.rb
WARN: Unresolved specs during Gem::Specification.reset:
ffi (>= 1.0.11, ~> 1.0)
WARN: Clearing out unresolved specs.
Please report a bug if this causes problems.
From: /Users/apple/rubyselenium1/selenium12.rb # line 9 :
4: require 'pry'
5: require 'pry-byebug'
6:
7: binding.pry
8:
=> 9: driver = Selenium::WebDriver.for:chrome
10:
11: driver.navigate.to "http://google.com"
12:
13: puts driver.find_element(:tag_name, 'input');
14: puts driver.find_element(:name, 'q');
[1] pry(main)> step
From: /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver.rb # line 86 Selenium::WebDriver.for:
85: def self.for(*args)
=> 86: WebDriver::Driver.for(*args)
87: end
[1] pry(Selenium::WebDriver)> step
From: /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/driver.rb # line 42 Selenium::WebDriver::Driver.for:
41: def for(browser, opts = {})
=> 42: case browser
43: when :chrome
44: Chrome::Driver.new(opts)
45: when :internet_explorer, :ie
46: IE::Driver.new(opts)
47: when :safari
48: Safari::Driver.new(opts)
49: when :phantomjs
50: PhantomJS::Driver.new(opts)
51: when :firefox, :ff
52: Firefox::Driver.new(opts)
53: when :edge
54: Edge::Driver.new(opts)
55: when :remote
56: Remote::Driver.new(opts)
57: else
58: raise ArgumentError, "unknown driver: #{browser.inspect}"
59: end
60: end
[1] pry(Selenium::WebDriver::Driver)> step
From: /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/driver.rb # line 44 Selenium::WebDriver::Driver.for:
41: def for(browser, opts = {})
42: case browser
43: when :chrome
=> 44: Chrome::Driver.new(opts)
45: when :internet_explorer, :ie
46: IE::Driver.new(opts)
47: when :safari
48: Safari::Driver.new(opts)
49: when :phantomjs
50: PhantomJS::Driver.new(opts)
51: when :firefox, :ff
52: Firefox::Driver.new(opts)
53: when :edge
54: Edge::Driver.new(opts)
55: when :remote
56: Remote::Driver.new(opts)
57: else
58: raise ArgumentError, "unknown driver: #{browser.inspect}"
59: end
60: end
[1] pry(Selenium::WebDriver::Driver)> step
From: /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb # line 40 Kernel#require:
35: #
36: # The normal <tt>require</tt> functionality of returning false if
37: # that file has already been loaded is preserved.
38:
39: def require path
=> 40: RUBYGEMS_ACTIVATION_MONITOR.enter
41:
42: path = path.to_path if path.respond_to? :to_path
43:
44: if spec = Gem.find_unresolved_default_spec(path)
45: Gem.remove_unresolved_default_spec(spec)
[1] pry(main)> step
From: /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb # line 184 MonitorMixin#mon_enter:
183: def mon_enter
=> 184: if #mon_owner != Thread.current
185: #mon_mutex.lock
186: #mon_owner = Thread.current
187: #mon_count = 0
188: end
189: #mon_count += 1
190: end
[1] pry(#<Monitor>)> step
From: /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb # line 185 MonitorMixin#mon_enter:
183: def mon_enter
184: if #mon_owner != Thread.current
=> 185: #mon_mutex.lock
186: #mon_owner = Thread.current
187: #mon_count = 0
188: end
189: #mon_count += 1
190: end
[1] pry(#<Monitor>)> step
before_session hook failed: ThreadError: deadlock; recursive locking
/usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb:185:in `lock'
(see _pry_.hooks.errors to debug)
[1] pry(#<Monitor>)>
Traceback (most recent call last):
29: from selenium12.rb:9:in `<main>'
28: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver.rb:86:in `for'
27: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/driver.rb:44:in `for'
26: from /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:40:in `require'
25: from /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb:186:in `mon_enter'
24: from /usr/local/lib/ruby/gems/2.5.0/gems/byebug-10.0.2/lib/byebug/context.rb:98:in `at_line'
23: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:63:in `at_line'
22: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:111:in `resume_pry'
21: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:27:in `run'
20: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:27:in `catch'
19: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:28:in `block in run'
18: from /usr/local/lib/ruby/gems/2.5.0/gems/byebug-10.0.2/lib/byebug/helpers/eval.rb:94:in `allowing_other_threads'
17: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:28:in `block (2 levels) in run'
16: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-byebug-3.6.0/lib/byebug/processors/pry_processor.rb:113:in `block in resume_pry'
15: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/pry_instance.rb:348:in `repl'
14: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:38:in `start'
13: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/input_lock.rb:79:in `with_ownership'
12: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/input_lock.rb:61:in `__with_ownership'
11: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:38:in `block in start'
10: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:67:in `repl'
9: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:67:in `loop'
8: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:68:in `block in repl'
7: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/repl.rb:108:in `read'
6: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/indent.rb:394:in `correct_indentation'
5: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/terminal.rb:8:in `screen_size'
4: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/terminal.rb:33:in `actual_screen_size'
3: from /usr/local/lib/ruby/gems/2.5.0/gems/pry-0.11.3/lib/pry/terminal.rb:47:in `screen_size_according_to_io_console'
2: from /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:40:in `require'
1: from /usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb:185:in `mon_enter'
/usr/local/Cellar/ruby/2.5.0/lib/ruby/2.5.0/monitor.rb:185:in `lock': deadlock; recursive locking (ThreadError)
Apples-MBP:rubyselenium1 apple$
Apples-MBP:rubyselenium1 apple$

This gem "Adds step-by-step debugging and stack navigation capabilities to pry using byebug." {quoted from pry-byebug}, So you need pry and byebug both inorder to use pry byebug. So ensure both gems are installed: you can add both gems to your GemFile and do bundle install or just do that directly, after that you should require both and then add binding.pry execution will stop at the first statment after that.
"The aliases 'n', 's', 'c' and 'f' were removed by default because they usually conflict with scratch variable names. But it's very easy to reenable them if you still want them, just add the following shortcuts to your ~/.pryrc file:"
if defined?(PryByebug)
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
end
More detailed info in the link i provided above, hope this helps.
added by barlop
rs comments that questioner try require pry and require pry-byebug and halt with binding.pry

The following is a partial answer. It doesn't solve the pry / byebug / pry-byebug issue, but it does address this part,
One of the things the question asks is
"I want to be able to check out the DOM with Selenium from the console
/ irb / byebug"
Code using Selenium does run OK typed straight into irb
$ irb
irb(main):001:0> require 'selenium-webdriver'
=> true
irb(main):011:0> driver = Selenium::WebDriver.for:firefox
=> #<Selenium::WebDriver::Firefox::Marionette::Driver:0x..fcead308af2433ac2 browser=:firefox>
irb(main):013:0> driver.navigate().to("http://www.google.com")
=> nil
irb(main):036:0> inps=driver.find_elements(:tag_name, "input");
=> [#<Selenium::WebDriver::Element:0x..f8ed35db92a849eea id="dac....
irb(main):041:0> inps[2].attribute('name');
=> "q"
irb(main):042:0> inps[2].attribute('value');
=> "" <-- shows whatever is typed in that google search box eg prior to checking the value we could've typed something e.g. 'asdf' into it manually or programmatically eg driver.find_element(:tag_name, "input").send_keys("asdf"); and it will show "asdf".

Related

Stack trace showing ERB syntax error. Is the problem with app code or ERB library?

I'm working through an ERB chapter from a Lynda.com course, Ruby Essential Training Part 3: Files, Formats, Templates, and keep getting a syntax error in what appears to be ERB itself. When I enter this code:
#!/usr/bin/env ruby
#### Mail Merge ####
#
# Launch this Ruby file from the command line
# to get started
#
require 'erb'
require 'csv'
APP_ROOT = File.expand_path(File.dirname(__FILE__))
# files in current dir
template_path = File.join(APP_ROOT, 'letter_template.txt')
csv_path = File.join(APP_ROOT, 'us_presidents.csv')
template = File.read(template_path)
i = 0
CSV.foreach(csv_path) do |row|
next if row[0].start_with?('Number') # Header row
i += 1
#last_name = row[1]
#first_name = row[2]
state = row[6]
end_date = row[4] || Time.now.year
#title = "The History of #{state}"
#due_date = end_date
years = Time.now.year - #due_date.to_i
#fee = "$#{years * 365}.00"
letter = ERB.new(template).result(binding)
num = i < 10 ? "0#{i}" : i
filename = "letter_#{num}.txt"
filepath = File.join('letters', filename)
puts "-------"
puts filepath
puts letter
File.write(filepath, letter)
end
I get this error message:
Traceback (most recent call last):
15: from init.rb:20:in `<main>'
14: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv.rb:510:in `foreach'
13: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv.rb:658:in `open'
12: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv.rb:511:in `block in foreach'
11: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv.rb:1280:in `each'
10: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv.rb:1280:in `each'
9: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:336:in `parse'
8: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:823:in `parse_quotable_loose'
7: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:49:in `each_line'
6: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:49:in `each_line'
5: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:52:in `block in each_line'
4: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:871:in `block in parse_quotable_loose'
3: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/csv/parser.rb:1122:in `emit_row'
2: from init.rb:34:in `block in <main>'
1: from /Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/erb.rb:905:in `result'
/Users/andrekibbe/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/erb.rb:905:in `eval': (erb):6: syntax error, unexpected '=', expecting end-of-input (SyntaxError)
; = #due_date ; _erbout.<< "\\n\\n...**
Everything in the stack trace references CSV and ERB lines, so I can't see anything I can correct on my end. Am I missing something?
Update: letter_template.rb added:
Dear <%= #first_name %> <%= #last_name %>,
The following library book is overdue.
"<%= #title %>"
Due: <% = #due_date %>
Overdue fee: <%= #fee %>
Thank you for your prompt attention to this matter.
The stack trace shows lines from ERb because ERb code is the one that is executing.
While the issue could theoretically be in either ERb itself or your template, it is much more likely that the issue is in your template given that ERb is used by thousands of developers and applications daily.

How to increase the number of lines around binding.pry?

Using the gem pry-byebug, when I add a binding.pry somewhere, it shows only 5 lines around the line that I am:
157: max_bytes: limits_config.max_read_bytes_per_parser,
158: max_reads: limits_config.max_reads_per_parser,
159: max_seeks: limits_config.max_seeks_per_parser
160: )
161:
=> 162: results = parsers.lazy.map do |parser|
163: # Reset all the read limits, per parser
164: limited_io.reset_limits!
165: read_limiter_under_cache.reset_limits!
166:
167: # We need to rewind for each parser, anew
Is there a way to increase this number to show more lines of code?
Use whereami with an integer argument specifying the number of lines to return.
For example, given the file foo.rb:
# foo.rb
require 'pry'
def foo; end
def bar; end
def foobar
# do something
binding.pry
# do something else
end
def baz; end
def foobarbaz; end
foobar
Run it with ruby foo.rb:
From: /Users/foo/foo.rb:11 Object#foobar:
9: def foobar
10: # do something
=> 11: binding.pry
12: # do something else
13: end
⇒
And ask to see +/- 10 lines with whereami 10:
⇒ whereami 10
From: /Users/foo/foo.rb:11 Object#foobar:
1: # foo.rb
2:
3: require 'pry'
4:
5: def foo; end
6:
7: def bar; end
8:
9: def foobar
10: # do something
=> 11: binding.pry
12: # do something else
13: end
14:
15: def baz; end
16:
17: def foobarbaz; end
18:
19: foobar
⇒
Or just the two surrounding lines with whereami 1:
⇒ whereami 1
From: /Users/foo/foo.rb:11 Object#foobar:
10: # do something
=> 11: binding.pry
12: # do something else
⇒

Sample server & client for Rack hijack proxy questions

I've got sample app for hijack proxy server
io_lambda = lambda{ |io|
3.times do |i|
puts i
io.write "David\r\n"
end
io.close
}
run lambda{ |req|
[
200,
[ [ "rack.hijack", io_lambda ] ],
[""]
]
}
and starting it
rackup config.ru -p 3000
Now I trying to code client for it. First, just curl it:
curl http://localhost:3000 -vv
and get following client output:
* Rebuilt URL to: http://localhost:3000/
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
<
David
David
* transfer closed with outstanding read data remaining
* stopped the pause stream!
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining
now, with httparty:
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)
response = HTTParty.get('http://localhost:3000')
puts response.body, response.code, response.message, response.headers.inspect
I get:
→ ruby httparty-client.rb
Traceback (most recent call last):
19: from httparty-client.rb:5:in `<main>'
18: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:627:in `get'
17: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:508:in `get'
16: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:594:in `perform_request'
15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty/request.rb:145:in `perform'
14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1470:in `request'
13: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1472:in `block in request'
11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:166:in `reading_body'
8: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:229:in `body'
7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
last try with net/http:
require 'net/http'
streamURL = 'http://localhost:3000'
uri = URI.parse(streamURL)
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri.request_uri
http.request request do |response|
response.read_body do |chunk|
#We get the data here chunk-by-chunk
puts chunk
end
end
end
I get:
→ ruby net-http-client.rb
David
David
David
David
Traceback (most recent call last):
16: from net-http-client.rb:7:in `<main>'
15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
13: from net-http-client.rb:10:in `block in <main>'
12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:165:in `reading_body'
9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1518:in `block in transport_request'
8: from net-http-client.rb:11:in `block (2 levels) in <main>'
7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
Could someone explain me:
1) Why curl return David x2, httparty - nothing and net/http - David x4, while server sent 5? Also I'm curious why httparty and net/http results differ, because one uses another under the hood.
2) Why in all cases we have an error (transfer closed with outstanding read data remaining and end of file reached (EOFError))?
Have figured it out. Headers do matter. This version makes it work for all clients
io_lambda = lambda{ |io|
5.times do |i|
puts i
io.write "David\r\n"
sleep 1
end
io.close
}
app = lambda do |env|
response_headers = {}
response_headers['Transfer-Encoding'] = 'binary'
response_headers["Content-Type"] = "text/plain"
response_headers["rack.hijack"] = io_lambda
[200, response_headers, nil]
end
run app

Ruby - Capybara recording test execution videos

I am trying to record and save in a video format my execution tests using Capybara. My tests are passing however I'm getting several errors in my Mac terminal. Also the videos are not being recorded/saved.
SPEC_HELPER.RB
require 'capybara'
require 'capybara/rspec'
require 'capybara/dsl'
require 'selenium-webdriver'
require 'headless'
headless = Headless.new
headless.start
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.include Capybara::DSL
config.before(:example) do
headless.video.start_capture
page.current_window.resize_to(1200, 800)
end
config.after(:example) do |e, scenario|
name = e.description.gsub(/[^A-Za-z0-9 ]/, '').tr(' ', '_')
d = Time.now.strftime("%F-%T")
page.save_screenshot('log/' + name + '-' + d.to_s + '.png')
headless.video.stop_and_save('log/' + name + '-' + d.to_s + '.mov')
end
end
Capybara.configure do |config|
config.default_driver = :selenium_chrome_headless
config.run_server = false
end
Capybara.default_max_wait_time = 10
MAC TERMINAL ERROR
Finished in 19.68 seconds (files took 0.82221 seconds to load)
4 examples, 0 failures
Traceback (most recent call last):
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:374:in `block in setup_exit_handler'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:208:in `quit'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/chrome/driver.rb:62:in `quit'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
Traceback (most recent call last):
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:374:in `block in setup_exit_handler'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:208:in `quit'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/chrome/driver.rb:62:in `quit'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
12: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/platform.rb:141:in `block in exit_hook'
11: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:67:in `block in start'
10: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:77:in `stop'
9: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:128:in `stop_server'
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:104:in `connect_to_server'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:919:in `start'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:930:in `do_start'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:945:in `connect'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/timeout.rb:103:in `timeout'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:946:in `block in connect'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:949:in `rescue in block in connect': Failed to open TCP connection to 127.0.0.1:9515 (Connection refused - connect(2) for "127.0.0.1" port 9515) (Errno::ECONNREFUSED)
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/platform.rb:141:in `block in exit_hook'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:67:in `block in start'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `ensure in stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
Try replacing these lines
page.save_screenshot('log/' + name + '-' + d.to_s + '.png')
headless.video.stop_and_save('log/' + name + '-' + d.to_s + '.mov')
With
#please note for this ../ from this file to root just reach to root of the project. in my case root
root_path = File.join(File.dirname(__FILE__), "../")
page.save_screenshot(File.join(root_path,'log/' + name + '-' + d.to_s + '.png'))
headless.video.stop_and_save(File.join(root_path,'log/' + name + '-' + d.to_s + '.mov'))
my searching show that Mac is not compatible with Xvfb which is something that Headless uses. Even if you get pass the rails error, you might not pass this one.

Ruby: run irb from trap context?

The following example is given in the book Programming Ruby 1.9 & 2.0:
require 'irb'
trap "INT" do
IRB.start
end
count = 0
loop do
count += 1
puts count
puts "Value = #{#value}" if defined? #value
sleep 1
end
Unfortunately, if I run this code with my Ruby 2.5.1 setup I get the following ThreadError (run_irb.rb is the name of the file with the code above):
24: from run_irb.rb:8:in `<main>'
23: from run_irb.rb:8:in `loop'
22: from run_irb.rb:12:in `block in <main>'
21: from run_irb.rb:12:in `sleep'
20: from run_irb.rb:4:in `block in <main>'
19: from /usr/lib/ruby/2.5.0/irb.rb:376:in `start'
18: from /usr/lib/ruby/2.5.0/irb/init.rb:17:in `setup'
17: from /usr/lib/ruby/2.5.0/irb/init.rb:112:in `init_config'
16: from /usr/lib/ruby/2.5.0/irb/init.rb:112:in `new'
15: from /usr/lib/ruby/2.5.0/irb/locale.rb:32:in `initialize'
14: from /usr/lib/ruby/2.5.0/irb/locale.rb:108:in `load'
13: from /usr/lib/ruby/2.5.0/irb/locale.rb:124:in `find'
12: from /usr/lib/ruby/2.5.0/irb/locale.rb:145:in `search_file'
11: from /usr/lib/ruby/2.5.0/irb/locale.rb:157:in `each_localized_path'
10: from /usr/lib/ruby/2.5.0/irb/locale.rb:167:in `each_sublocale'
9: from /usr/lib/ruby/2.5.0/irb/locale.rb:158:in `block in each_localized_path'
8: from /usr/lib/ruby/2.5.0/irb/locale.rb:150:in `block in search_file'
7: from /usr/lib/ruby/2.5.0/rubygems.rb:213:in `try_activate'
6: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `find_by_path'
5: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `find'
4: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `each'
3: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1064:in `block in find_by_path'
2: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:40:in `require'
1: from /usr/lib/ruby/2.5.0/monitor.rb:185:in `mon_enter'
/usr/lib/ruby/2.5.0/monitor.rb:185:in `lock': can't be called from trap context (ThreadError)
Is there a way to get the irb run from the trap context with Ruby 2.5.1?
Ruby 2.0 does not allow Mutex#lock within a signal handler
According to this bug 7917 in ruby lang this is the "expected" behaviour. So you've basically found a language bug and a book bug because the author didn't test this example in ruby 2.0 (confirmed that it works in 1.9.)
An alternative method is to use an exception/rescue and execute an IRB session from an interrupt like this:
require 'irb'
count = 0
loop do
count += 1
puts count
puts "Value = #{#value}" if defined? #value
sleep 1
rescue Interrupt => e
IRB.start
break
end
The above will correctly trap an interrupt and allow an IRB session to start. I did notice that IRB.start won't give you a local execution context, so you may want to look at binding.irb that let's you start a more useful debugging session like this:
$ ruby thread-test.rb
1
2
^C
[1] irb(main)>
From: /work/_scratch/thread-test/thread-test.rb # line 11 :
6: puts count
7: puts "Value = #{#value}" if defined? #value
8: sleep 1
9: rescue Interrupt => e
10: binding.irb
=> 11: break
12: end
[2] irb(main)> e
=> Interrupt
[3] irb(main)> count
=> 2
I found a few blog posts on handling Signals, Traps, and Rescues and Graceful Shutdown that may help you further with your problem.

Resources