Selenium UI-Element Locator

Note: A bevy of additional information on UI-Element may be found by browsing the Selenium category of this blog.

Overview

UI-Element is an extension to Selenium IDE that aims to fill several functional gaps in both the IDE itself and integration with a driven testing environment, namely with Selenium Remote Control. If you’re not already familiar with the Selenium suite of open-source web application testing tools, please refer to the OpenQA Selenium page to learn more.

Note: This blog entry has been edited for consistency with the latest UI-Element release.

The goals of the extension are summarized as follows:

Insulate testcases from change in underlying application

With traditional Selenium IDE recorded tests, small modifications to the presentational layer of a web application can break the ability of the test to locate elements on a page. Tests should be more resilient to change, such that testcase breakage can be minimized with careful test construction, and can be fixed at a central point as opposed to in all affected testcases. This calls for some mechanism of abstracting the locator.

Provide a richer language for encoding locator logic

Ideally, the expressiveness of locator logic should mirror that of the web application logic that drives the presentational layer. This isn’t really possible with simple XPath or DOM expressions. Conditional and indexed logic should be supported in the calculation of the locator.

Increase testcase readability

XPath and DOM expressions don’t give the tester a good sense of what page elements are being interacted with. Page elements should be uniquely identified by descriptive names that don’t necessarily look like code. Any relevant information about the element previous testers have recorded should also be easily accessible and easy to understand.

Enable a smooth transition from the record-playback to the scripting paradigm

Not all users come to web testing with expert skills in scripting web tests in perl, ruby, or proprietary languages. However, as users’ understanding of scripting grows, they should be able to smoothly transition from using record-playback through the IDE to creating scripts run through the Remote Control without losing the above advantages and without duplicating effort. The testing tools should promote the development of a users’ abilities.

Diving In: A Taste of UI-Element

Here is a short test fragment created using Selenium IDE, sans UI-Element extension. Notice in particular how the locators in the second column are content dependent. In other words, the require the link text to be a certain value. If the text ever changes, or if these move to a slightly different spot in the web application (as front page articles are likely to do as new articles are posted), the test will break.

open /  
clickAndWait //a[contains(text(),’Educate Your Stakeholders!’)]
clickAndWait //a[contains(text(),’Shane Diffily’)]
clickAndWait //a[contains(text(),’Content’)]

If we were to read the above test aloud in English, it might sound like: “Click link on the page that says Educate Your Stakeholders. Then click the link on the page that says Shane Diffily. Finally, click the link on the page that says Content.”

Here is the same test fragment created using Selenium IDE leveraging UI-Element. There’s some magic happening behind the scenes which you’ll see in just a moment. For now, notice what information is being conveyed by the locator. The Paamayim Nekudotayim, or double-colon, is obviously being used to delimit two pieces of data. This is the ui locator in action.

open /  
clickAndWait ui=issuePages::article(index=2)
clickAndWait ui=articlePages::author()
clickAndWait ui=allPages::topics(topic=Content)

The English reading for this test may be a little less intuitive, so I’ll tell you what it is: “We should be on some issue page. Click the second article element on the page. Now we should be on an article page. Click the author element on the page. We should be on a page that contains some generic elements. Finally, click the topic element on the page for the Content topic.”

Notice how different the two English readings sound. The first reading focuses on the textual content of the page, while the second focuses on its structure. With the former, we know we’re clicking something … but we’re given no clues about the contextual significance of what we’re clicking. The latter tells us what it is, semantically, that we’re clicking.

What’s Behind the Curtain: The Map File

It would be a feat of Artificial Intelligence for the IDE to just “know what we mean” when we provide a descriptive locator. We’re not that lucky, but fortunately the map file that makes it all possible isn’t rocket science. It is a file included into the Selenium IDE as a companion extension to UI-Element that defines the names (and other attributes) of page elements, and specifies the mapping from name to location on the page. It is written in Javascript, which provides a convenient and concise way to express all the required information. Here is an example:

myMap.addPageset({
    name: 'issuePages'
    , description: 'pages including magazine issues'
    , pathRegexp: '(issues/.+)?'
});
myMap.addElement('issuePages', {
    name: 'article'
    , description: 'front or issue page link to article'
    , args: [
        {
            name: 'index'
            , description: 'the index of the article'
            , defaultValues: range(1, 5)
        }
    ]
    , getLocator: function(args) {
        return "//div[@class='item']"
            + "[" + args.index + "]/h4/a";
    }
});

If you’re not pretty familiar with Javascript or other scripting, the syntax alone will look pretty hairy to you. Don’t worry about this yet … we’ll save matching square and curly brackets, regular expressions, and comma hunting for later. Let me tell you in plain English what this definition is saying:

  • I’m defining a group of pages, called a “pageset”. The name of the pageset is issuePages.
  • Pages are included in the pageset depending on their URL’s. I’m doing this using the regular expression (issues/.+)? , which must match part of the URL.
  • I’m defining a UI element, and I’m calling it the article element.
  • Here’s a nice description for what this element means: it’s a link to an article on the front page, or on an issue page.
  • You know, there might be several article elements on any given page. So I’m defining an argument which I’m calling the index of the article. I’m guessing there will typically be at most 4 such elements on a page.
  • I can tell you exactly how to find the element on the page, so long all of the required information is available (in particular the index of the article being located). I do this by feeding you an XPath expression which will unequivocally specify the element.
  • To explain the xpath locator: the element will be an Anchor element, which is the child of an H4 header element, which is the child of the N’th DIV element of class item. N was the value given as the index of the article element in question.

Here’s a simpler one:

myMap.addPageset({
    name: 'articlePages'
    , description: 'pages for actual articles'
    , pathRegexp: 'articles/.+'
});
myMap.addElement('articlePages', {
    name: 'author'
    , description: 'article author link'
    , locator: "//div[@id='content']/h3[@class='byline']/a";
});

In plain English:

  • I’m defining a pageset called articlePages. I’m using another regular expression as the rule for pages that are included within this pageset.
  • I’m defining the author UI element.
  • This element is a link to the author of an article.
  • There should be only one such element per page, and I know exactly how to find it with an xpath. I don’t need to define any arguments whatsoever.

Those more versed in Javascript can take advantage of the full expressive power of the language. Here we define a list of acceptable values for an argument.

var topLevelTopics = [
    'Code',
    'Content',
    'Culture',
    'Design',
    'Process',
    'User Science'
];

myMap.addPageset({
    name: 'allPages'
    , description: 'all alistapart.com pages'
    , pathRegexp: '.*'
});
myMap.addElement('allPages', {
    name: 'topics'
    , description: 'sidebar links to topic categories'
    , args: [
        {
            name: 'topic'
            , description: 'the name of the topic'
            , defaultValues: topLevelTopics
        }
    ]
    , getLocator: function(args) {
        return "//div[@id='topiclist']/ul/li" +
            "/a[text()=" + args.topic.quoteForXPath() + "]";
    }
    , testcase1: {
        args: { topic: 'foo' }
        , xhtml: '<div id="topiclist"><ul><li>'
            + '<a expected-result="1">foo</a>'
            + '</li></ul></div>'
    }
});

Again in plain English:

  • I’m defining the allPages pageset for all pages, including the home page.
  • I’m defining the topics element.
  • This element is a link appearing on the sidebar of a page. It links to a topic category page.
  • A fixed set of topics elements can appear on any page. These include Code, Content, and others. Although the list doesn’t change very often, and perhaps not at all, I’d like to be able to add and remove topics in the case that the list does change. I can do this by adding or removing from the topLevelTopics list.
  • I can locate any topics element on a page using an xpath locator. To construct the xpath, I’ll have to take into consideration just what topic is being considered. Other than that, the xpath is pretty straightforward.

Jumpstart: See UI-Element In Action

Enough talk - let’s get up and running! Download Selenium IDE with the UI-Element extension. (Note that you can build a more recent version out of the Selenium IDE subversion trunk.) Currently it is based on Selenium IDE version 0.8.7 . After you’ve downloaded the XPI file, open it in Firefox to initiate the install. If you already had another version of Selenium IDE installed, it might be a good idea to uninstall that first.

You’ll have to edit your configuration before you see anything special. Start the IDE extension, and go to Options > Options. You’ll see a field called “Selenium Core extensions (user-extensions.js)”. Copy the following text into the field, and click OK:

chrome://selenium-ide/content/ui-element.js, chrome://selenium-ide/content/ui-map-sample.js

