FireWatir TextField set : Very Slow - ruby

When calling the set method of a text_field in ruby, the text is being entered at a very slow rate in the browser, roughly at 1 character / second.
Environment Information:
Ubuntu 10.10
FireFox 3.6.13
JSSh 0.9
Ruby 1.9.2p136
FireWatir 1.7.1
Kindly advice. Thanks in advance.

It is a known bug: WTR-397
Workaround is to use watir-webdriver or to use value= instead of set. Example:
browser.text_field(how => what).value= "string"

solve slow key type issue on firewatir:
need to edit the file text_field.rb
enter to the folder
#>cd /usr/lib/ruby/gems/1.8/gems/firewatir-1.7.1/lib/firewatir/elements/ make it writeable
#>chmod 777 text_field.rb edit the proc def doKeyPress( value )
put # in front of #o.fireEvent("onKeyDown") and #o.fireEvent("onKeyPress") and #o.fireEvent("onKeyPress")
instead enter fire_key_events
def doKeyPress( value )
begin
max = maxlength
if (max > 0 && value.length > max)
original_value = value
value = original_value[0...max]
element.log " Supplied string is #{suppliedValue.length} chars, which exceeds the max length (#{max}) of the field. Using value: #{value}"
end
rescue
# probably a text area - so it doesnt have a max Length
end
for i in 0..value.length-1
#sleep element.typingspeed # typing speed
c = value[i,1]
#element.log " adding c.chr " + c #.chr.to_s
#o.value = "#{(#o.value.to_s + c)}" #c.chr
fire_key_events #add this
##o.fireEvent("onKeyDown")
##o.fireEvent("onKeyPress")
##o.fireEvent("onKeyUp")
end
now it should work faster

Related

Improving an algorithm for substring search when reading ZIP files

So I have a ZIP reader library, and I read ZIP files by first figuring out where the EOCD record is (the standard way "from the tail"). I have to look for a pattern that is roughly this:
4byte_magic_number, fixed_n_bytes, 2_bytes_of_comment_size, comment
The bytesize of comment is provided in the 2_bytes_of_comment_size. Just scanning for the magic number is insufficient, because I eager-read a substantial portion at the tail of the file - basically the maximum size the ZIP EOCD record can be, and then look for this pattern in there.
So far, I came up with this
def locate_eocd_signature(in_str)
# We have to scan from the _very_ tail. We read the very minimum size
# the EOCD record can have (up to and including the comment size), using
# a sliding window. Once our end offset matches the comment size we found our
# EOCD marker.
eocd_signature_int = 0x06054b50
unpack_pattern = 'VvvvvVVv'
minimum_record_size = 22
end_location = minimum_record_size * -1
loop do
# If the window is nil, we have rolled off the start of the string, nothing to do here.
# We use negative values because if we used positive slice indices
# we would have to detect the rollover ourselves
break unless window = in_str[end_location, minimum_record_size]
window_location = in_str.bytesize + end_location
unpacked = window.unpack(unpack_pattern)
# If we found the signature, pick up the comment size, and check if the size of the window
# plus that comment size is where we are in the string. If we are - bingo.
if unpacked[0] == 0x06054b50 && comment_size = unpacked[-1]
assumed_eocd_location = in_str.bytesize - comment_size - minimum_record_size
# if the comment size is where we should be at - we found our EOCD
return assumed_eocd_location if assumed_eocd_location == window_location
end
end_location -= 1 # Shift the window back, by one byte, and try again.
end
end
but it just screams ugly at me. Is there a better way to do something like this? Is there a pack specifier that says "all the bytes in binary until the the end of the string" that I do not know of? Then I could tack that onto the end of the pack specifier for example... A bit at loss here.
In the end I opted for the following optimization. First, I made a method for finding all the indices of a given substring in a string - there is no stdlib builtin for this.
def all_indices_of_substr_in_str(of_substring, in_string)
last_i = 0
found_at_indices = []
while last_i = in_string.index(of_substring, last_i)
found_at_indices << last_i
last_i += of_substring.bytesize
end
found_at_indices
end
Then, we use it to "latch" onto the offsets in our buffer where our signature was found.
def locate_eocd_signature(in_str)
eocd_signature = 0x06054b50
eocd_signature_str = [eocd_signature].pack('V')
unpack_pattern = 'VvvvvVVv'
minimum_record_size = 22
str_size = in_str.bytesize
indices = all_indices_of_substr_in_str(eocd_signature_str, in_str)
indices.each do |check_at|
maybe_record = in_str[check_at..str_size]
# If the record is smaller than the minimum - we will never recover anything
break if maybe_record.bytesize < minimum_record_size
# Now we check if the record ends with the combination
# of the comment size and an arbitrary byte string of that size.
# If it does - we found our match
*_unused, comment_size = maybe_record.unpack(unpack_pattern)
if (maybe_record.bytesize - minimum_record_size) == comment_size
return check_at # Found the EOCD marker location
end
end
# If we haven't caught anything, return nil deliberately instead of returning the last statement
nil
end

