I would like to write an application in Ruby using Qt which will communicate over the network with other instances.
How can I integrate Qt's event loop with DRb or EventMachine?
EDIT:
I found the answer when I will have more time I will post it
require 'eventmachine'
require 'Qt4'
app = Qt::Application.new(ARGV)
hello_button = Qt::PushButton.new("Hello EventMachine")
hello_button.resize(100,20)
hello_button.show
EventMachine.run do
EM.add_periodic_timer(0.01) do
app.process_events
end
end
Related
I'm trying to communicate with CoinEx (cryptocurrency exchange) API via WebSocket using Ruby 2.6. I have the following code:
require 'faye/websocket'
require 'eventmachine'
url = 'wss://socket.coinex.com/'
# url = 'wss://stream.binance.com:9443/ws/ltcbtc#miniTicker'
EM.run do
ws = Faye::WebSocket::Client.new(url)
ws.on :open do |event|
p [:open]
...
end
ws.on :message do |event|
p [:message]
...
end
ws.on :close do |event|
p [:close, event.code, event.reason]
...
end
end
When I run this code, I always see [:close, 1006, ""] immediately, without [:open]. I hacked deeply into gems (faye/websocket and eventmachine) and added some debug output to have better understanding of what is going on. Now my traceback is as follows:
/home/chernish2/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/faye-websocket-0.10.9/lib/faye/websocket/client.rb:87:in `unbind'
/home/chernish2/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:1483:in `event_callback'
/home/chernish2/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run_machine'
/home/chernish2/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run'
/home/chernish2/soft/trader2/test/ws_test.rb:36:in `<main>'
emit_error(), message=Errno::ENETUNREACH
[:close, 1006, ""]
Which really doesn't make any sense to me since another URL
url = 'wss://stream.binance.com:9443/ws/ltcbtc#miniTicker'
works just fine, and when I'm using https://github.com/altangent/ccxws library (nodejs) it connects to CoinEx using exactly the same URL as in my code without any troubles which means I don't have problems connecting to CoinEx WS endpoint.
So what is wrong with my code? Thank you in advance!
Oh, it is working now, without any changes from my side. Seems like there was some problems on the server side.
PROBLEM SOLVED:
I've figured out how to solve my problem:
in the before hook I fork the current process to start my sinatra web app:
Before do
if $pid.nil?
$pid = fork do
App.run!
end
end
end
Notice I have to have the forked PID attributed to a global variable so it doesnt get flushed after each scenario in cucumber. Besides that, I make sure to start my sintra app once in the entire cucumber execution.
Then at the end of my cucumber execution, I kill the child process and wait for it to be cleared prior to terminating the cucumber session:
at_exit do
unless $pid.nil?
Process.kill "TERM", $pid
Process.wait $pid
end
end
ORIGINAL QUESTION:
I am looking to stub a web app which contain content that will then be used by my application to fetch that content from that stub and do its trick...
What I am looking to achieve is start Sinatra app within cucumber hook... then stop it at end of execution... is that possible?
Below is where I've got so far...
#myapp.rb
require 'sinatra'
class App < Sinatra::Base
set :server, 'webrick'
get '/' do
'Hello!!!'
end
end
Then in hook:
Before do
App.run!
end
The first issue there is that the sinatra app won't run in the background... after solving that problem then I would need to understand if it's easy enough to stop the sinatra session as well...
I am automating test cases for a website using selenium-webdriver and cucumber in ruby. I need each feature to run in a particular order and using the same browser window. Atm each feature creates a new window to run test in. Though in some test cases this behavior is desired- in many cases it is not. From my research so far it seems there are mixed answers about whether or not it is possible to drive the same browser window with selenium throughout test cases. Most answers I have run into were for other languages and were work arounds specific to a browser (I am developing my test while testing IE but will be expected to run these test in other browsers). I am working in Ruby and from what I have read it seems as though I'd have to make a class for the page? I'm confused as to why I would have to do this or how that helps.
my env.rb file:
require 'selenium-webdriver'
require 'rubygems'
require 'nokogiri'
require 'rspec/expectations'
Before do
#driver ||= Selenium::WebDriver.for :ie
#accept_next_alert = true
#driver.manage.timeouts.implicit_wait = 30
#driver.manage.timeouts.script_timeout = 30
#verification_errors = []
end
After do
##driver.quit
##verification_errors.should == []
end
Some information I've gathered so far of people with similar problems:
https://code.google.com/p/selenium/issues/detail?id=18
Is there any way to attach an already running browser to selenium webdriver in java?
Please ask me questions if anything about my question is not clear. I have many more test to create but I do not want to move on creating test if my foundation is sloppy and missing requested capabilities. (If you notice any other issues within my code please point them out in a comment)
The Before hook is run before each scenario. This is why a new browser is opened each time.
Do the following instead (in the env.rb):
require "selenium-webdriver"
driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []
Before do
#driver = driver
end
at_exit do
driver.close
end
In this case, a browser will be opened at the start (before any tests). Then each test will grab that browser and continue using it.
Note: While it is usually okay to re-use the browser across tests. You should be careful about tests that need to be run in a specific order (ie become dependent). Dependent tests can be hard to debug and maintain.
I had a similar problem in creating a spec_helper file. I did the following (simplified for locally-run firefox) for my purposes and it works very, very reliably. RSpec will use the same browser window for all it blocks in your _spec.rb file.
Rspec.configure do |config|
config.before(:all) do
#driver = Selenium::WebDriver.for :firefox
end
config.after(:all) do
#driver.quit
end
end
If you switch to :each instead of :all, you can use a separate browser instance for each assertion block... again, with :each RSpec will give a new browser instance for each it. Both are useful depending on the circumstance.
As the answers solve the problem but do not answer the question "How to connect to an existing session".
I managed to do this with the following code since it is not officially supported.
# monkey-patch 2 methods
module Selenium
module WebDriver
class Driver
# Be able to set the driver
def set_bridge_to(b)
#bridge = b
end
# bridge is a private method, simply create a public version
def public_bridge
#bridge
end
end
end
end
caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")
driver = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
used_bridge = driver.bridge
driver.get('https://www.google.com')
# opens a new unused chrome window
driver2 = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
driver2.close() # close unused chrome window
driver2.set_bridge_to(used_bridge)
driver2.title # => "Google"
Sadly this did not test work between 2 rescue jobs, will update this in the future when I made it work for my own use case.
I am trying to scrape a web page with a lot of javascript. with the help of pguardiano i have this piece of code in ruby.
require 'rubygems'
require 'watir-webdriver'
require 'csv'
#browser = Watir::Browser.new
#browser.goto 'http://www.oddsportal.com/matches/soccer/'
CSV.open('out.csv', 'w') do |out|
#browser.trs(:class => /deactivate/).each do |tr|
out << tr.tds.map(&:text)
end
end
The scraping is done recursively in background with a sleep time of 1 hour approximatively. I have no experience of ruby and in particular of web scraping, so i have a couple of questions.
How can i avoid that every time a new firefox session is opened with a lot of cpu and ram consumption?
Is it possible to use a firefox engine without using his GUI?
You can try a headless option.
require 'watir-webdriver'
require 'headless'
headless = Headless.new
headless.start
b = Watir::Browser.start 'www.google.com'
puts b.title
b.close
headless.destroy
An alternative is to use the selenium server. A third alternative is to use a scraper like Kapow.
I starting to work with Ruby and Soap and had some questions:
How do I generate a WSDL file for the service I created?
Will it be compatible with an .NET client ?
begin
class MyServer < SOAP::RPC::StandaloneServer
# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
# Expose our services
def initialize(*args)
add_method(self, 'add', 'a', 'b')
add_method(self, 'div', 'a', 'b')
end
end
server = MyServer.new("MyServer",
'urn:ruby:calculation', 'localhost', 8080)
trap('INT'){
server.shutdown
}
server.start
rescue => err
puts err.message
end
ActionWebService (previously in Rails core, now a gem) has tools to generate WSDL files. You can use the tools even if you're not running your service within Rails.
http://www.datanoise.com/articles/2008/7/2/actionwebservice-is-back
As for whether it will work with a .NET client, the answer is maybe. Many .NET clients seem to expect Microsoft's "extended" SOAP info, which .NET webservices provide by default. If the client is also able to consume a service without that extra stuff, then sure.
UPDATE #1
The above link no longer appears to work. There are however forks of ActionWebService that have popped up over on github. You can see a pretty good list of them here. Here are a couple of links to some key versions:
original datanoise version
clevertechru's port, works w/ Rails 3.1.* & Ruby 1.9