7

So, there are multiple products that can let you automate testing interaction with web pages. I have used Selenium IDE for some time now and it works great for creating unit tests for HTML elements on the client side (make sure URLs work, you can access values in the drop-down list etc).

However, I have not found on the Internet any evidence that someone is using any out-of-the-box product for automating testing of web pages that are using ArcGIS JS API.

What I have found:

Consider testing an Editing template widget web page. You cannot capture selecting a feature template and creating a feature on the map using, for instance, with Selenium IDE. This is because those things don't happen at the client side, and the testing software is not aware of JS API and considers editing templates to be just a group of CSS elements.

Of course I automate testing of the feature services via the REST and can verify that the services are capable of creating and storing features, but I am interested specifically in the web page (feature service can be working, but the editing template may get broken and user won't be able to create a feature).

Before I will go and try all trial versions of the testing software that are out there, maybe someone can say if there is a product (can be either commercial or free, doesn't matter) that is capable of recording and reproducing a user page interaction workflow when having functionality from ArcGIS JS API embedded? If recording/playing is not an option, then at least a piece of software that would create a test case with some manual configuration, but without becoming a JS guru.

8

You cannot capture selecting a feature template and creating a feature on the map using, for instance, with Selenium IDE. This is because those things don't happen at the client side, and the testing software is not aware of JS API and considers editing templates to be just a group of CSS elements.

Actually, you can test those kinds of interactions. They are initiated on the client-side and (after some requests/responses from the server) have verifiable client-side results (DOM elements that can be queried by CSS selectors). I have done this sort of functional (a.k.a. integration, end to end, or e2e) testing of feature layers using The Intern (once). You are correct in that the WebDriver API is not aware of the Esri JSAPI and unless you use global variables, you will have to query the DOM (such as the number of paths in the SVG element that represents that feature layer) to verify that the feature was added to the map. This type of testing can be cumbersome and brittle. Furthermore, getting Selenium and the browser drivers installed and working has always been a problem for me

For those reasons, I tend to place an emphasis on unit testing instead of functional testing. I use Karma/mocha to unit test application code that uses the Esri JSAPI. My tutorial on how to do this, is a bit out of date, but should be enough to get you started if you're interested in unit testing. I know your question is more about functional tests, but you mention @dbouwman's blog post on automated unit testing being along the lines of what you are looking for. You can find all the resources from last year's DevSummit presentation (including a video of the presentation) here: https://github.com/tomwayson/esri-js-testing-tools-and-patterns

  • Tom, thanks so much for the input. I've heard of karma and intern, but the github tutorials expect you to be very savvy in JS, which I have only limited knowledge of. Do you think there would be any GUI based product which have those JS library wrapped? Something like TestComplete? I could try to get those examples working, but it is going to be a very steep learning curve. – Alex Tereshenkov Jan 10 '15 at 7:45
  • 1
    I will admit that both functional testing w/ the Intern and unit testing w/ Karma require you to be somewhat savvy about JavaScript and Node, and I don't know of any GUI that wraps them (doesn't really even make sense for unit tests). I've not tried using Selenium IDE to capture interactions for a mapping app, and the only people I know that have tried did not have success. Something like TestComplete is probably your best bet. I know there are teams at Esri that use it to test online maps (I do not). – Tom Wayson Jan 10 '15 at 8:11
  • 2
    The Intern now has a functional test recorder that is more along the lines of what @AlexTereshenkov was asking for. It's available as a chrome plugin. I have not used it (yet). I'd be interested to see if anyone is able to get it to record verification of things like features on a map (i.e. paths in SVG elements, etc). – Tom Wayson Jun 14 '15 at 18:25
4

I just found this post, from your post here and wanted to share some Python code I wrote that helps select a given feature in a JavaScript app. This code is obviously very specific to the Selenium and Python bindings, but I've got good mileage from it across different browsers, OS and screen resolutions.

The idea is that if you

  1. Know the real world x/y of an item: you can get the screen X/Y values by sending JS to the app and get a response with 'return'
  2. Also have a start location of another item (in my case I use the home button on the app in the zoom bar)
  3. Get the app to a known location (again, I use the home button)
  4. Do a simple diff on the XY from the known item (home button) against the item I want
  5. Move the mouse that diff'd amount and perform an action (like click)

Again, this answer is very specific to a certain case, using specific technologies, but I believe it further proves @Tom Wayson point about being able to perform these map interactions.

def realUnits2ScreenUnits(driver, x, y, wkid, refEle):

  #Pass JavaScript to the client browser to get screen units based on its real world location

  jscode = '''
    var realPoint = esri.geometry.Point({"x":%f, "y":%f, "spatialReference":{"wkid":%d}});
    sp = map.toScreen(realPoint); return ({'x': sp.x, 'y':sp.y}); ''' % (x, y, wkid)

  screenXY = driver.execute_script(jscode)  

  return screenXY

def offsetMouse(driver, startEle, offSetXYDict):

  #Moves the mouse from one element to another based on XY offset
  #Returns the move obj: you can then d-click, click, further move, and perform

  xdif = offSetXYDict['x'] - startEle.location['x'] + 3
  ydif = offSetXYDict['y'] - startEle.location['y'] + 3
  print xdif, ydif
  move = ActionChains(driver)
  move.move_to_element_with_offset(startEle, xdif, ydif)  

  return move      


homeButton.click()  #reset map to center
screenXY = realUnits2ScreenUnits(self.driver, -9816122.81720005,5126627.9475767734, 102100, homeButton)
move = offsetMouse(self.driver, homeButton, screenXY)
move.click()    
move.perform()
  • 1
    +1, always great to see people share knowledge =) – Joseph Apr 20 '15 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.