You just enabled the UI-Element extension, along with a sample map file. (Note that the order of specifying extensions matters; the map file must appear after ui-element.js.) The map file ui-map-sample.js is a reference map for the website alistapart.com, which I chose as my testbed when writing UI-Element. I’ve defined a number of page elements which you can try out to get a sense of what the extension is doing. Go ahead and browse to http://alistapart.com, then restart Selenium IDE.

Now, just start interacting with the website. Click here, click there. Observe what command locators, or “Targets”, are being created in the IDE window. You should see at least some occurrences of the ui locator.

After you’ve clicked around a bit, try running the test. The IDE should be able to trace your path through the application using any ui locators created. If you experience difficulties, try creating a new test, and making sure you give each page enough time to load before clicking on. Premature clicks can be the cause of commands not being captured correctly.

Let’s explore a couple of interesting UI-Element features. Click one of the ui locator commands in the IDE command tree. Now hover the mouse over the “Target” text field. You should see a tooltip which contains a description of the page element. If there were any arguments defined for it in the map file, they should be described too, complete with default argument values. Notice that with this knowledge, it is very easy to edit the element locator. For example, say you start with this locator:

ui=allPages::section(section=contact)

Suppose instead of clicking this element, I want to click the element for a different section. Hovering the mouse over the text field, I see that articles, topics, about, contact, and contribute are among the sections defined for this element. I need only edit the locator to update it:

ui=allPages::section(section=about)

This is one of the primary benefits of the ui locator: it is not only easy to read, it is easy to edit too. Herein lies a good argument for maintaining accurate metadata in the map file documenting the elements you’ve defined - you’ll reap the rewards when editing tests in the IDE.

UI Element Tooltip

Down the Rabbit Hole: The Map File

As you’ve seen, the map file is what makes the ui locator work. This section delves into the syntax of the map file in more detail. One of the great things about UI-Element, ironically, is that not every tester needs to know how to write the map file. As long as one tester has the ability (or guts) to deal with the Javascript and seed the map file, which is really a repository of knowledge, all others will benefit. With time, any tester can learn to contribute to the repository.

(I know I learn best by example. If you’d like to take a look at the map file for alistapart.com and you’ve got UI-Element installed in Firefox, simply paste the following chrome URL into the address bar of the browser:)

chrome://selenium-ide/content/ui-map-sample.js

First things first: you need a good text editor to view and edit your map file. I highly recommend jEdit. Of the editors I’ve tried, its Javascript syntax highlighting is the most complete. It will ease any struggle you have closing parentheses, curly and square brackets, and keeping track of quotes and commas:

A dissertation on the mapping file syntax once lived here, but no longer. The reason: documentation that supersedes it is now included in the UI-Element distribution, under the Help menu. Here’s a snapshot of that documentation:

ui-doc.html

A few words on XPath.

There’s an art to constructing XPaths. For any given page element, a whole slew of XPath expressions can uniquely identify it. Remember this though - you are designing your expression to withstand unrelated changes to the application, if at all possible. It is brittle to construct XPaths that start at the root of the document tree and drill down, for example /html/body/div[4]/p/a . Rely instead on the semantic relationships of your pages - ids, names, and classes are your friends. For instance:

//div[@id='easy_to_find']/a

this div element can be anywhere on the page - it doesn’t matter where - and I’ll still be able to locate the link which has a semantic relationship with it. Base your XPaths on those semantic associations which will not change, in the face of presentational associations which almost surely will.

By the way, the Selenium IDE is a great place to test your XPaths. Navigate to the desired page, type your XPath expression into the IDE as the Target, and click the Find button. If the XPath is true, the correct page element should blink with a bright border.

On occasion, you may be frustrated with syntax errors in your map file that you can’t find. If this happens, there is a simple remedy - include the map file into a simple HTML file, which you can open in Firefox. Any Javascript errors should leap out at you in the Firefox Error Console. Here’s the HTML you can use:

<html>
<head></head>
<body>
<script type="text/javascript" src="path/to/my/map.js">
</script>
</body>
</html>

Driven: Graduating the IDE

You love using the IDE to record tests, but you need the power of variables, control structures (loops, functions), database queries, and automated scheduling of regression tests. Selenium Remote Control (RC) to the rescue! Now that you’ve created testcases with the ui locator, we need to be able to drive these testcases in the language of our choice.

