wxruby and rubymsn - ruby

I'm currently playing with wxRuby and RubyMSN to learn to program desktop-programs. I know it is a hard task instead of just crating a notepad etc, but I need a bigger task than a notepad.
I now do manage to use them by them self, but I cant get them to work together. The problem is the loop.
RubyMSN wants to have an endless loop like
while true
sleep 1
end
or using the GUI's mainloop or something
I currently have this code as the loop
TheApp.new.main_loop()
while true
sleep 1
end
I have my window working, and the main_loop doing something. But I cant log in, it's like I doesn't have any loop (from the tutorial), I only get one debug line. But as soon as I close the window and lets the endless loop do it's job it works like a charm.
Someone ?

Worked for me. Try this: copy the minimal sample from the wxruby distribution, and modify minimal.rb so that you start your msn thread just before the wx main loop:
require 'msn/msn'
conn = MSNConnection.new("rubybot#channelwood.org", "secretpassword123")
conn.start
# Wx::App is the container class for any wxruby app. To start an
# application, either define a subclass of Wx::App, create an instance,
# and call its main_loop method, OR, simply call the Wx::App.run class
# method, as shown here.
Wx::App.run do
self.app_name = 'Minimal'
frame = MinimalFrame.new("Minimal wxRuby App")
frame.show
end
You'll need to symlink the msn directory inside the minimal directory to get the require statement working, of course.
You don't need the while true {sleep 1} loop; that's just to prevent the program from exiting so that your msn thread can keep running. The wx main loop accomplishes the same purpose.

Related

Pause an "until" loop and wait for a keypress to continue (Ruby)

I have a method with an until loop that keeps calling another method until a third method returns true. This is basically checking to see if a puzzle is solved.
def call_loop
until solved? #returns true if puzzle is solved
flip #changes one piece on the board
end
end
Is there a way to have this loop pause before each call to the flip method and wait for the user to press the spacebar?
The easy solution would be to add a gets before flip. Then it would wait for you to hit enter.
If you really want to wait for spacebar, you can use curses. It can do robust input handling in the terminal, but it can get pretty complicated. If you're using Ruby 2.1.0 or earlier curses is part of the stdlib. Otherwise you'll need one of the gems.

Debugging Advice for Python

I have to debug large programs with nested function calls. I would like it s.t. whenever an exception occurs I simply halt the execution at that point, within any function I might be in. Then I can try out different corrections for the error and move on.
While I have been using try except, what I need here is that I can halt inside any function, no matter how nested the call to it might be. So, to do it manually I would have to wrap each function's code around a try-except! like so:
def fun1:
try:
except:
pdb.set_trace()
And this would be very cumbersome to write. Also since whenever I encounter an exception I go straight to the except block, for large functions this would require me to restart from the beginning, which would be time taking. So basically I have this (ambitious) requirement of running each line of code in it's own try-except block, like:
def func1:
try:
line1
except:
pdb.set_trace()
try:
line2
except:
pdb.set_trace()
Is there some automatic, or clever way to rig up such a system?
Thanks in advance.
Any good IDE will have the ability to add breakpoints to debug your code. I personally use PyCharm by Jetbrains jetbrains.com/pycharm. You can add breakpoints and step line-by-line through your code easily. It also automatically halts execution at an exception and you can manipulate values. How are you developing your python code now?

Can a watir browser object be re-used in a later Ruby process?

So let's say pretty often a script runs that opens a browser and does web things:
require 'watir-webdriver'
$browser = Watir::Browser.new(:firefox, :profile => "botmode")
=> #<Watir::Browser:0x7fc97b06f558 url="about:blank" title="about:blank">
It could end gracefully with a browser.close, or it could crash sooner and leave behind the memory-hungry Firefox process, unnoticed until they accumulate and slow the server to a crawl.
My question is twofold:
What is a good practice to ensure that even in case of script failure anywhere leading to immediate error exit, the subprocess will always get cleaned up (I already have lots of short begin-rescue-end blocks peppered for other unrelated small tests)
More importantly, can I simply remember this Watir::Browser:0x7fc97b06f558 object address or PID somehow and re-assign it to another $browser variable in a whole new Ruby process, for example irb? I.e. can an orphaned browser on webdriver be re-attached later in another program using watir-webdriver on the same machine? From irb I could then get in and re-attach to the browser left behind by the crashed Ruby script, to examine the website it was on, check what went wrong, what elements are different than expected, etc.
Another hugely advantageous use of the latter would be to avoid the overhead of potentially hundreds of browser startups and shutdowns per day...best to keep one alive as sort of a daemon. The first run would attempt to reuse a previous browser object using my specially prepared botmode profile, otherwise create one. Then I would deliberately not call $browser.close at the end of my script. If nothing else I run an at job to kill the Xvfb :99 display FF runs inside of at the end of the day anyway (giving FF no choice but to die with it, if still running). Yes I am aware of Selenium standalone jar, but trying to avoid that java service footprint too.
Apologies if this is more a basic Ruby question. I just wasn't sure how to phrase it and keep getting irrelevant search results.
I guess, U cant just remember the variable from another process. But the solution might be creating a master process and process your script in loop in thread, periodically checking the browser running state. I'm using some thing similar in my acceptance tests on Cucumber + watir. So it will be some thing like that:
require 'rubygems'
require 'firewatir' # or watir
#browser = FireWatir::Firefox.new
t = Thread.new do
#browser.goto "http://google.com"
#call more browser actions here
end
while not_exit?
if t.stop?
# error occurred in thread, restart or exit
end
if browser_live?
# browser was killed for a some reason
# restart or exit
end
end
#browser.close
not_exit? - can be over TRAP for the ctrl+C
browser_live? - you can check if firefox browser running with processes listings
It is quite tricky but might work for you
You can use DRb like this:
browsers pool:
require 'drb'
require 'watir'
browser = Watir::Browser.new :chrome
DRb.start_service 'druby://127.0.0.1:9395', browser
gets
and then from test script use this browser:
require 'drb'
browser = DRbObject.new_with_uri 'druby://127.0.0.1:9395'
browser.goto 'stackoverflow.com'
I'm pretty sure that at the point ruby exits, any handles or pointers to something like a browser object would become invalid. So re-using something in a later ruby process is likely not a good approach. In addition I might be wrong on this, but it does seem that webdriver is not very good at connecting to a running browser process. So for your approach to work it would really all need to be wrapped by some master process that was calling all the tests etc.. and hey wait a sec, that's starting to sound like a framework, which you might already (or perhaps should be) using in the first place.
So a better solution is probably to look at whatever framework you are using to run your tests and investigate any capability for 'setup/teardown' actions (which can go by different names) which are run before and after either each test, groups of tests, or all tests. Going this way is good since most frameworks are designed to allow you to run any single test, or set of tests that you want to. And if your tests are well designed they can be run singly without having to expect the system was left in some perfect state by a prior test. Thus these sorts of setup/teardown actions are designed to work that way as well.
As an example Cucumber has this at the feature level, with the idea of a 'background' which is basically intended as a way to dry out scenarios by defining common steps to run before each scenario in a feature file. (such as navigating to and logging into your site) This could include a call to a series of steps that would look to see if a browser object existed, and if not create one. However you'd need to put that in every feature file which starts to become rather non dry.
Fortunately cucumber also allows a way to do this in one place via the use of Hooks. You can define hooks to run before steps, in the event of specific conditions, 'before' and 'after' each scenario, as well as code that runs once before any scenarios, and code defined to run 'at_exit' where you could close the browser after all scenarios have run.
If I was using cucumber I'd look at the idea of a some code in env.rb that would run at the start to create a browser, complemented by at_exit code to close the browser. Then perhaps also code in a before hook which could check to see that the browser is still there and re-create it if needed, and maybe logout actions in a after hook. Leave stuff like logging in for the individual scenarios, or a background block if all scenarios in a feature login with the same sort of user.
Not so much a solution but a workaround for part 1 of my question, using pkill. Posting here since it turned out to be a lot less trivial than I had hoped.
After the ruby script exits, its spawned processes (which may not at all belong in the same PID tree anymore, like firefox-bin) have a predictable "session leader" which turned out to be the parent of the bash shell calling rubyprogram.rb in my case. Available as $PPID in Bash, for when you have to go higher than $$.
Thus to really clean up unwanted heavyweight processes eg. after a ruby crash:
#!/bin/bash
# This is the script that wraps on top of Ruby scripts
./ruby_program_using_watirwebdriver_browser.rb myparams & # spawn ruby in background but keep going below:
sleep 11 # give Ruby a chance to launch its web browser
pstree -panu $$ # prints out a process tree starting under Bash, the parent of Ruby. Firefox may not show!
wait # now wait for Ruby to exit or crash
pkill -s $PPID firefox-bin # should only kill firefox-bin's caused above, not elsewhere on the system
# Another way without pkill, will also print out what's getting killed if anything:
awk '$7=="firefox-bin" && $3=="'$PPID'" {print $1}' <(ps x -o pid,pgid,sess,ppid,tty,time,comm) | xargs -rt kill
OPTIONAL
And since I use a dedicated Xvfb Xwindows server just for webdriving on DISPLAY :99, I can also count on xkill:
timeout 1s xwininfo -display :99 -root -all |awk '/("Navigator" "Firefox")/ {print $1}' |xargs -rt xkill -display :99 -id
# the timeout is in case xkill decides to wait for user action, when window id was missing
Just an update on part 2 of my question.
It seems one CAN serialize a Watir:Browser object with YAML, and because it's text-based the contents were quite interesting to me (e.g. some things I've only dreamed of tweaking hidden inside private elements of private classes...but that's a separate topic)
Deserializing from YAML is still trouble. While I haven't tested beyond the first try it gives me some kind of reg exp parse error...not sure what that's about.
(more on that at at how to serialize an object using TCPServer inside? )
Meanwhile, even attempting to serialize with Marshal, which is also built-in to Ruby but stores in binary format, results in a very reasonable-sounding error about not being able to dump a TCPServer object (apparently contained within my Watir:Browser pointed to by $browser)
All in all I'm not surprised at these results, but still pretty confident there is a way, until Watir arrives at something more native (like PersistentWebdriver or how it used to be in the days of jssh when you could simply attach to an already running browser with the right extension)
Until then, if serialization + deserialization to a working object gets too thorny I'll resort to daemonizing a portion of my Ruby to keep objects persistent and spare the frequent and costly setup/teardowns. And I did take a gander at some established (unit testing) frameworks but none seem to fit well yet within my overall software structure--I'm not web testing after all.

Take over console output using ruby

When I run vim or top from a console they are able to take over rendering the whole console. When I quit I'm then returned to the console.
Is it possible to do this from ruby? As a simple example, how would I do the following
# Rakefile
task :clock do
loop do
console.render Time.now
sleep 1
end
end
when I run this the console would be cleared and the first line would show the time. When I quit I'd then continue the console session as it was before I ran rake clock.
Update
Having checked the tictactoe example for ruby curses here's an implementation of the clock example. I've shown the clock on random lines to demonstrate refreshing the whole console.
#!/usr/bin/env ruby
require 'curses'
loop do
Curses.clear
Curses.setpos(rand * 10, 0)
Curses.addstr(Time.now.to_s);
Curses.refresh
sleep 1
end
You're looking for the Ruby curses library which gives you full control over the screen: positioning, color, &c.
It's not a well document library, but a Stackoverflow search for "[ruby] curses" will give you links to examples.

How could I pack a rack web-application includes infinite loop

I want to pack a rack web-application in order to distribute it, In which a infinite loop resides. So it won't stop until my ctrl-c. But it seems ocra will only pack it when it ends 'naturally', and ctrl-c stopped the process.
have been tring use exit or abort in callmethod of object being passed to rake. after which the whole process do not end, some trace info appears though.
it is possible to invoke rake.run in a thread, and end application after given time. But I do not want to distribute a suicide version. so is there some more eligible and controllable way to normally end it ?
not sure if this is a insane question, but thanks in advance.
According to the OCRA docu, OCRA sets an environment variable OCRA_EXECUTABLE when being run.
So you could check for that environment var in your code and break the loop if OCRA is running, e.g.:
while true
break if ENV.has_key? 'OCRA_EXECUTABLE'
...
end

Resources