Non-latin letters in test script result in "No translation for key. Assuming unicode input..." - ruby

When I execute on Windows7+Ruby1.9.2+watir-webdriver this test script:
# encoding: utf-8
require "rubygems"
require "watir-webdriver"
ie = Watir::Browser.new :ie
ie.goto "www.tilde.eu"
ie.select_list(:name => "tr-direction").select "Latvian-English"
ie.select_list(:name => "tr-direction").selected? "Latvian-English"
ie.text_field(:class => "tr-area").set "skolas dārzā aug divas priedes"
ie.element_by_xpath("/html/body/div[3]/div/div/div/section/div/div/div/form/table/tbody/tr/td[3]/input").click
Watir::Wait.until { ie.text.include? "About Tilde Machine Translation" }
puts ie.div(:class => "translate_text_result").text
Script executes fine as it is in Firefox, but IE9 crashes when trying to set "ā" letter in text field and CMD shows following:
No translation for key. Assuming unicode input: 257
Timeout awaiting keypress: 82
Key up failed: 1400
Key down failed: 1400
Timeout awaiting keypress: 90
Key up failed: 1400
No translation for key. Assuming unicode input: 257
Key down failed: 1400
Script executes completely in Chrome, but still some warning in CMD are shown:
Started ChromeDriver
port=52409
version=14.0.836.0
[0825/095000:WARNING:webdriver_key_converter.cc(271)] No translation for key code. Code point: 257
[0825/095000:WARNING:webdriver_key_converter.cc(271)] No translation for key code. Code point: 257
Do I need to specify anything else apart from # encoding: utf-8 for it to work correctly in IE and Chrome?
I suggest to excecute above script on your computer to determine if this is common issue or just something in my configuration.

This is a known bug in the IE driver, which you can follow here. The warnings in Chrome are harmless, though they probably shouldn't be printed by default.

I've discovered that issue is actual only if non-windows keyboard layout is set.
If any of standard windows layouts is set e.g. "Latvian(QWERTY)" on script execution machine, IE doesn't crash anymore just outputs warnings similar to Chrome.
Temporary hack until IE driver bug is fixed could be to set standard windows keyboard layout before execution of test suite and to revert to previous one after execution.
How to get the keyboard layout on windows with ruby? - for inspiration.

Related

How to read a file in utf8 encoding and output in Windows 10?

