How to fall-back from WebDriver’s findElementBy() method to the one using native JS getElementBy* methods

Hi All,

If any of you ever encountered problems using WedDriver’s “By.*” selectors (especially in IE7 !!!! ) then you can find this post somehow useful/helpful 馃檪

The idea is simple: Use native JavaScript selector’s to find desired element.
I know that this is not a perfect solution, but works for me 馃檪

ps. Sorry for a crappy post title 馃檪

Cheers,
J

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.Assert;



/** 
 * Can be used as a fall-back method to find element(s) on page using native JS selector.  
 * VERY USEFUL when buil-in WebDriver's selector doesn't work, especially with IE7 !!!!!!!!!!!!!!!!!!!!!!
 * 
 * Author				: Janusz Kowalczyk
 * Created Date			: 07Jul2011   
 * REVISION HISTORY
 * DATE				CHANGED BY				DESCRIPTION
 * 07Jul2011		Janusz Kowalczyk		Initial Creation  
*/ 
public class JShelper
{
	private JavascriptExecutor jsExec = null;
	private Object o = null;
	private String jsSelector = null;
	
	/**
	 * Class constructor that instantiates JavascriptExecutor 
	*/
	public JShelper(WebDriver webdriver)
	{
		this.jsExec = (JavascriptExecutor) webdriver;
	}
	
	/**
	 * Tends to find HTML element by using three native JavaScript methods:
	 * getElementById(), getElementsByName(), getElementsByTagName().
	 * As a result WebElement is expected.
	 * For more info please refer to docs:   
	 * http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/JavascriptExecutor.html
	 * 
	 * @param byIdentificator Any unique ID (like: ID, Name, TagName) that gonna be used to find desired element, 
	 * by using one of the native JS methods: 
	 * getElementById(), getElementsByName(), getElementsByTagName()
	 * 
	 * @param foundElementsOffset If you expect to find more than 1 element, 
	 * then explicitly specify which one you want to get. 
	 * 
	*/
	public WebElement getElement(String byIdentificator, int foundElementsOffset)
	{
		String tmpSelector = null;
		
	
		tmpSelector = "document.getElementById('" 
			+ byIdentificator 
			+ "')[" 
			+ foundElementsOffset 
			+ "]";
		o = exec("return " + tmpSelector);
		if (o != null) 
			{ 
				jsSelector = tmpSelector; 
				return (WebElement) o; 
			}
		
		
		tmpSelector = "document.getElementsByName('" 
			+ byIdentificator 
			+ "')[" 
			+ foundElementsOffset 
			+ "]";
		o = exec("return " + tmpSelector);
		if (o != null) 
			{ 
				jsSelector = tmpSelector; 
				return (WebElement) o; 
			}
		
		
		tmpSelector = "document.getElementsByTagName('" 
			+ byIdentificator 
			+ "')[" 
			+ foundElementsOffset 
			+ "]";
		o = exec("return " + tmpSelector);
		if (o != null) 
			{ 
				jsSelector = tmpSelector; 
				return (WebElement) o; 
			}
		
		return (WebElement) o;
	}
	
	
	/**
	 * Retrieves the value of element's attribute
	 * For more information please refer to documentation:
	 * http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/JavascriptExecutor.html
	 * 
	 * 
	 * @param attribute Any html attribute like: value, class, name, id etc.
	 * 
	 * @return Value of element's attribute
	*/
	public String getAttributeValue(String attribute)
	{
		String tmpCmnd = "return " 
			+ jsSelector 
			+ ".getAttribute('" 
			+ attribute 
			+ "');";
		
		return (String) exec(tmpCmnd);
	}
	
	
	/**
	 * Sets the new value of element's attribute
	 * 
	 * @param attribute Any HTML attribute like: value, class, name, id etc.
	 * @param value Attribute's new value 
	*/
	public void setAttribute(String attribute, String value)
	{
		String tmpCmnd = jsSelector 
		+ ".setAttribute('" 
		+ attribute 
		+ "', '" 
		+ value 
		+ "');";
		
		exec(tmpCmnd);

		assertIsSetTo(attribute, value);
	}
	
	
	/**
	 * Simple assertion to chech is current attribute's value is the same as expected
	 * 
	 * @param attribute Any HTML attribute like: value, class, name, id etc.
	 * @param expValue Expected attribute's value 
	*/
	public void assertIsSetTo(String attribute, String expValue) 
	{
		String currentValue = (String) getAttributeValue(attribute);
		
    	Assert.assertTrue(currentValue != null && currentValue.equals(expValue),
    			"Attribute's new value is different from exptected. Expected value: '" 
    			+ expValue 
    			+ "' Current value: '" 
    			+ currentValue 
    			+ "'");
    }
	
	
	/**
	 * Executes JS
	 * 
	 * @param script Executes JavaScript in the context of the currently selected frame or window. 
	 * For more information please refer to documentation:
	 * http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/JavascriptExecutor.html
	*/
	private Object exec(String script)
	{
		return jsExec.executeScript(script);
	}
}

Test your knowledge

[EN]
During my current job search, I wanted to check what can they they ask me during job interviews in companies that are looking for an web/front-end developer etc. After browsing few post like “js/html/css interview questions”, I started to seek some knowledge tests, that can help me with rating my current knowledge and deficiencies in it. Below you can find list of few selected tests, I’ve encountered somewhere in net.


[PL]
Podczas moich obecnych poszukiwa艅 pracy, chcia艂em sprawdzi膰 czego wymaga si臋 na rozmowach na stanowiska web / front-end developera itp. 聽Po przeszukaniu paru post贸w z serii “js/html/css/ interview questions”, zabra艂em si臋 za szukanie gotowych quiz贸w, kt贸re oceni膮 obecny stan wiedzy i braki. Poni偶ej znajduje si臋 lista wybranych test贸w na r贸偶nym poziomie zaawansowania, kt贸re uzna艂em za warte wymienienia.

[CSS quiz]
http://www.w3schools.com/quiztest/quiztest.asp?qtest=CSS

[java script / jQuery quizzes]
http://dhtmlkitchen.com/jstest/jquery/quiz.jsp
http://www.planetpdf.com/developer/article.asp?ContentID=6337
http://www.w3schools.com/js/js_quiz.asp
http://dean.edwards.name/weblog/2006/06/levels/