The examples I use here are in Perl. To set up the driven test environment, download the latest release of the RC from the openqa.org website. (You may have to update your Java version to 1.5 or greater, or install a parallel version. If you experience problems with this release, try downloading a nightly snapshot build from the OpenQA site; the files will be named something like selenium-server-x.x.x-yyyymmdd.hhmmss-x-standalone.jar.) Now we need to install the Perl driver from CPAN:

% perl -MCPAN -e shell
...
cpan> install Test::WWW::Selenium
...

Now open the test you want to drive in the IDE. Export the test into Perl: File > Export Test As > Perl - Selenium RC. The exported file will look something like:

use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More "no_plan";
use Test::Exception;

my $sel = Test::WWW::Selenium->new(
    host => "localhost",
    port => 4444,
    browser => "*firefox",
    browser_url => "http://localhost:4444"
);

$sel->open_ok("/issues/237");
$sel->click_ok("ui=issuePages::article(index=2)");
$sel->wait_for_page_to_load_ok("30000");
$sel->click_ok("ui=articlePages::author()");
$sel->wait_for_page_to_load_ok("30000");
$sel->click_ok("ui=allPages::topics(topic=Content)");
$sel->wait_for_page_to_load_ok("30000");

If you’re running this particular example, you’ll have to edit the text highlighted in red to be the following:

http://alistapart.com

Save the test as ui-test.pl.

Let’s take this test on a test drive! Notice the presence of the ui locators in the code. We need to make the RC aware of both UI-Element and our map file, otherwise the locator will not be recognized and will fail to find the proper page elements. The Selenium Server component of the RC supports loading of Javascript extensions; however it currently requires all extensions to be packaged in a single file called user-extensions.js. (I’ve created a JIRA ticket for this.) We need to work around this restriction because we need to load two extensions files.

To get the first extension file, you can type the chrome URL:

chrome://selenium-ide/content/ui-element.js

into the Firefox address bar, then copy and paste the contents into a file called ui-element.js. Alternatively, you can unjar the UI-Element XPI file and drill down into the content folder to find it.

If you’ve got Unix tools at your disposal, simply concatenate the two files in this order:

% cat ui-element.js ui-map-sample.js > user-extensions.js

If not, simply concatenate the two files in a text editor, and save the resulting file as user-extensions.js. Now lets start up the Selenium Server.

% cd selenium-remote-control-0.9.0
% cd server
% java -jar selenium-server.jar -userExtensions user-extensions.js

Now run the test:

% perl ui-test.pl
ok 1 - open, /issues/237
ok 2 - click, ui=issuePages::article(index=2)
ok 3 - wait_for_page_to_load, 30000
ok 4 - click, ui=articlePages::author()
ok 5 - wait_for_page_to_load, 30000
ok 6 - click, ui=allPages::topics(topic=Content)
ok 7 - wait_for_page_to_load, 30000
1..7

A browser window should open and iterate through the test steps. The console window should indicate the success or failure of steps as they execute. Congratulations - you just ran your first Selenium driven test with UI-Element!

Conclusion

UI-Element gives the tester the option to trade off some simplicity for the sake of more power. It aims to improve the readability, maintainability, and expressiveness of testcases while still allowing the user the implement testcases, in full or in part, using Selenium IDE. It offers one valuable deliverable - the map file - which serves as living documentation for the user interface of the system under test. And it paves the road for transitioning from IDE-only testing to RC testing, with all the benefits inherent to real-world programming languages and automated regression.

Looking to the future, I hope to get feedback from the Selenium community on the usefulness of UI-Element, as well as improvement and bugfix requests. Eventually, I hope UI-Element will be good enough to merge into the Selenium project. If you have a comment, please leave a reply to this blog post, or to my UI-Element announcement post in the OpenQA forums.