What is proper procedure to read and output utf8 encoded data in Windows 10?
My attempt to read utf8 encoded file in Windows 10 and output lines into terminal does not reproduce symbols of some languages.
OS: Windows 10
Native codepage: 437
Switched codepage: 65001
In cmd window issued command chcp 65001. Following ruby code reads utf8 encoded file and outputs lines with puts.
fname = 'hello_world.dat'
File.open(fname,'r:UTF-8') do |f|
puts f.read
end
hello_world.dat content
Afrikaans: Hello Wêreld!
Albanian: Përshendetje Botë!
Amharic: ሰላም ልዑል!
Arabic: مرحبا بالعالم!
Armenian: Բարեւ աշխարհ!
Basque: Kaixo Mundua!
Belarussian: Прывітанне Сусвет!
Bengali: ওহে বিশ্ব!
Bulgarian: Здравей свят!
Catalan: Hola món!
Chichewa: Moni Dziko Lapansi!
Chinese: 你好世界!
Croatian: Pozdrav svijete!
Czech: Ahoj světe!
Danish: Hej Verden!
Dutch: Hallo Wereld!
English: Hello World!
Estonian: Tere maailm!
Finnish: Hei maailma!
French: Bonjour monde!
Frisian: Hallo wrâld!
Georgian: გამარჯობა მსოფლიო!
German: Hallo Welt!
Greek: Γειά σου Κόσμε!
Hausa: Sannu Duniya!
Hebrew: שלום עולם!
Hindi: नमस्ते दुनिया!
Hungarian: Helló Világ!
Icelandic: Halló heimur!
Igbo: Ndewo Ụwa!
Indonesian: Halo Dunia!
Italian: Ciao mondo!
Japanese: こんにちは世界!
Kazakh: Сәлем Әлем!
Khmer: សួស្តី​ពិភពលោក!
Kyrgyz: Салам дүйнө!
Lao: ສະ​ບາຍ​ດີ​ຊາວ​ໂລກ!
Latvian: Sveika pasaule!
Lithuanian: Labas pasauli!
Luxemburgish: Moien Welt!
Macedonian: Здраво свету!
Malay: Hai dunia!
Malayalam: ഹലോ വേൾഡ്!
Mongolian: Сайн уу дэлхий!
Myanmar: မင်္ဂလာပါကမ္ဘာလောက!
Nepali: नमस्कार संसार!
Norwegian: Hei Verden!
Pashto: سلام نړی!
Persian: سلام دنیا!
Polish: Witaj świecie!
Portuguese: Olá Mundo!
Punjabi: ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ ਦੁਨਿਆ!
Romanian: Salut Lume!
Russian: Привет мир!
Scots Gaelic: Hàlo a Shaoghail!
Serbian: Здраво Свете!
Sesotho: Lefatše Lumela!
Sinhala: හෙලෝ වර්ල්ඩ්!
Slovenian: Pozdravljen svet!
Spanish: ¡Hola Mundo!
Sundanese: Halo Dunya!
Swahili: Salamu Dunia!
Swedish: Hej världen!
Tajik: Салом Ҷаҳон!
Thai: สวัสดีชาวโลก!
Turkish: Selam Dünya!
Ukrainian: Привіт Світ!
Uzbek: Salom Dunyo!
Vietnamese: Chào thế giới!
Welsh: Helo Byd!
Xhosa: Molo Lizwe!
Yiddish: העלא וועלט!
Yoruba: Mo ki O Ile Aiye!
Zulu: Sawubona Mhlaba!
Steven Penny suggested to use PowerShell and do not change code page. Following picture demonstrates that the issue persists.
Windows Terminal installer (which is not a part of Windows distribution) solves utf8 output issue, please see included screen capture.
The problem is, you are using a some methods and tools that are really old. First:
Native codepage: 437
Switched codepage: 65001
You don't need to mess with the codepage any more, just leave it as the default. Also, from you picture I see you are also using Console Host, which is also really old. Windows Terminal [1] has been available since 2019, and has built in UTF-8 support. Using Windows Terminal, I can run your script, even without specifying UTF-8:
fname = 'hello_world.dat'
File.open(fname,'r') do |f|
puts f.read
end
and I get perfect result:
To use Windows Terminal, download the msixbundle file [2], then install it. Or, as it's essentially just a Zip file, you can rename it to file.zip and extract it with Windows, then run WindowsTerminal.exe. Or, since you are really having trouble with this process, you can use a portable version I just created
[3] (at your own risk).
https://github.com/microsoft/terminal
https://github.com/microsoft/terminal/releases/tag/v1.8.1444.0
https://github.com/microsoft/terminal/files/6563899/CascadiaPackage_1.8.1444.0_x64.zip

Commands not accepted by instrument over RS232 w/ ruby serialport script