Ruby convert string array to string

I have a ruby string array value and i want to get it as string value. I am using ruby with chef recipe. Running in windows platform. Code-
version_string = Mixlib::ShellOut.new('some.exe -version').run_command
Log.info(version.stdout.to_s)
extract_var = version_string.stdout.to_s.lines.grep(/ver/)
Log.info('version:'+ extract_var.to_s)
output is coming-
version 530
[2016-06-08T07:03:49+00:00] INFO: version ["version 530\r\n"]
I want to extract 530 string only.
long time no see since Rot :)
You can use some Chef helper methods and regular expressions to make this a little easier.
output = shell_out!('saphostexec.exe -version', cwd: 'C:\\Program Files\\hostctrl\\exe').stdout
if output =~ /kernel release\s+(\d+)/
kernel_version = $1
else
raise "unable to parse kernel version"
end
Chef::Log.info(kernel_version)
As you want val = 720 and not val = "720" you can write
val = strvar.first.to_i
#=> 720
You can return the first series of digits found as an integer from the current_kernel string with String#[regexp] :
current_kernel[/\d+/].to_i
#=> 720

watir-webdriver setting value to text_field very slow

It takes around 4-5 seconds to set large text to text_field using watir-webdriver. I have also tried value method, but still it's very slow.
I have found a workaround for this on Windows using Clipboard gem and send_keys [:control, "v"], however this does not really work with headless linux. Any suggestion on this?
Inputting large values can be slow because the characters are inputted one at a time. This is to trigger each of the key events.
Assuming your application does not care about the events triggered by inputting the field, you could directly set the value via JavaScript.
Watir 6.8+
Watir now provides a #set! method to do this:
long_text = "abcde fghijk lmnop qrstuv"
browser.text_field.set!(long_text)
Pre-Watir 6.8
Prior to v6.8 (when this was originally answered), this needed to be done manually via #execute_script:
long_text = "abcde fghijk lmnop qrstuv"
the_field = browser.text_field
p the_field.value
#=> ""
browser.execute_script("arguments[0].value = '#{long_text}';", the_field)
p the_field.value
#=> "abcde fghijk lmnop qrstuv"
Performance Comparison
Even with this small text, you can see that execute_script is much faster. A benchmark:
n = 100
Benchmark.bm do |x|
x.report("execute_script:") { n.times { browser.execute_script("arguments[0].value = '#{long_text}';", the_field) } }
x.report("set:") { n.times { the_field.set(long_text) } }
end
The results:
user system total real
execute_script: 0.874000 0.609000 1.483000 ( 6.690669)
set: 2.199000 1.295000 3.494000 ( 22.384238)

get random password with puppet function

