[webdriver] Smart GWT?

1,224 views
Skip to first unread message

Robert Atkins

unread,
Apr 19, 2010, 4:49:39 AM4/19/10
to webdriver
Hi all,

Anyone have any success testing a SmartGWT application with Webdriver?

Smart GWT makes it difficult by giving you no control over the IDs of
the page elements. For even more fun, it renders things differently
for different browsers, so even your horrendous xpath expressions
which work on Firefox won't work on IE.

The "Selenium support" just added to the SmartGWT nightlies doesn't
really help us much as it is predicated on using Selenium IDE-
generated tests rather than Webdriver from Java. Has anyone got a
"By.scLocator()" implementation, or any other suggestions of
techniques for testing SmartGWT with WebDriver?

Cheers, Robert.

--
You received this message because you are subscribed to the Google Groups "webdriver" group.
To post to this group, send email to webd...@googlegroups.com.
To unsubscribe from this group, send email to webdriver+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/webdriver?hl=en.

Colin Alworth

unread,
Apr 19, 2010, 9:09:53 AM4/19/10
to webd...@googlegroups.com
While we are not using SmartGWT, we do have several ExtJS and GXT
applications we are testing and maintaining - the best suggestion I
can offer is to encourage good unique classnames to be added to your
components, and once you've found a component, make the other
findElement queries relative to that component's WebElement.

Hope this helps,
Colin

Robert Atkins

unread,
Apr 19, 2010, 11:21:23 AM4/19/10
to webdriver
On Apr 19, 2:09 pm, Colin Alworth <niloc...@gmail.com> wrote:
> While we are not using SmartGWT, we do have several ExtJS and GXT  
> applications we are testing and maintaining - the best suggestion I  
> can offer is to encourage good unique classnames to be added to your  
> components, and once you've found a component, make the other  
> findElement queries relative to that component's WebElement.

We are adding special "findMe-blahComponentName" classes to everything
and using By.className(), but when we tried doing a
findElement(By.xpath()) on the WebElement returned by the find by
className, it looked like it was searching from the start of the DOM,
not relative to the found element. Should this have worked?

Cheers, Robert.

--
You received this message because you are subscribed to the Google Groups "webdriver" group.
To post to this group, send email to webd...@googlegroups.com.

Michael Tamm

unread,
Apr 20, 2010, 6:07:38 PM4/20/10
to webd...@googlegroups.com
Make sure your xpath starts with "./" or ".//" if you call findElement(By.xpath(...)) on a WebElement.
If your xpath starts with "/" or "//" the entire DOM will be searched - this is no fault of WebDriver/Selenium,
but comes from the XPATH spec: http://www.w3.org/TR/xpath/#path-abbrev

Regards, Michael

2010/4/19 Robert Atkins <snikta...@gmail.com>

Simon Stewart

unread,
Apr 21, 2010, 6:15:27 AM4/21/10
to webd...@googlegroups.com
Are there any details on the Selenium support for SmartGWT? It's
probably easy enough to execute a wedge of JS to find stuff.

Simon

Robert Atkins

unread,
Apr 22, 2010, 12:03:12 PM4/22/10
to webdriver
On Apr 20, 11:07 pm, Michael Tamm <michael.ta...@googlemail.com>
wrote:
> Make sure your xpath starts with "./" or ".//" if you call
> findElement(By.xpath(...)) on a WebElement.
> If your xpath starts with "/" or "//" the entire DOM will be searched - this
> is no fault of WebDriver/Selenium,
> but comes from the XPATH spec:http://www.w3.org/TR/xpath/#path-abbrev

You know that's almost certainly the problem. Thanks Michael. Trap for
young players.

Robert Atkins

unread,
Apr 22, 2010, 12:12:05 PM4/22/10
to webdriver
On Apr 21, 11:15 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
> Are there any details on the Selenium support for SmartGWT? It's
> probably easy enough to execute a wedge of JS to find stuff.

After having another look at it my initial optimism evaporated. Sure,
you can execute a wedge of Smart-provided Javascript, but that relies
on their user-extensions.js being installed into your Selenium proxy.
But we're not using the Selenium proxy, we're using the WebDriver-
provided FirefoxDriver.

Simon Stewart