MY ENVIRONMENT
I'm sending commands to a camera simulator device made by Vivid Engineering (Model CLS-211) over RS-232 from my laptop which is running CentOS 7.
ISSUE
I have installed two different serial monitors (minicom, gtkterm) and can successfully send successive commands over and over to the device. I can send a command to dump the memory contents as well. There are several configuration commands I have to send to the CLS-211 to set it up per a specific test. I want to automate this process and have written a ruby script to write a list of commands to the CLS-211 to make this process easier. However, it appears that I am not terminating each command correctly or the CLS-211 requires a specific terminator/signal that I am not giving to it in my ruby script. I'm confused why I can successfully accomplish this task with a serial monitor but not a ruby script. I've configured the serial port settings correctly per their manual so I know this is not the issue. You'll see those settings below defined in my scirpts. Their manual points out they use HyperTerminal which I can't use because I'm on a Linux system. Manufacture mentioned that other serial terminals should work just fine but they have only chosen to test one out being HyperTerminal. I've asked for their feedback on the issue and they simply say "We don't use Linux but it shouldn't be much different, good luck".
TROUBLESHOOTING
I have verified that my "send.rb" script is working to the best of my knowledge by writing a "read.rb" script to read back what I sent. I essentially connected pin 2 "rx" to pin 3 "tx" on the RS-232 cable for a loopback test. Below is my two scripts and the resulting output from running this test.
## Filename send.rb
require 'serialport'
ser = SerialPort.new("/dev/ttyS0", 9600, 8, 1, SerialPort::NONE)
ser.write "LVAL_LO 5\r\n"
ser.write "LVAL_HI 6\r\n"
ser.write "FVAL_LO 7\r\n"
ser.write "FVAL_HI 8\r\n"
ser.close
## Filename read.rb
require 'serialport'
ser = SerialPort.new("/dev/ttyS0", 9600, 8, 1, SerialPort::NONE)
while true do
printf("%c", ser.getc)
end
ser.close
Just found out that I cannot post more than 2 links since my reputation is so low. Anyways the output is just the following...
username#hostname $ ruby read.rb
LVAL_LO 5
LVAL_HI 6
FVAL_LO 7
FVAL_HI 8
I have hooked up the CLS-211 and dumped the memory contents by issuing the DUMP command using GtkTerm and this works fine. The following image shows the memory contents of the first four parameters being LVAL_LO, LVAL_HI, FVAL_LO, and FVAL_HI. I'm just choosing to show four values in the memory dump for the sake of keeping this thread short versus listing all of them. Since I cannot include more than 2 links because my reputation is low being a new guy I'm typing what the output looks like in GtkTerm instead...
CLS-211 initializing, please wait
............
ready
CLS211 Camera Link Simulator CLI
Vivid Engineering
Rev 3.0
DUMP
LVAL_LO = 0x0020 / 32
LVAL_HI = 0x0100 / 256
FVAL_LO = 0x0002 / 2
FVAL_HI = 0x0100 / 256
In the above image you can clearly see that the system boots as expected. After I typed in the command "DUMP" it printed out the memory contents successfully. You see that LVAL_LO = 32, LVAL_HI = 256, FVAL_LO = 2, and FVAL_HI = 256. As I mentioned before I can successfully type in a command to GtkTerm to change a specific parameter as well. The below images shows that after typing in the command LVAL_LO 5 to GtkTerm and then issuing a DUMP command the value 5 was read correctly and LVAL_LO was changed as expected. I can replicate this successful behavior with every command using GtkTerm.
Again, I can't post more than 2 links so I'm writing the output below...
LVAL_LO 5
DUMP
LVAL_LO = 0x0005 / 5
LVAL_HI = 0x0100 / 256
FVAL_LO = 0x0002 / 2
FVAL_HI = 0x0100 / 256
At this point I was like ok everything is working as expected. Lets see if I can execute my ruby script and replicate the same successfully. I then ran the script I typed up above titled "send.rb". Then I opened up GtkTerm and issued a DUMP command afterwards to see if those values were taken. Let it be known that before I ran "send.rb" the values that existed in memory on the CLS-211 were LVAL_LO = 32, LVAL_HI = 256, FVAL_LO = 2, and FVAL_HI = 256. You can see that after running "send.rb", opening GtkTerm back up and issuing the DUMP command the CLS-211 replied w/ "invalid entry". After issuing it again you'll see that it dumped the contents of memory and showed LVAL_LO was changed correctly but the other three values were not.
Almost Successful
At this point I assumed that the first value was being received and written to the memory contents of the CLS-211 correctly but the other commands were not being received correctly. I assumed this was most likely because of the lack of any delay. Therefore, I placed a 1 second delay between each ser.write command. I changed the script "send.rb" to the following.
## Filename send.rb
require 'serialport'
ser = SerialPort.new("/dev/ttyS0", 9600, 8, 1, SerialPort::NONE)
ser.write "LVAL_LO 9\r\n"
sleep(1)
ser.write "LVAL_HI 10\r\n"
sleep(1)
ser.write "FVAL_LO 11\r\n"
sleep(1)
ser.write "FVAL_HI 12\r\n"
sleep(1)
ser.close
The following is the result of running "send.rb" again with the above changes, opening up GtkTerm, and executing the DUMP command to verify memory.
Added sleep(1)
Nothing really changed. I was able to tell that the script took longer to execute and the first value did change but like before the last three values I sent did not get received and saved to memory on the CLS-211.
CONCLUSION
How can I continue troubleshooting this issue? What sort of terminations are happening to each command that I send through GtkTerm and is that different from what I have sent in my ruby script "send.rb" being "...\r\n". Totally lost and out of options on what I can do next.
[EDIT/UPDATE 10/09/17]
I'm so stupid. The one termination character I forgot to try out "by itself" was carriage return "\r". Using a carriage return by itself after each command fixed the issue. I'm curious what requirements drive a manufacturer to define how a serial packet should be constructed in terms of a termination character(s). I would think there would be a predefined standard to what termination character(s) should be used. For completeness I have included my code below to what it should be in the case of communicating correctly with the CLS-211 device. Basically, i took out the '\n' and kept the '\r' that was it.
## Filename send.rb
require 'serialport'
ser = SerialPort.new("/dev/ttyS0", 9600, 8, 1, SerialPort::NONE)
ser.write "LVAL_LO 9\r"
sleep(1)
ser.write "LVAL_HI 10\r"
sleep(1)
ser.write "FVAL_LO 11\r"
sleep(1)
ser.write "FVAL_HI 12\r"
sleep(1)
ser.close