26 Responses to “Selenium UI-Element Locator”

  1. Frederic Says:

    Thanks for the post. I find Selenium is a clever tool but very difficult to use. For my web testing requirements the free imacros Firefox add-on works well and is MUCH easier to use: http://www.iopus.com/imacros/firefox

    Maybe this helps some other frustrated selenium users, too :)

  2. Daniel Says:

    I couldn’t understand some parts of this article Selenium UI-Element Locator, but I guess I just need to check some more resources regarding this, because it sounds interesting.

  3. James Davis Says:

    Is it possible to include this library in Selenium RC? That would be sweet!

  4. Administrator Says:

    Yes, that’s actually the idea of keeping the contents of the extension in a separate javascript file and keeping the map file in a separate file too.

    If you’re asking whether the extension could be included by default into Selenium … I think that’s a good idea. However, I haven’t gotten a ton of feedback about it yet and would like to have some more before submitting it for inclusion. :)

  5. Luke Closs Says:

    Interesting post. I wonder how much of this idea could be applied to script-side locators. For instance, perhaps one could write special locators or locator maps in a scripting language of their choice, and then hook it into the RC client. For instance, Test::WWW::Selenium could have pluggable locators. Cool things to think about.

    We do all of our automation using something called Wiki Tests [1]. It could benefit from this kind of RC client side locators.

    Cheers,
    Luke

    [1] - https://www.socialtext.net/open/?wiki_tests

  6. Administrator Says:

    Thanks Luke, I’ll check out Wiki Tests.

    As far as “script-side locators”, you might want to check out the Selenium framework presentation by Apple and Santiago at the last GTAC. Looks like they’ve built a really cool framework using TestNG / Java / XML. The locators are basically defined in XML.

    http://www.youtube.com/watch?v=hWQdCdH77NA

  7. Robert Seidl Says:

    Thanks a lot for creating this and making it available. It really serves a strong need to make tests 1) more readable and 2) more easily maintainable when UI changes.

    I love the way that the “smart locators” are showing up even when recording (when I first read your post I thought I could type them, but this is much faster)

    I am just digging in, and would love to have a bit more documentation on the syntax of the mapping file. Or perhaps i just need to reread your chrome://selenium-ide/content/ui-map-sample.js a few more times :)

    Also, are the locators in there only xpath or are other locator types id/dom etc. also possible ? I read that XPath is comparatively slow and not reliable on - surprise - IE. Or can the getXPath function actually return something like “id=myButton” instead of “//input[@id=’myButton]’” ?

    Also (minor) your links to download are zip files not properly mimetyped - perhaps easy to fix so that a click will get the fox to just ask the usual “Install?” dialog instead of downloading a zip file, changing extensions, File>Open…> Install etc.

  8. Robert Seidl Says:

    oops never mind, your latest version
    http://ttwhy.org/home/blog/2007/10/04/ui-element-release-07/
    seems to address most of my questions !
    Google finds this page as the most interesting thats why I started reading here. Perhaps a “updated info here” to your new documentation page at
    http://ttwhy.org/code/ui-doc.html
    would be helpful to readers coming in from google.

    very nice, thanks.

  9. Administrator Says:

    Robert,

    Thanks for the feedback - it’s really valuable to me! I haven’t gotten a ton of it so far and am constantly thinking of ways to improve UI-Element. You’re right about the MIME type of the xpi file … I’ll try to get that figured out. I’m also interested in whether the documentation is clear, and if there are enough examples (I tried to include a bunch), so let me know if there’s room for improvement! :)

    Haw-Bin

  10. Andrew Thompson Says:

    This is great stuff. I think this area - a need for a good G/UI mapping - will become stronger as Selenium gets a wider user community.
    Users concerned with seeing a clearer representation of business requirements and more semantic definition in automation test cases will appreciate it.
    I’m certainly going try implementing this is my Selenium framework.
    Best wishes,
    Andrew

  11. Jeff Reichenberg Says:

    Wow! Your work potentially makes Selenium a viable tool for us, where we have automation QA folks who shouldn’t need to be experts in producing maintainable XPATH. Thanks!

    One question: is it possible to combine a UI Element locator and XPATH to make a new locator? I’m not sure we can realistically maintain a map file with UI Element locators for /everything/ that needs to be exposed to Selenium, but we certainly could define key regions on every page to use as a solid base from which to build more specific XPATH expressions. Something like
    (ui=helpPageSet::contactModule())//a[@class=’helpLink’] Already possible?

  12. Jeff Reichenberg Says:

    Wow! Your work potentially makes Selenium a viable tool for us, where we have automation QA folks who shouldn’t need to be experts in producing maintainable XPATH. Thanks!

    One question: is it possible to combine a UI Element locator and XPATH to make a new locator? I’m not sure we can realistically maintain a map file with UI Element locators for /everything/ that needs to be exposed to Selenium, but we certainly could define key regions on every page to use as a solid base from which to build more specific XPATH expressions. Something like
    (ui=helpPageSet::contactModule())//a[@class=’helpLink’] Already possible?

  13. gyrm Says:

    That’s a really interesting idea - chaining locators. While the exact syntax you suggested isn’t currently supported, it should be possible to add the suffix XPath as an argument to the UI element. So you might have something like:

    ui=helpPageSet::contactModule(subpath=//a[@class=’helpLink’])

    and modify your definition of getLocator() for the element accordingly. One thing you’d have to watch out for with this approach are the “special characters” in the context of parsing the arguments to the UI element. Since the argument values aren’t quoted, both commas and equals-signs may delimit values. Thus, in the example above you would not be able to include a comma in the value of “subpath”.

    Let me know if this is a sufficient work-around for you. BTW, you can grab the latest UI-Element code from the Selenium IDE trunk.

    Haw-Bin

  14. Jeff Reichenberg Says:

    Great tip…I didn’t think of that. The feature request that ties into this is to get the IDE to “think” this way during recording — know what UI element locators would accommodate a “subpath” (or perhaps they all would), and then favor those locators that would produce the shortest “remainder”, and then passing the remainder in as the “subpath”…

  15. gyrm Says:

    It seems that what you’re suggesting would be best accomplished the “UI-Element way”, with arguments.

    There are a couple of difficulties with recording an XPath “fragment” appended to a UI locator. First, there are potentially many ways to represent a page element with an XPath, so the recorder would have to make lots of assumptions on how your page is structured and the kinds of XPaths you prefer. Second, performance during recording would likely be an issue. To automatically detect UI elements when recording, the elements defined for matching pagesets are evaluated on a page. Normally if they don’t match the interacted element, they are skipped. If however they could be the “anchor” of a continued XPath expression, they would not be able to be skipped … unless we make an assumption about the relationship between the located element and the interacted element (such as a descendant relationship). A quick stab at what the recording logic pseudocode might be like:

    for (pageset in pagesets)
        for (element in pageset)
            for (defaultLocator in element.defaultLocators)
                locatedElement = evaluate(defaultLocator)
                if (matches(locatedElement, pageElement))
                    return defaultLocator
                else if (isDescendant(locatedElement,
                                      pageElement))
                    return bestXPath(locatedElement,
                                     pageElement)
    

    It seems like it would be a little hairy to get bestXPath() right. Another downside is that with the XPath, you lose the semantic meaningfulness of the element. Instead of saying “this element is a link on the menu”, for example, you would be saying “this element is a child element of the parent menu element”. Using arguments to the UI element would help you avoid this loss of readability.

    If you can provide a concrete example of a case where you think “locator combination” provides some advantage over using arguments, I’d be happy to consider it, just point me at the page source and indicate what elements you’re trying to locate. Maybe I can convince you that using arguments is better after all. :)

  16. Jeff Reichenberg Says:

    Yep, it would be slow, so my suggestion may not be viable. The need isn’t driven by any particular page structure, but is more an organizational dynamics and resourcing question. We have just a few people who know our mark-up really well and therefore are in a position to write and maintain ui-element map files. Given multiple hundreds of different pages and test cases that automate arbitrary functions on those pages, it’s not possible to write ui-element locators for everything. When an elements doesn’t have a UI Element locator, our software and QA automation engineers would be forced to stop thinking in terms of UI Elements and guess at some XPath.

    Because our site is driven off a template engine that is in charge of inserting page modules into the output, a general “module” ui-element locator can be used as a root for specific items in that module and would at least anchor the test author to the general area of the page he is concerned with and limit the impact of “bad” XPath. We could later search our test scripts for uses of that “module” ui-element locator to know where to focus on providing more specific locators.

    Using your suggestion around provide a generic ’subpath’ argument, I wrote just such a “module” locator keyed off some generic mark-up that our template engine (Tiles) adds when it inserts a page module. It accepts a “subpath” arg. So we have the “Chevy” version, and it’s great. But the “Cadillac” version would have the IDE recognize it during recording :-) Thanks!

  17. gyrm Says:

    Jeff, I think your idea is a good one … I’m just in the process of wrapping my head around how it would work. :) I’ll let you know if / when I come up with something!

    Haw-Bin

  18. gyrm Says:

    Check the following link for updated information on the “offset locator”: http://forums.openqa.org/thread.jspa?messageID=33026

  19. ilia liberman Says:

    Hi!
    First of all, thanks for a great tool!
    Could you, please, help me out with a problem I’ve experienced running my tests using UI in chrome://selenium-ide/content/selenium/TestRunner.html?
    It seems like re-occurrence of http://jira.openqa.org/browse/SIDE-84 bug.
    I’ve tried reinstalling IDE+UI (0.8.7ui0.7), tried to put both extension files into d:/user-extensions.js and attaching it as userExtensionsURL=file:///d:/user-extensions.js – both don’t work. I’ve also tried running UI-tests in standard IDE-testrunner: although it does load extensions, UI elements don’t work with the same error.

    URL:
    chrome://selenium-ide/content/selenium/TestRunner.html?test=/content/PlayerTestSuite.html&userExtensionsURL=chrome://selenium-ide/content/ui-element.js,file:///D:/Automation/Selenium/UI-Maps/ui-map-pr01.js&baseURL=

    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
    Command:
    type | ui=LoginPage::input_field(field_name=username) | selenium |

    error: Unrecognised locator type: ‘ui’

    Thanks in advance!

  20. Mel Ludowise Says:

    Please vote on this bug to allow multiple user-extensions.js files to Remote Control. This will allow the ui-map.js and ui-element.js files to be separate.

    http://jira.openqa.org/browse/SRC-250

  21. Jeff Weiss Says:

    Hi,
    I’m very interested in using UI-Element. However, there’s one deal breaker for me.

    It appears that currently, the extensions needed by selenium RC have to be specified when you start RC. What about people who want to use Selenium Grid? In other words, we want to have a general-purpose selenium server that knows nothing in advance about the web applications it’s going to be testing. The clients that connect to it are the ones that will have the application-specific UI-Element data.

    How hard is it to allow the clients to pass UI-Element data to RC when the client connects to RC?

  22. gyrm Says:

    > How hard is it to allow the clients to pass UI-Element data to RC when the client connects to RC?

    Currently I don’t believe it’s possible. However, given the interest of a number of people in this feature, I’m looking into how difficult this would be to add into the RC. I have not personally started using Grid, but I see it would be quite necessary for testing multiple web applications.

    Currently my thinking is that a browser session should have an independent store of extension javascript which can either be appended to or cleared. In the context of UI-Element, the entire contents of the UI map would be appended just after the browser was launched, and would be available until the browser was closed.

    Does this sound like it fits your needs?

  23. Dave Butler Says:

    Hi,
    We are trying to get UI-Element to work in with Selenese scripts in a tomcat/cargo/surefire/maven/selenium environment. I am attempting to use the selenium-maven-plugin configuration to include the UI-Element and mapping javascript for my selenium-integration-test profile. The HTML script is running when I run maven, but I get the following error in the selenium-results.html file.

    clickAndWait ui=MainPage::tab(tab=Content) Unrecognised locator type: ‘ui’

    It obviously appears to not be able to find the javascript definitions. Do you know of any good examples of how to include the user extensions in a maven profile’s startup of the selenium server?

  24. gyrm Says:

    Hi Dave,

    You’re in luck - I was just trying to teach myself a little about Maven today, not being very familiar with it. Configuration parameters for plugins are automatically generated from annotated source. The source indicates you can configure a userExtensions setting, which is the path to your user extensions. So you’d have in your pom.xml:

    ...
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>selenium-maven-plugin</artifactId>
      <executions>
        <execution>
          <phase>pre-integration-test</phase>
          <goals>
            <goal>start-server</goal>
          </goals>
          <configuration>
            <userExtensions>path/to/my/extensions.js</userExtensions>
            <background>true</background>
          </configuration>
        </execution>
      </executions>
    </plugin>
    ...
    

    Incidentally, though I haven’t posted about this, UI-Element has been integrated with Selenium Core in subversion, so if you pull down the latest and build you can specify your extensions without also pulling in what used to be in ui-element.js :)

  25. gyrm Says:

    As this page seems to get the most hits for UI-Element, I thought I’d put a pointer to another post which explains how it is now possible to specify per-session extension Javascript.

  26. Dave Butler Says:

    Did you ever get the userExtensions parameter working? I am able to include my element mapping file no problem. It is appended to the default user-extensions.js file as advertised and then moved to the workingDirectory (another config parameter) as advertised.

    But, I am still getting the same error as my 7/8/2008 post above.

Leave a Reply


Bad Behavior has blocked 774 access attempts in the last 7 days.