unread,
Apr 22, 2010, 12:45:41 PM4/22/10
to webd...@googlegroups.com
On Thu, Apr 22, 2010 at 5:12 PM, Robert Atkins <snikta...@gmail.com> wrote:
> On Apr 21, 11:15 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
>> Are there any details on the Selenium support for SmartGWT? It's
>> probably easy enough to execute a wedge of JS to find stuff.
>
> After having another look at it my initial optimism evaporated. Sure,
> you can execute a wedge of Smart-provided Javascript, but that relies
> on their user-extensions.js being installed into your Selenium proxy.
> But we're not using the Selenium proxy, we're using the WebDriver-
> provided FirefoxDriver.

But where is this Smart provided JS? I'm having a hard time finding
it, and until I can look at it, I have no idea how hard it'll be to
port.

Simon

Robert Atkins

unread,
Apr 22, 2010, 12:54:53 PM4/22/10
to webdriver
On Apr 22, 5:45 pm, Simon Stewart <simon.m.stew...@gmail.com> wrote:
> But where is this Smart provided JS? I'm having a hard time finding
> it, and until I can look at it, I have no idea how hard it'll be to
> port.

Ah yeah, it took me a while to find too. Try the "smartgwt-2.1.zip"
from here:

http://www.smartclient.com/smartgwt/builds/latest/

Cheers, Robert.

Sanjiv Jivan

unread,
Apr 25, 2010, 2:57:13 AM4/25/10
to webdriver
The Selenium user extensions for SmartGWT / SmartClient are located
under the "selenium" directory of the .zip distribution found here :
http://www.smartclient.com/smartgwt/builds/latest/

SmartGWT does not guarantee the same DOM structure to be rendered on
different browsers for various reasons however it does support an
XPath like locator, called scLocator, and a Javascript API which
consistently allows the user to get DOM <---> scLocator. The logical
SmartGWT widget ID does not map directly to a DOM ID.

In additional to adding a new scLocator locator extension to Selenium,
the user extensions also override the "click" command when a SmartGWT
widget is clicked. This is because SmartGWT widgets expect the full
event cycle of mousedown, click, mouseup for a "real" click event to
be triggered while Selenium by default does not emulate the
mousedown / mouseup events.

Further details are mentioned the userguide.html file under the
"selenium" directory in the distro. These scLocators are more logical
to understand than the XPath counterpart for, say, a representation of
a particular cell in a ListGrid. In XPath it could be some complex
table/tr/td expression.

The actual code for mapping a scLocator path to a DOM element and vice-
versa resides in a JS file AutoTest.js which can be found in this .jar
file http://www.smartclient.com/smartgwt/builds/latest/smartgwt.jar
under the path com/smartclient/debug/public/sc/client/tools/
AutoTest.js and is dependent on various widget types and SmartClient
API's. So I'm not sure if reproducing this logic in WebDriver makes
sense. Instead if a new By.scLocator can be added as a WebDriver
extension that is able to evaluate by calling this AutoTest JS API
that would be ideal. We'd be happy to include such an extension in the
SmartGWT distribution. I'm just not familiar enough with WebDriver to
know if this is something that is supported by WebDriver.

Feel free to ask any questions on the workings of the SmartGWT
Selenium user extension or give me some pointers on how we can go
about building a By.scLocator WebDriver extension.

Thanks,
Sanjiv


On Apr 22, 12:45 pm, Simon Stewart <simon.m.stew...@gmail.com> wrote:

Robert Atkins

unread,
Apr 28, 2010, 4:50:20 AM4/28/10
to webdriver
On Apr 25, 7:57 am, Sanjiv Jivan <sanjiv.ji...@gmail.com> wrote:
> Further details are mentioned the userguide.html file under the
> "selenium" directory in the distro. These scLocators are more logical

I just downloaded the smartgwt-2.1.zip from that link and it doesn't
seem to contain a selenium directory (it used to, the copy I
downloaded at work last week does but I'm at home on a different
machine today.)

In any case, from memory that doc seemed to imply the SmartGWT GUI
builder tool would tell you what the scLocators were for elements on
your page. We're not using that tool, so is there an scLocator syntax
reference anywhere?

> to understand than the XPath counterpart for, say, a representation of
> a particular cell in a ListGrid. In XPath it could be some complex
> table/tr/td expression.

