Best practices with framework like dojo

Visto 541 veces
Saltar al primer mensaje no leído

greenGoby

no leída,
28 jul 2009, 16:45:0128/7/09
a webdriver
Our app makes heavy use of dojo and its templating mechanism, and we
don't put ids on many of our dom elements. So, to find elements we
often have to find references to known objects on the page and get
handles that way. This has actually been very beneficial to us and has
allowed us to get a lot of reuse without worrying about clashing ids,
etc.

I started out using Selenium, and found I had to do many user
extensions to work nicely with our application because of this.
Things like find items by id or even xpath just don't work well in
this scenario. I then found out that Web Driver was "replacing" the
Selenium core, so I switched over.

So, in trying to avoid dead ends, I am looking for best practices for
an application built like this. (Object handles need to be obtained,
which will then give handles to their dom nodes)

What is the best way to plug in something like this? In Selenium I
used a Locator in my user extensions file. This was actually pretty
natural for me. However, Web Driver seems to be "one step removed"
from the browser in regards to the api. I took a look at the By
class, but I want to see if there is a better place. Or, do I use the
PageObject pattern and wrap everything? (Still need to get a lot of
Javascript handles)

Any starting help for someone embarking on this type of project would
be of great value!

Thanks,

Irv

Simon Stewart

no leída,
29 jul 2009, 10:26:1629/7/09
a webd...@googlegroups.com
Hi,

I've not had too much experience with dojo, but I believe it uses
digit to locate elements. If so, then you could try something like
this:

public WebElement findUsingDijit(String identifier) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return (WebElement) js.executeScript(
"return digit.byId(arguments[0]);",
identifier);
);

The important thing here is that you can locate elements using dojo's
own element location strategy, and by returning these from a chunk of
javascript, you can get hold of the underlying element.

Regards,

Simon

Irv Salisbury

no leída,
29 jul 2009, 10:49:2329/7/09
a webd...@googlegroups.com
So, as long as the javascript I am executing returns a dom node, the driver is smart enough to deal with it?

Just in case others do a search and find this thread, I think the actual code folks would want for returning the appropriate input node of a dijit widget would be:

var widget = dijit.byId( arguments[0] );
if( widget ){
   return widget.focusNode || widget.domNode;
}
else {
  // not sure what to return here?  null maybe
 return null;
}

Also, if you happen to be using a combo box, or a menu you need to click on the downArrowNode, so it is worth testing for that as well. 

Thanks for the reply, I'll give it a try!

Irv

Irv Salisbury

no leída,
29 jul 2009, 14:44:2129/7/09
a webd...@googlegroups.com
Another follow up question (and I will continue to try and figure it out on my own as well)

In firebug I can definitely type in dijit.byId and it is fine.

I am getting an error doing this JavascriptExecutor that says "dijit.byId is not a function".  What I am struggling with is, how does one debug something like this with WebDriver?  Is there a log file somewhere, a place I can set a breakpoint?

The docs say the get method waits for the page to load, so at that point dijit should be there...

Irv

Irv Salisbury

no leída,
29 jul 2009, 14:49:1929/7/09
a webd...@googlegroups.com
For what its worth, it is dying in this function here:

FirefoxDriver.prototype.executeScript = function(respond, script) {
  var context = this.context;
  var window = Utils.getDocument(this.context).defaultView;

  var parameters = new Array();
  var runScript;
  // Pre 2.0.0.15
  if (window['alert'] && !window.wrappedJSObject) {
    runScript = function(scriptSrc) {
      var document = window.document;
      var __webdriverParams = parameters;
      var __webdriverEval = eval;

      with (window) {
        return __webdriverEval(scriptSrc);
      }
    };
  } else {
    runScript = function(scriptSrc) {
      window = window.wrappedJSObject;
      var sandbox = new Components.utils.Sandbox(window);
      sandbox.window = window;
      sandbox.__webdriverParams = parameters;
      sandbox.document = window.document;
      sandbox.unsafeWindow = window;
      sandbox.__proto__ = window;

      return Components.utils.evalInSandbox(scriptSrc, sandbox);
    };

On the last line in the function. evalInSandbox....

Irv

Simon Stewart

no leída,
30 jul 2009, 5:32:0730/7/09
a webd...@googlegroups.com
We wrap the javascript that's sent in an anonymous function before
executing it. We also execute it in a sandbox whereever possible,
since we don't want your script to have elevated privileges (because
that makes running the same script on IE Really Difficult)

The bottom block of the method you sent sets up this sandbox, and sets
a couple of key variables ("document" and "window") So, first off:
where is the "dijit" variable? If it's defined as a global (that is,
if it's on "window") then everything should Just Work. A quick look at
the dojo site and an experiment with firebug suggests that everything
will be fine.

I guess the first thing to do would be to see if "window.dijit"
exists. If it doesn't, a small test case would be really useful.

Regards,

Simon

Irv Salisbury

no leída,
30 jul 2009, 6:55:1530/7/09
a webd...@googlegroups.com
In firefox, dijit is available as a high level global variable and off the window as well.  When I saw the sandbox code and researched what that was doing, I tried window.dijit but that said it wasn't a function either.

When I do everything I am trying in firebug, it does work fine.  It is only when I run the same code through Web Driver that I get function not found.

I will put together a small test case and send it out.  

Thanks,

Irv

Irv Salisbury

no leída,
30 jul 2009, 10:48:4830/7/09
a webd...@googlegroups.com
I think I need to do some more investigation.  It literally is working like every 1 out of 10 times.  I tried a page off the dojocampus site and it seems to work everytime with theirs.  It is pretty basic stuff, so I am at a loss for why it works sometimes and not others.  Here is the find method I was using:

    public static WebElement findUsingDijit( WebDriver driver, String identifier ){
        JavascriptExecutor js = (JavascriptExecutor)(driver);
        String script = "return window.dijit.byId( arguments[0] ).domNode;";
        WebElement returnElement =
                (WebElement)(js.executeScript( script, identifier ) );
        return returnElement;
    }

Here is my main method (with different versions in here of various things I was testing ):

    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver( "WebTest" );
        // WebDriver driver = new InternetExplorerDriver();
        // driver.get("http://dojocampus.org/explorer/");
        driver.get("http://127.0.0.1:6080/launcher.jsp");
        /* WebElement element1 = driver.findElement(By.id("container"));
        WebElement element = driver.findElement(By.id("DojoxLink"));
        element.click();
        */
        // WebElement element2 = findUsingDijit( driver, "DojoxLink" );
        WebElement element2 = findUsingDijit( driver, "sb" );
        // WebElement element = driver.findElement(By.id("appCell"));
        element2.click();
        // PaychexHelper helper = new PaychexHelper();
        // WebElement element3 = helper.findUsingDijit2( driver, "sb" );

    }


Sometimes it is fine, other times is says dijit.byId is not a function. 

I am not sure what the "get" method waits for before moving on...  maybe it is a timing issue with my local stuff being cached and faster?

Irv

Simon Stewart

no leída,
30 jul 2009, 14:57:2630/7/09
a webd...@googlegroups.com
The "get" method returns once the "onload" handler is fired. With some
JS frameworks (GWT, for example) this is used as the time for hauling
in more content and setting up the UI using AJAX.

The quick way to find out: if you put a 5 second sleep in, do your
tests become more reliable? If they do, then you can poll the page
until it's ready by calling a basic dijit method and catching the
exception.

Regards,

Simon

Irv Salisbury

no leída,
30 jul 2009, 15:00:4730/7/09
a webd...@googlegroups.com
Yep, that's the path I was on. 

Thanks for all your help.

Irv
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos