-
18 Dec 2012 2:17 AM #1
ExtJS functional testing - get internal elements of extjs controls
ExtJS functional testing - get internal elements of extjs controls
Hello everyone,
We have decided to use Sencha ExtJS for the client side of our new products and we plan to do automated functional testing on the client side. We looked into several tools like Ranorex, Selenium, Telerik Test Studio etc and so far we like Test Studio more than the others. Anyway, the question I am asking is relevant no matter which of these tools one might use.
I am interested to find out what is the recommended way to get internal elements of extjs controls. In order to be clear enough I will give an example.
I have a numberfield control and I would like to test that if I clicked on the 'up' button the value in the field will increase by one unit. Note that I did set an unique ID to the number field (id="testDurationHourNumberField"). The number field has the following (simplified) DOM structure:
In order to do this I must access the input element (id="testDurationHourNumberField-inputEl") and the button (id="ext-gen1211"). How is the recommended way of accessing these 2 elements?Code:<table id="testDurationHourNumberField"> <tbody> <tr id="testDurationHourNumberField-inputRow"> <td id="testDurationHourNumberField-labelCell"> <label id="testDurationHourNumberField-labelEl">Label:</label> </td> <td id="testDurationHourNumberField-bodyEl"> <table id="testDurationHourNumberField-triggerWrap"> <tbody> <tr> <td id="testDurationHourNumberField-inputCell"> <input id="testDurationHourNumberField-inputEl"> </td> <td> <div role="button" id="ext-gen1211"></div> <div role="button" id="ext-gen1212"></div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table>
So far I have the following options:- Use ExtJS internal IDs - does NOT seem good because:
- These are internal IDs, they are out of my control and they may change if I will later add another control on the page
- It seems that for the same page I get different IDs in different browsers. For example in IE 10 I get different IDs for the buttons from the IDs I get in Google Chrome.
- Get controls by unique ID and get internal elements by knowing their internal DOM structure or attributes - does NOT seem good because:
- I would rather not use this way because I do not know that when upgrading to the next version of ExtJS the internal DOM structure won't change or some attribute names will change and I will have to update the tests that I created
- eg pseudocode: getById('testDurationHourNumberField').getElementByAttributeAndIndex('role=button', 0)
Thanks,
Paul
- Use ExtJS internal IDs - does NOT seem good because:
-
20 Dec 2012 7:24 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,656
- Vote Rating
- 435
Each component has an el property on itself when it has been rendered. That Element class can use the down/query methods to resolve other elements...
comp.el.down('input') to get the <input>Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
21 Dec 2012 2:12 AM #3
I had the same problem some time ago, so I decided to add CSS-Classes for all Components (cls-Property).
For me every...
- View has a reference, so I add "prefix-ref-reference"
- Field has a name, so I add "prefix-name-name"
Now for the CSS-Selector I simply put those together ".prefix-ref-reference .prefix-name-name .x-form-field", that's it!
-
21 Dec 2012 7:00 AM #4
Thanks for the solution!
Still this seems to be based on some internal class of Extjs, in this case "x-form-field". If, on a later upgrade of ExtJS, this class will be removed than the test suites will fail, so there is a risk of backwards compatibility. But hopefully that class won't be removed or renamed too soon so this might work.
Do you have a similar solution for the elements that are not fields? The solution proposed seems to work only for fields...like for buttons, I did not see a similar class, other than "x-btn-center", that is set on the "button" html element.
Regards,
Paul
-
3 Jan 2013 5:20 AM #5
In my post I said that I am aware of a similar solution, which is to get internal elements by knowing the internal structure of extjs controls. Also in my post I explained why I do not like this solution very much. Is there any other way of doing this without relying on something internal to ExtJS that I have no idea when it will change?
Regards,
Paul
-
3 Jan 2013 9:07 AM #6Sencha - Community Support Team
- Join Date
- Nov 2007
- Location
- Helsingborg, Sweden
- Posts
- 2,455
- Vote Rating
- 52
Paul, did you try Siesta? It tries to solve this exact issue. Using Siesta, you can target components, component queries, CSS selectors etc which makes it so much easier to do functional testing.
-
4 Jan 2013 3:29 AM #7
Hi,
I am aware of Siesta but using it would mean that we have to manually code the test suites.
We are more interested in using some tools that incorporate an action recorder (eg. Telerik Test Studio, Selenium, RiaTest), which means that the user records the tests and just plays them afterwards. This way these test suites can be done by our QA engineers without much manual code being involved.
The issue is that these tools operate on the DOM but ExtJS actually generates the DOM so I have no guarantee that the tests I recorded will still work after I change some parts of the GUI or I upgrade ExtJS.
I am asking on this thread for the recommended generic way of getting internal elements of ExtJS controls so I might be able to create a plugin for these automation tools or alter the way the action recorders generate code - to make life easier for QA engineers.
Thanks,
Paul
-
7 Jan 2013 4:29 AM #8
I am thinking right now of another solution...
The solution would imply that we can override the way ExtJS generates IDs. Is there any support for this?
As an example, let's say I have a number field, and programatically I will set the ID = "testDurationHourNumberField". Currently ExtJS generates the following DOM structure:
I would like, if possible, to have the ID that I set programatically as a base ID for all internal elements within the number field control.HTML Code:<table id="testDurationHourNumberField"> <tbody> <tr id="testDurationHourNumberField-inputRow"> <td id="testDurationHourNumberField-labelCell"> <label id="testDurationHourNumberField-labelEl">Label:</label> </td> <td id="testDurationHourNumberField-bodyEl"> <table id="testDurationHourNumberField-triggerWrap"> <tbody> <tr> <td id="testDurationHourNumberField-inputCell"> <input id="testDurationHourNumberField-inputEl"> </td> <td> <div role="button" id="ext-gen1211"></div> <div role="button" id="ext-gen1212"></div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table>
This would mean, that I would somehow be able to specify that the up and down buttons will have the IDs "testDurationHourNumberField-upButton" and "testDurationHourNumberField-downButton".
In other words, I want to get rid of all these ugly ExtJS generated ID like "ext-gen-1500", which don't mean anything. The desired DOM structure with the nice IDs would be the following:
This is a way to avoid randomly generated IDs and at the same time keeps IDs the same no matter what browser I am using.HTML Code:<table id="testDurationHourNumberField"> <tbody> <tr id="testDurationHourNumberField-inputRow"> <td id="testDurationHourNumberField-labelCell"> <label id="testDurationHourNumberField-labelEl">Label:</label> </td> <td id="testDurationHourNumberField-bodyEl"> <table id="testDurationHourNumberField-triggerWrap"> <tbody> <tr> <td id="testDurationHourNumberField-inputCell"> <input id="testDurationHourNumberField-inputEl"> </td> <td> <div role="button" id="testDurationHourNumberField-upButton"></div> <div role="button" id="testDurationHourNumberField-downButton"></div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table>
I would actually suggest that ExtJS switches to this approach as I do not see any flaws right now and evidently would have the customers happier (as there are many complaining about this!)
Can the ExtJS dev team tell me if overriding the way ExtJS names the IDs is possible?
Thanks,
Paul


Reply With Quote