Suppressing ipdb output in Spyder iPython interpreter

I have reason to believe that my iPython interpreter is causing my kernel to die and restart similar to the issues logged in this link and that link.
The latter link indicates that the error is caused by the fact that the debugger outputs step-by-step ipdb content into the interpreter. One user reported that the behavior stopped when he (and I quote)
disabled logging to console before running in debug mode
How does one "disable logging to console" in Spyder IDE/IPython? I really need to do this so I can at least step through my code....
EDIT
I would like to suppress this kind of output
ipdb> > d:\temp\other const models\plaxis\output\plotparfile.py(16)PlotParFile()
14 with open(filename,'r') as fid:
15 lines = fid.readlines()
---> 16 fid.close()
17 #split first line get header and pop it out
18 header = lines[0].split()
> d:\temp\other const models\plaxis\output\plotparfile.py(18)PlotParFile()
16 fid.close()
17 #split first line get header and pop it out
---> 18 header = lines[0].split()
19 lines.pop(0)
20
(Spyder developer here) That output is generated automatically and its purpose is to tell you where are you placed in your code while debugging.
Right now there are no options in Spyder to deactivate it. Besides, I really doubt that output could be the cause of any kernel failures.

Change Process Priority of a browser created by Watir Webdriver in ruby

I have this in ruby mine on a windows computer:
require 'watir-webdriver'
Before do
#browser = Watir::Browser.new :ie
end
I need to change #browser to run at a higher priority because of some time out issues that I get that are caused when other programs are running at the same time. I know how to increase the amount of time allowed for time out, but after some testing I found I would have to set time out higher than I find to be acceptable.
I have found that you can actually find the webdriven browser's PID from deep inside the #browser object (reading all protected and private components), and then renice it with a negative number to increase priority, which might require sudo to be allowed by a non-root user.
I've explored exporting this object to an ASCII form for storage, which actually works, though importing it back was the subject of another question. Try this (I do it just for fun every time my code fires up a new Watir::Browser):
require "yaml"
File.open("browserObj.yaml", 'w').write YAML::dump($browser)
Then when you peek inside this file browserObj.yaml, it gives you all sorts of interesting info, like:
server_url: !ruby/object:URI::HTTP
fragment:
host: 127.0.0.1
opaque:
parser:
password:
path: /hub/
port: 7055
query:
registry:
scheme: http
user:
timeout:
launcher: !ruby/object:Selenium::WebDriver::Firefox::Launcher
binary: !ruby/object:Selenium::WebDriver::Firefox::Binary
process: !ruby/object:ChildProcess::Unix::ForkExecProcess
args:
- ./firefox.sh
- -no-remote
- -foreground
detach: false
duplex: false
environment: {}
exit_code:
io:
pid: 6114
started: true
Notice the PID in the 2nd last line, which your code can easily detect and do whatever with at this point.
That is even safer than simply parsing the hierarchical process tree with eg. pstree -panu $PPID to find child browser processes.
In my own stuff I actually don't bother (eg. when I need to kill the proper Firefox process and not others) because I go by DISPLAY. All my desktop/interactive user stuff happens on DISPLAY :0, while my Watir Webdriver stuff happens on DISPLAY :99 hosted by Xvfb or Xephyr, which I can more selectively kill/xkill with the help of tools like xprop and xwininfo.
EDIT
For completeness, here's the Unix/Cygwin command I use to send a kill command to the watir-webdriver browser's pid if I need to:
awk '/pid:/ {print $2;}' browserObj.yaml |xargs -rt kill
Browsing the docs and code I didn't see any ready way to find the process id of the IE that the driver uses. You might try using system tools to discover what process is listening on the webdriver port (default 5555) and nicing that process. On posix you could try lsof or netstat to find processes using a specific port, I have no idea how to help you on windows.
Of course if this is a resource competition issue, why don't you just give your watir tests a better controlled environment which doesn't have other stuff preventing it from running at the speeds you desire.

firefox not opening - cron, ruby, firewatir

I have written a ruby script which opens up dlink admin page in firefox and does a ADSL connection or disconnection.
I could run this script in the terminal without any problem. But if I put it as cron job, it doesn't fire up firefox.
This is the entry I have in crontab
# connect to dataone
55 17 * * * ruby /home/raguanu/Dropbox/nettie.rb >> /tmp/cron_test
I see the following entries in /tmp/cron_test. So it looks like the script indeed ran.
PROFILE:
i486-linux
/usr/bin/firefox -jssh
But I couldn't figure out why I didn't see firefox opening up, for this automation to work. Here is /home/raguanu/Dropbox/nettie.rb
#!/usr/bin/ruby -w
require 'rubygems'
require 'firewatir'
require 'optiflag'
module Options extend OptiFlagSet
character_flag :d do
long_form 'disconnect'
description 'Mention this flag if you want to disconnect dataone'
end
flag :l do
optional
long_form 'admin_link'
default 'http://192.168.1.1'
description 'Dlink web administration link. Defaults to http://192.168.1.1'
end
flag :u do
optional
long_form 'user'
default 'admin'
description 'Dlink administrator user name. Defaults to "admin"'
end
flag :p do
optional
long_form 'password'
default 'admin'
description 'Dlink administrator password. Defaults to "admin"'
end
flag :c do
optional
long_form 'connection_name'
default 'bsnl'
description 'Dataone connection name. Defaults to "bsnl"'
end
extended_help_flag :h do
long_form 'help'
end
and_process!
end
class DlinkAdmin
include FireWatir
def initialize(admin_link = "http://192.168.1.1", user = 'admin', pwd = 'admin')
#admin_link, #user, #pwd = admin_link, user, pwd
end
def connect( connection_name = 'bsnl' )
goto_connection_page connection_name
# disconnect prior to connection
#browser.button(:value, 'Disconnect').click
# connect
#browser.button(:value, 'Connect').click
# done!
#browser.close
end
def disconnect( connection_name = 'bsnl' )
goto_connection_page connection_name
# disconnect
#browser.button(:value, 'Disconnect').click
# done!
#browser.close
end
private
def goto_connection_page( connection_name = 'bsnl')
#browser ||= Firefox.new
#browser.goto(#admin_link)
# login
#browser.text_field(:name, 'uiViewUserName').set(#user)
#browser.text_field(:name, 'uiViewPassword').set(#pwd)
#browser.button(:value,'Log In').click
# setup > dataone
#browser.image(:alt, 'Setup').click
#browser.link(:text, connection_name).click
end
end
admin = DlinkAdmin.new(Options.flags.l, Options.flags.u, Options.flags.p)
unless Options.flags.d?
admin.connect( Options.flags.c )
else
admin.disconnect( Options.flags.c )
end
Any help is appreciated.
You need to have a DISPLAY environment pointing at a valid X-server. This could either involve setting it to the value ":0.0" (without quotes), such that it refers to your local standard DISPLAY.
There's a few things to keep in mind though:
You could run an X virtual frame buffer (xvfb), so that Firefox simply uses that as it's display. This would mean that Firefox would be able to do all its graphical operations, but that it would be independent of your standard graphical environment. You'll have to set the DISPLAY variable appropriately so that it points to the xvfb instance. For instance, if you invoke xvfb as follows:
Xvfb :1 -screen 0 1600x1200x32
Then you'll be able to use this by setting the DISPLAY variable to :1
You're starting a full-blown firefox instance to simply connect or disconnect your modem. You would most likely be able to use "curl" to send the appropriate HTTP requests to the server, such that it performs a connect or disconnect for you. One way to trivially see what you should recreate would be to install a Firefox plugin such as LiveHTTPHeaders and note down the most important HTTP requests as you perform the actions manually.
There's even a ruby binding for curl:
libcurl for Ruby. The resulting script should be much smaller than your current script.
Programs run from cron don't have your interactive environment. Therefore they don't have and DISPLAY variable, and so you can't run any X (graphical) programs, e.g. Firefox.
I would suggest doing the HTTP connections yourself, in ruby, rather than trying to automate Firefox.
the crontab entry is wrong
it is like
#min hour day month dow user command
55 17 * * * ur_user_is_missing ruby /home/raguanu/Dropbox/nettie.rb >> /tmp/cron_test

Resources