I have a function that allow me to generate random password. My function is working well without a puppetmaster. When I tried with a master an error appear when I called the function :
Error 400 on SERVER: bad value for range
Here is my function:
module Puppet::Parser::Functions
newfunction(:get_random_password, :type => :rvalue, :doc => <<-EOS
Returns a random password.
EOS
) do |args|
raise(Puppet::ParseError, "get_random_password(): Wrong number of arguments " +
"given (#{args.size} for 1)") if args.size != 1
specials = ((33..33).to_a + (35..38).to_a + (40..47).to_a + (58..64).to_a + (91..93).to_a + (95..96).to_a + (123..125).to_a).pack('U*').chars.to_a
numbers = (0..9).to_a
alphal = ('a'..'z').to_a
alphau = ('A'..'Z').to_a
length = args[0]
CHARS = (alphal + specials + numbers + alphau)
pwd = CHARS.sort_by { rand }.join[0...length]
return pwd
end
end
The function is called in both case with $pwd = get_random_password(10).
When I specified the length directly in the function to 10 for example. The password is well generated in master mode.
Have you any idea why I can't specify the length value?
It's unclear why this works for puppet apply (if that's what you're insinuating), but the error is most likely a typing issue.
Try
length = args[0].to_i
To my Knowledge,For situations like this I use the puppet generate() function to create the random password and store it in a persistent data store on the master.
For instance,an SQLITE database or something. This way, the password is generated randomly if it does not exist and the same password is used if it does already exist.
It's important to have the resource always be managed, that way if the password is changed on the managed node Puppet will realize this, change it to the value you're managing, and report that it did so.

Cucumber and variables internal to methods called indirectly

Please note: I am new to TDD & cucumber, so the answer may be very easy.
I am creating a basic image editor for a test (the image is just a sequence of letters).
I have written a Cucumber story:
Scenario Outline: edit commands
Given I start the editor
And a 3 x 3 image is created
When I type the command <command>
Then the image should look like <image>
The step
Scenarios: colour single pixel
| command | image |
| L 1 2 C | OOOCOOOOO |
always fails, returning
expected: "OOOCOOOOO"
got: " OOOOOOOO" (using ==) (RSpec::Expectations::ExpectationNotMetError)
This is the step code:
When /^I type the command (.*)$/ do |command|
#editor.exec_cmd(command).should be
end
The function exec_cmd in the program recognizes the command and launches the appropriate action. In this case it will launch the following
def colorize_pixel(x, y, color)
if !#image.nil?
x = x.to_i
y = y.to_i
pos = (y - 1) * #image[:columns] + x
#image[:content].insert(pos, color).slice!(pos - 1)
else
#messenger.puts "There's no image. Create one first!"
end
end
However, this always fails unless I hardcode the values of the two local variables (pos and color) in the function in the program itself.
Why? It doesn's seem I'm doing anything wrong in the program itself: the function does what it's supposed to do and those two variables are only useful locally. So I'd think this is a problem with my use of cucumber. How do I properly test this?
---edit---
def exec_cmd(cmd = nil)
if !cmd.nil?
case cmd.split.first
when "I" then create_image(cmd[1], cmd[2])
when "S" then show_image
when "C" then clear_table
when "L" then colorize_pixel(cmd[1], cmd[2], cmd[3])
else
#messenger.puts "Incorrect command. " + "Commands available: I C L V H F S X."
end
else
#messenger.puts "Please enter a command."
end
end
When /^I type the command (.*)$/ do |command|
#output = #editor.exec_cmd(command)
end
Then /^the image should look like (.)*$/ do |expected_image|
#output.should == expected_image
end
Hope this may help you.
It's not a cucumber issue.
The problem was that, in exec_cmd, split was called only in the "case" clause, not in the "when"s. This meant that, since the command's format was "a 1 2 b", cmd[1] in the "when" would call the second character of the string, a space, not the second value of the array, and the other functions would convert that to_i, returning 0.
I changed exec_cmd like this:
def exec_cmd(cmd = nil)
if !cmd.nil?
cmd = cmd.split
case cmd.first
when "I" then create_image(cmd[1], cmd[2])
[...]
end
which fixed the issue.

Resources