2

We have a rich UI application developed using sproutcore. We are trying to automate the pages using Selenium webdriver in Ruby. With dynamically generated id's and hidden items we are finding it difficult to identify some of the elements. Application is complex. Developers are saying they cannot add unique layer-id's for hidden items or frames. For static pages, they added unique layer-id or class names.

I want to understand from my friends here about what automation they are using for their sproutcore applications? How are they tackling these issues?

Any pointers are appreciated.

Ratnakar
  • 163
  • 1
  • 6

3 Answers3

0

Even if the web elements are

dynamically generated id's and hidden items we are finding it difficult to identify some

One solution is to ask if developers can add naming pattern for them, so just last chars to be generated on-the-fly. By doing this you can use some of these location approaches:

Community
  • 1
  • 1
ekostadinov
  • 6,880
  • 3
  • 29
  • 47
0

An approach that will work with SproutCore is to use the SproutCore view tree to identify elements rather than by layer ID or class. For example, consider this basic main page,

MyApp.mainPage = SC.Page.create({

  mainPane: SC.MainPane.extend({

    childViews: ['header', 'mainContent', 'footer'],

    header: SC.ToolbarView.extend({
      layout: { height: 44 },

      childViews: ['headerButton'],

      headerButton: SC.ButtonView.extend({
        layout: { centerX: 0, centerY: 0, height: 40, width: 100 },
        title: "Click Here"
      })

    }),

    mainContent: SC.View.extend({
      layout: { top: 44, bottom: 33 },

    // etc.

While we don't know the layer ids of these elements beforehand, we do know their parent child relationship in JavaScript. For instance, if I needed certain elements from the page, I'd probably grab them in advance like so,

// Retrieve target views for the current page.
var mainPane = MyApp.mainPage.get('mainPane'),
  header = mainPane.get('header'),
  headerButton = header.get('headerButton'),
  // … etc.

// Then retrieve an element for acting upon.
var buttonLayer = headerButton.get('layer');  // returns a DOM node

// Or retrieve an element id for acting upon.
var buttonLayerId = headerButton.get('layerId');  // returns the auto-generated id

Although I don't have firsthand experience with Selenium, it appears that you can use the execute_script WebDriver instance method to run some simple lookups that return either the element you need or the id of the element you need.

Finally, bear in mind that some views may have dynamically changing children, in particular SC.CollectionView subclasses like SC.ListView. In this case, once you target the parent view, you can access the child that you need easily enough using methods particular to that parent view, such as itemViewForContentIndex(idx) to get item views of a list.

0

I use selenium to automate (via Jenkins) some QA testing for a Sproutcore app and in my experience it is usually enough to add specific class names to the Sproutcore objects and then use xpath expression in Selenium to target those classes.

Example:

bottomRightView: SC.View.design({
        classNames: ["bottomRightView"],
        layout: { top: 60, width: 299, bottom:50, right: 15, zIndex: Maps.RIGHT_TOOL_BOX_PANE_ZINDEX },
        childViews: "resultsView noResultsView buttons featureView".w(),

Xpath expression:

xpath=//div[contains(@class,'bottomRightView')]

It is always possible to use //@if(debug) statements to exclude those classNames from production builds.

Example Selenium IDE scripts for above mentioned app: https://github.com/unicolet/mappu/tree/master/tests/selenium

unicoletti
  • 204
  • 1
  • 8