You're not kidding. But this is the way we're currently muddling
through.

> Feel free to ask any questions on the workings of the SmartGWT
> Selenium user extension or give me some pointers on how we can go
> about building a By.scLocator WebDriver extension.

Forgive my javascript naivete, but would it be as simple as this:

public class SmartGWT {

public static By locator(final String locator) {
if (locator == null)
throw new IllegalArgumentException("Cannot find elements with a
null id attribute.");

return new By() {

@Override
public List<WebElement> findElements(SearchContext context) {
JavascriptExecutor executor = (JavascriptExecutor) context;
return executor.executeScript("AutoTest.findElement", locator);
}

};
}

}

Simon?

Cheers, Robert.

Simon Stewart

unread,
Apr 28, 2010, 7:58:21 AM4/28/10
to webd...@googlegroups.com
Looks pretty close, though the JS should be something like:

(JavascriptExecutor) context).executeScript(
"return AutoTest.findElement(arguments[0]);", locator);

Assuming that the "AutoTest" object is the one provided by SmartGWT.

Simon

Sanjiv Jivan

unread,
Apr 28, 2010, 10:57:44 AM4/28/10
to webdriver
Great! Looks simple enough, I'll give it a shot.

Simon : can you let us know if the WebDriver "click" command
implementation does a mousedown, click and mouseup? This is required
my Smart GWT and some other JS toolkits as well.

Robert : I'll fix the build to include the selenium extensions in the
distro. Also note that you'll need to prefix AutoTest by $wnd since
GWT loads the main app in an IFrame named $wnd. So try

(JavascriptExecutor) context).executeScript(
"return $wnd.AutoTest.findElement(arguments[0]);", locator);



On Apr 28, 7:58 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:

Simon Stewart

unread,
Apr 28, 2010, 11:25:11 AM4/28/10
to webd...@googlegroups.com
Hi,

"click" should certainly do all of those things.

Simon

Sanjiv Jivan

unread,
Apr 29, 2010, 12:26:13 AM4/29/10
to webdriver
Thanks Simon. I'll check it out and post if I run into any issues.
WebDriver looks great and a nice improvement over Selenium,

Robert : the build has been fixed and you should see the "selenium"
directory in the distribution in nightly builds starting today. Since
you're having a go at it before me please do share your findings on
the SmartGWT forum.

Thanks,
Sanjiv

Robert Atkins

unread,
May 1, 2010, 6:50:25 AM5/1/10
to webdriver
On Apr 29, 5:26 am, Sanjiv Jivan <sanjiv.ji...@gmail.com> wrote:
> Robert : the build has been fixed and you should see the "selenium"
> directory in the distribution in nightly builds starting today. Since
> you're having a go at it before me please do share your findings on
> the SmartGWT forum.

Thanks Sanjiv.

This from selenium/user-guide.html in the nightly: "Typically these
locators will not be hand-written and are generated by Selenium IDE,
Selenium's test recording tool."

As a proof-of-concept I'll d/l Selenium IDE and ask it for the
locators for one of our pages and update our tests and see how we go.
But, we do test-first even for our integration/web tests, so we can't
use a tool on a page we haven't created yet to give us the locators to
put into the test which, when green, proves we've created the
page :-).

So, is there a reference for the SCLocator syntax anywhere?

Cheers, Robert.

Sanjiv Jivan

unread,
May 1, 2010, 10:10:17 AM5/1/10
to webdriver
I agree that the scLocator syntax needs to be documented. It will
probably be documented post Smart GWT 2.2 and until then you can use
Selenium IDE to guide you on the syntax. You'll quickly see that the
syntax is rather intuitive and will be able to hand write the locators
for new tests.

For example here is the scLocator syntax for ListGrid cells and
DynamicForms.

List Grid cells:

- //ListGrid[ID="itemList"]/body/row[itemID=1996||itemName=Sugar White
1KG||SKU=85201400||1]/col[fieldName=SKU||1]"
- This assumes the ListGrid has an explicit ID
- the 'body' part might be 'frozenBody' if the field in question was
frozen
- row[......] identifies the row (record)
- itemID=<value> - that's the primary key field from the dataSource
the grid is bound to
- itemName=<value> - that's the title field value for the record
- SKU=... - that's the cell the user clicked's value
- 1 - that's the index of the row (rowNum)
- col[.....] - identifies the column in the grid
- fieldName=... - field name for the field the user clicked
- 1 - that's the index of the column

