jueves, 31 de mayo de 2012

Versiones de gemas en Ruby

¿Cómo conocer la versión disponible de una gema?



gem list -a --remote watir


-a permite ver todas las versiones disponibles de la gema (en este caso watir), no solo la última.
--remote indica que la búsqueda se hará en el repositorio remoto por defecto. Si se quiere hacer una búsqueda local, --local es la alternativa.



¿Cómo instalar una versión específica de una gema?

gem install --version 0.4 ruby-mp3info

En ruby es posible y válido instalar varias versiones de una gema.

Cuando se utiliza una gema en un programa, por defecto se obtiene la versión más reciente. Si se quiere una versión específica: 

gem 'ruby-mp3info', '=0.5'
require 'mp3info'

Lo anterior se escribiría en IRB o en un ejecutable de ruby. El parámetro de la versión acepta otros operadores como: >, <=, etc. 


martes, 29 de mayo de 2012

Accediendo a elementos sin id con Watir




Cuando estás automatizando la prueba sobre la GUI de una aplicación es muy posible que no puedas acceder a los elementos mediante su id por la simple razón de que no tienen id. Por ejemplo, queremos acceder al campo de texto del siguiente código: 


<tr>
<td class="tns-PanelFormTitleText">Nombre</td>
<td>
<input class="gwt-TextBox tns-TextBox" type="text">
</td>
</tr>

No hay un atributo name, tampoco un id. 

Una solución es utilizar XPath (presento solo el xpath asociado con la porción de código de arriba): 

ie.text_field(:xpath, "...tr/td[2]/input").set 'WATIR 1'

Al ejecutar la prueba con XPath el campo de texto recibió la cadena 'WATIR 1' pero después de una larga espera en la que cada 2 segundos aproximadamente se escribía un caracter. No conozco la implementación pero supongo que por cada caracter que será ingresado, se recorre el xpath.  

Una mejor solución, es aprovechar que el campo tiene un "label" asociado. O mejor, en la celda anterior a la que contiene el campo, hay un texto que al menos semánticamente se relaciona con nuestro campo objetivo. La estrategia entonces puede ser esta: 

Acceder a la celda con el texto "Nombre". 
A partir de esta celda, obtener la fila que la contiene. 
Acceder a la segunda celda de la fila, que contiene a nuestro campo objetivo. 

En código: 

nombreRow = ie.td(:text => 'Nombre').parent
# se ubica el campo de texto y se le asigna un valor
nombreRow.cells[1].text_field.set 'WATIR 1'

El tiempo de ejecución disminuye considerablemente, a la mitad o menos. 

Especificar el ID de un radio button en GWT

En el caso de algunos elementos GWT el id se puede especificar simplemente con la operación setId de Element. Por ejemplo, para un botón el id se puede establecer así: 


this.buttonSetEnvironment.getElement().setId("btnEstablecerAmbiente");


Sin embargo, otros componentes como los radio button o los check boxes requieren conocer su estructura GWT para asignarles un id. Esto implica que asignar el id a un radio button no funciona con una sentencia como: 


radioButton.getElement().setId("miRadioButton");


Cuando se genera el código HTML el id queda asociado con un elemento span que contiene a nuestro radio button: 



<span id="miRadioButton" class="gwt-RadioButton tns-CheckBox">
  <input id="gwt-uid-1" type="radio" name="Grupo" value="on" tabindex="0">
  <label for="gwt-uid-1">CENT2</label>
</span>

Como se puede apreciar en el código anterior, el span agrupa al radio button y su respectivo label. Esto implica que los objetos RadioButton de GWT están compuestos por dos hijos (cuando se genera su HTML): un input y un label.  Sabiendo esto, podemos utilizar la clase DOM para acceder a la estructura del radio button y asignar el id al elemento que deseamos: 

private void setId(RadioButton radioButton, String id){
  Element radoButton_input = DOM.getChild(radioButton.getElement(),0);
  DOM.setElementAttribute(radoButton_input, "id", id);
}

De igual forma, si quisiéramos asignar un id al label, accederíamos al child 1.


Dicen algo muy interesante para el label. Su asociación con el button se especifica diferente en IE que para los demás navegadores: 

DOM.setElementAttribute(e_label, "htmlFor", newID); // For IE 
DOM.setElementAttribute(e_label, "for", newID); // For other 


viernes, 25 de mayo de 2012

Ruby y Ubuntu - Trabajar con la versión correcta


Al parecer, no. con seguridad la combinación "No ser experto en Linux", "Ser nuevo en Ruby" es muy peligrosa si quieres programar con Ruby en Linux.

Esta es mi historia.

No sabía que ubuntu tiene por defecto una versión de ruby, en mi caso la 1.8.x. De todas maneras, aún sabiéndolo habría instalado la versión más reciente que para la fecha es la 1.9.3. La instalación fue sencilla:

sudo apt-get ruby

Y empieza el sufrimiento. Ubuntu simplemente no asocia la nueva instalación como el ruby por defecto.

¿Solución?, un enlace simbólico:

 sudo ln -s /usr/bin/ruby1.9.3 /usr/bin/ruby

En el cambio instalé una gema supuestamente recomendada pero que la verdad no sé para qué sirve a ciencia cierta. De todas maneras, ahí va:

sudo apt-get install ruby-dev

Finalmente, se presentó otro problema. IRB, la consola interactica de Ruby tampoco quedó asociada con la nueva versión de ruby. ¿Solución?, así es, enlaces simbólicos:

sudo ln -s /usr/bin/irb1.9.3 /usr/bin/irb

Nota: me di cuenta que irb apuntaba a una versión vieja de ruby porque al intentar usar watir me salía este error:


irb(main):003:0> require 'watir-webdriver'
LoadError: no such file to load -- watir-webdriver
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from (irb):3
from :0

IRB estaba accediente a la versión 1.8 (por defecto) de Ubuntu. 

También se puede verificar la versión a la que apunta irb con este comando: 
En IRB: 

puts $:

Muestra algo así: 

/usr/local/lib/site_ruby/1.9.1
/usr/local/lib/site_ruby/1.9.1/x86_64-linux
/usr/local/lib/site_ruby
/usr/lib/ruby/vendor_ruby/1.9.1
/usr/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
/usr/lib/ruby/vendor_ruby
/usr/lib/ruby/1.9.1
/usr/lib/ruby/1.9.1/x86_64-linux
=> nil

Ahora sí, todo listo para trabajar. 

Se preguntará usted, único lector de mi blog, cómo encontré la solución. NO, no busqué por todo linux hasta encontrarla; recuerde que no soy experto en Linux. Después de horas y horas buscando en google llegué a esta solución, que seguramente no es la mejor, pero funcionó y con eso me basta. Igual, no quiero ser experto en linux, solo quería (hace unas 8 horas en total) hacer un pequeño programa en watir... por ahora creo que voy a dormir.