Jan 07

When element doesn’t contain any id and name, using xpath to find the element is very important for writing selenium test. I list some sample locate for the element which doesn’t contain id or name.

1. get the link with the link text<a href=”link url”>Link Text</a> -> link=Link Text

2. get element with the element text

<a href=”link url”>Link Text</a> -> //a[text()='Link Text']

3. get element with part of the element text

<a href=”link url”>Link Text</a> -> //a[contains(text(), 'ink Tex')]

4. get element with an attribute

<a href=”link url”>Link Text</a> -> //a[@href='link url']

5. get element with two attributes

<input type=”text” value=”value”/> -> //input[@type='text' and @value='value']

XPather is a firefox plugin help you to find the xpath.

There is more element locators document to be found on Selenium Doc

Jan 03

Sometime I want to use a ruby library and implement something in ruby code so I could use the cool ruby features. JRuby provide the capability to run ruby code in Java. Therefore I could implement Java interface in Ruby.

1. Create the Java Interface

public interface Animal
{
public String speak();

public String move();
}

2. Implement the interface in Ruby


class Animal
def move
"Move..."
end

def speak
"Speak..."
end
end

3. Create a factory to create the concrete class of the interface


import org.jruby.Ruby;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaEmbedUtils;

import java.lang.reflect.Method;
import java.io.InputStream;
import java.io.File;

public class RubyFactory
{
public static final String RUBY_src="ruby";

public static <T> T getBean(Class<T> type)
{
Ruby runtime = Ruby.getDefaultInstance();

try
{
runtime.evalScript(runtime.evalScript("File.open('" + RUBY_SRC + File.separator + type.getSimpleName().toLowerCase() + ".rb').read").toString());
runtime.evalScript(extendRubyScript(type));
}
catch (Exception e)
{
System.err.println(e.toString());
}

Object c = runtime.evalScript(type.getSimpleName() + ".new");
c = JavaEmbedUtils.rubyToJava(runtime, (IRubyObject) c, type);
return (T) c;
}

private static String extendRubyScript(Class type)
{
String rubyScript = "require 'java'\n" +
"class " + type.getSimpleName() + "\n" +
"  include Java::" + type.getName().replace(".", "::") + "\n";

Method[] methods = type.getMethods();

for (Method method : methods)

{
String name = method.getName();
rubyScript += "  eval(\"alias " + name + " #{’" + name +        "’.gsub(/([A-Z]+)([A-Z][a-z])/,’\\1_\\2′).gsub(/([a-z\\d])([A-Z])/,’\\1_\\2′).tr(’-', ‘_’).downcase}\")\n";
}

rubyScript += "end";
return rubyScript;
}    public static void main(String[] args)
{

Animal animal = RubyFactory.getBean(Animal.class);
System.out.println(animal.move());

System.out.println(animal.speak());
}
}

All the ruby files should be put into the ruby directory. I follow the naming convertion as following:

interface Greeting -> greeting.rb with class Greeting

method sayGoodbye in java -> method say_goodbye in ruby

4. use the factory above, we could easily to implement another java interface.


public interface Greeting
{
public String sayGoodbye();

public String sayHello();
}

5. The implementation of interface greeting.


class Greeting
def say_hello()
"Hello"
end

def say_goodbye()
"Goodbye"
end
end

6. Test Greeting.


public class GreetingTest extends TestCase
{
private Greeting greeting;

@Before
protected void setUp() throws Exception
{
greeting = RubyFactory.getBean(Greeting.class);
}

@Test
public void testSayHello()
{
assertEquals("Hello", greeting.sayHello());
}

@Test
public void testSayGoodbye()
{
assertEquals("Goodbye", greeting.sayGoodbye());
}
}

In order to run the application, you need to include asm-2.2.3.jar, asm-commons-2.2.3.jar, backport-util-concurrent.jar and jruby-complete-1.0.1.jar

download source code