Form Items... There are a bunch of possibilities for the internals of
a form item - let me give you the more common ones!:

//DynamicForm[ID="autoTestForm"]/item[name=textField||title=textField||
value=test||index=0||Class=TextItem]/element"
This example is the data element (text entry box) for a text field
- this form has an explicit ID
- item[...] identifies the item
- name (field name, if set)
- title (title, if set)
- value (current value if set)
- index (index in the form items array)
- Class (SC class of the item - in this case TextItem)
after the "/" we identify the part of the item in question
options here include:
"element" - the data element
"canvas" - for CanvasItems - points to the canvas embedded in the item
- in this case the xpath might continue to contain, for example
children of the canvas or elements within it (cells in a listGrid,
etc)
"textbox" - the "text box" - this is the area where content is written
out for items without a 'data element' - like header items
"[icon=<...>]" - the icon element -- "<...>" would contain the "name"
of the icon

Robert Atkins

unread,
May 20, 2010, 12:24:12 PM5/20/10
to webdriver
(Some) Success! I'm currently using the following code:

import java.util.Collections;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;

public class Sc {

public static By locator(final String locator) {
if (locator == null) {
throw new IllegalArgumentException("Cannot find elements with a
null id attribute.");
}

return new By() {

@Override
public List<WebElement> findElements(SearchContext context) {
return Collections.<WebElement>emptyList();
}

@Override
public WebElement findElement(SearchContext context) {
JavascriptExecutor executor = (JavascriptExecutor) context;
return (WebElement) executor.executeScript("return
AutoTest.getElement(arguments[0]);", locator);
}

};
}

}

It took a bit of figuring out, but with smartgwt-2.2/gwt-2.0.3 there's
no need for the "$wnd" mentioned earlier and it's now
AutoTest.getElement() rather than AutoTest.findElements() (that's why
I've made my findElements() method a no-op--will AutoTest.getElement
return a list of elements if the scLocator points to a list of
things?)

On May 1, 3:10 pm, Sanjiv Jivan <sanjiv.ji...@gmail.com> wrote:
> I agree that the scLocator syntax needs to be documented. It will

[...]

So now I'm trying to puzzle through the SC Locator syntax. Is there
any way to find the file name for an image's source, for instance?

Can I convince the SmartClient Developer Console to tell me about the
properties available on an element, or is there a better way?

wil.pannell

unread,
May 25, 2010, 3:21:52 PM5/25/10
to webdriver
Robert and Sanjiv,

Following your discussion I've tried the following test case based on
what was located by selenium ide, and I'm interested in your thoughts
about why the loginButton.click() method does not work:

@Test
public void testWebDriver()
{
WebDriver driver = new FirefoxDriver();
driver.navigate().to("http://localhost:8080");

WebElement userIdTextBox = driver.findElement(By.locator(
"//Window[ID=\"isc_Window_0\"]/item[0][Class=\"DynamicForm\"]/
item"
+ "[name=userId||title=userID||index=0||Class=TextItem]/
element"));

WebElement passwordTextBox = driver.findElement(By.locator(
"//Window[ID=\"isc_Window_0\"]/item[0][Class=\"DynamicForm\"]/
item"
+ "[name=password||title=password||index=1||Class=PasswordItem]/
element"));

WebElement loginButton = driver.findElement(By.locator(
"//Window[ID=\"isc_Window_0\"]/item[0][Class=\"DynamicForm\"]/
item"
+ "[name=loginButton||title=login||index=2||Class=ButtonItem]/
canvas"));

userIdTextBox.clear();
userIdTextBox.sendKeys("goodUsername");

passwordTextBox.clear();
passwordTextBox.sendKeys("goodPassword");
loginButton.click(); // doesn't work...
//loginButton.sendKeys(Keys.ENTER); doesn't work, either...
//loginButton.submit(); doesn't work, either...
driver.close();
driver.quit();
}

Cheers,

Wil

Reply all
Reply to author
Forward
0 new messages