PushToTest - Open Source Test

An Excellent Future For Building Rich Internet Applications

An Excellent Future For Building Rich Internet Applications

PushToTest built the TestMaker Editor using Rich Internet Application (RIA) techniques. The result is a single code base for an application that runs on Windows, Linux, Unix, Mac OS X, iPhone, iPad, and Android platforms. This is a briefing for technical team members to understand how we used Open Source application development tools (Appcelerator Titanium, JQuery, Sencha Ext-JS, and Javascript) to build the TestMaker Editor.


Register for new screencasts and webinar announcements


The Camtasia Studio video content presented here requires a more recent version of the Adobe Flash Player. If you are you using a browser with JavaScript disabled please enable it now. Otherwise, please update your version of the free Flash Player by downloading here.


Watch new screencasts

An Excellent Future For Building Rich Internet Applications



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Frank Cohen: Hi, this is Frank Cohen. I'm the CEO and founder at PushToTest. What you're about to see is a Screencast of a conversation that PushToTest had with Andrew Zuercher and Ali Faiz of Zuercher Tech. These are the constructors or the builders of the new TestMaker Editor. We put together this Screencast so that software developers and testers that are interested in building rich internet applications and ones that use service-oriented architecture techniques would be able to learn from the PushToTest experience building the new TestMaker Editor. We intend in this Screencast to introduce the goals of the TestMaker Editor project, to introduce the core development concepts especially as they pertain to our use of JQuery, Appcelerator, Titanium, and Ext JS. We'll also be presenting a cookbook of techniques to build this editor that you might be able to apply to your own rich internet application and AJAX development. We'll also cover debugging techniques and also examples of how to modify the editor.


TestMaker 5.4 moves TestMaker architecturally away from any of the previous versions of the product. The new TestMaker 5.4 will be based on AJAX techniques for delivering a rich user experience. In TestMaker 5.3, users have to hand edit XML document that define a TestScenario. A TestScenario defines everything TestMaker needs to know how to orchestrate a test as a functional test, a load and performance test, or as a service monitor. With TestMaker 5.4, the new TestMaker Editor delivers a graphical user interface for configuring those TestMaker Scenario files. The TestMaker Editor will run as a desktop application external to TestMaker. It's implemented in AJAX using Ext JS visual components, Appcelerator Titanium, and JQuery. The TestMaker Editor will be able to still load and save TestScenario files from the local hard disk volumes. This is in first preparation for a future version of TestMaker that will come with its own repository of TestScenarios. In TestMaker 5.4 the TestMaker Editor will edit files that conform to the TestScenario XML Schema Definition and this slide gives you our URL where you can find that, that schema definition.


In this Screencast, you'll hear several participants' voices. These are a combination of voices from Zuercher Technologies, the subcontracting company that actually built the TestMaker Editor. Group Avantica which is the company that PushToTest outsources its engineering to and also myself, Frank Cohen, CEO at PushToTest.


The URLs that you see on the screen allow you to download the TestMaker Editor and start using it today. You can also download TestMaker itself and also the TestMaker Editor source code. PushToTest is an open source test automation company and we greatly encourage your participation in our open source project. The ways that you could participate include finding bugs and surfacing t hem so that we can work on a resolution. You can also make improvements to the code yourself in which case we'd ask you to contribute those improvements back to the community.


This is the PushToTest TestMaker Editor in its current incarnation. You can see that it's installed as a desktop application and it gives you dropdown menus, it gives you kind of a nice splash screen. If you want to immediately edit functional test, here it is with the tabs appearing on the top. Here's resources, for example, I could identify a Selenium test that I wanted to use and add additional resources. Under use cases, I then could schedule in that Selenium test like this, identify the selenese file. I can even data-enable this test by injecting operational test data from CSV files or from relational databases or a number of other sources. I can identify which test nodes would be able to operate this test and I can also have this test run on a cloud environment like the PushToTest on-demand service. So if I wanted to run on, say, 100 different testnodes, that's how hard it is nowadays. I also have monitoring and then different options. At any time, I can also click down here and see the original XML version of that TestScenario and make changes to it.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Andrew Zuercher: All right. Excellent. Well, thank you for having us here. What we're about ready to go over is some of the general cookbook of recipes for how to make modifications to the Appcelerator Titanium based application that we developed for PushToTest. For introduction purposes, I'm Andrew Zuercher, founder and CEO of Zuercher Technologies and...


Ali Faiz: And I’m Ali Faiz, principal consultant, Zuercher Technologies.


Andrew Zuercher: And over the past month or so we've built this desktop application for PushToTest. If you'd go to the actual project itself in some version, we've got some directory called cookbook and in that folder what you can see I've got up on the screen here in front of you are various links for the various recipes that we've created so far. Our orientation was really to try to get a good cover of the implementation, how to make modification system, as well as some things that really aren’t necessarily specific to our application or almost maybe even with desktop web development in general.


So without further ado, let's move into our first item that we want to cover which is how we define model objects. So in our application we have essentially three different states that are important for the implementation of the solution. Well, it's going to be the view so it's going to be almost the standard model view controller type of approach. The view aspect of it is going to be the actual HTML DOM elements themselves. Underneath the scenes we capture a Java object level what we call model objects which are stored at the file object level which is an ability which allows us to be able to switch states between different files in the application. And in the final view is the rendered view in XML which is what we use for displaying in the text editor and also the native formats that we use to be able to load files from your desktop or from your file system.


So we're going to the generic model definition. It's a pretty simple recipe that we've used. We implement something called the ArrayUtil object and it has three primary responsibilities to allow us to capture objects. Like I said before, all objects are defined at the file objects level. So we define them as simple arrays. An ArrayUtil allows us to be able to manipulate and access those arrays in a standard fashion. So if I go over here in the application, these are ArrayUtil objects. Primarily, it takes the array that you're going to use and then it's also going to take the id element. I'm talking into too much details here. Out lookup allows us to build to look up by index id and also to be able to do a lookup by an attribute name as well. Likewise, we will offer destroying of objects in arrays using the delete_object method and then the creation of objects using the add_object. The add_object method allows us to id generation which is pretty important for us to be able to do selector based implementations and as well as be able to correlate form objects to model objects in the application. You'll see that outside that there's going to be some top level definitions for others.


So I'm coming back over here. When we reset or create objects right here, we find some pretty simple top level objects would correspond to the same naming conventions that you see in the forms or the application itself. Outside that there are lots of other objects that are going to be created, instantiated, and captured but they're not going to be captured as top level. So we use a composition approach to be able to deal with those aggregates. At a high level, kind of gives you an idea how it is the ArrayUtil functionality is implemented. Moving onto another kind of generic concept is the concept of Lambda expressions.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


So lambda expressions are computer science content. They imply the ability to be able to export behavior to a function and extremely prevalent in dynamic languages such as Scheme and JavaScript. Ruby makes use of them and a lot of other languages. Well, an extreme powerful technique especially for us you'll see that it's used extensibly in the JQuery API itself and is particularly useful for dealing with asynchronous invocations where you need to export some sort of behavior and that becomes the parameter. So if you're not familiar with it then you will become immediately familiar with it by using the API that we've implemented for our internal solution here and also if you view JQuery extensibly you'll find it's very prevalent there.


Frank Cohen: When I looked at this initially, it seemed like writing super, a constructor within a Java class.


Andrew Zuercher: Yeah. Definitely we'll be different than that. I think if you come from a Java world the closest thing that is going come to it for it's going to be some concept of anonymous classes. It gets passed into creation of a thread. So really what you're doing is you're exposing to the instantiation. Just trying to give you a Java console because I know you guys are Java guys. If you were to provide that type of anonymous, what you're doing you're exporting basically an implementation for a type of interface as an anonymous class where you're exporting the run portion of it through the thread so he knows how to be able to invoke it.


So typically, what's going on is internally in Java you accept a tight interface or subclass as a parameter and then you know to call on to a particular method within that interface. Really what this is doing, this allows you to create functions or use functions as first class objects. It's almost as if you're passing in a call back or a function pointer. Obviously, that shows the implementation detail. Some languages imply and allow for that as a natural language aspect rather than as interface or an API definition. In our case, we use it all over the place so you'll see some of the terminologies. You'll see lambda is the name of the parameter in a lot of cases and the reason for that is because we comp sci reasoning behind it.


So moving into it there are two pieces to this. One side is the callee and the other part is the caller. So the callee is going to be, for example, JQuery implements a $.get which I defined here. It's very prevalent. And the reason why we implement that, what the $.get does is it goes out, invokes a service for creating HTTP request or maybe a local power request, whatever, it pages the URL and then synchronously later on after that's complete is going to then call method that you pass into it or be able to like for you to be able to handle what happens upon final fetch of that particular URI. So in our case, we've implemented something called read_xml is the name of our function and you also notice that we take in two parameters. One is going to be the filename and the other one is going to be lambda which is the function to invoke. So if you look at underneath the scenes, we get the file, store that into XML and then basically we call that function, that lambda function or expression, with the parameter of the XML that we fetched. That's the callee standpoint.


The caller or the invoker of the method is going to be responsible for defining the lambda expression itself which is the anonymous or the function or the behavior that you're exporting to the function. So in our case, we're making a call to read_xmlfile. We pass in the filename. We also pass in our behavior which is this piece right here is our behavior. So I hope this kind of makes sense. For some people, it's a little bit -- it's a new concept to be able to pick up but it's extremely powerful and actually you get to use it for a little bit. It comes as second nature. If you got some questions as I start to go through some of this stuff, please feel free to ask.


Frank Cohen: Okay.


Andrew Zuercher: Moving on to the next piece here. Did somebody have a question?


Frank Cohen: No, I just want to say it's okay and we will be asking questions.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Andrew Zuercher: Okay. The next piece is how to style the application. As you can see, we're here from the fundamental concepts before we start to dive into anything application specific. One of our key things within the application is obviously to be able to style the application we leverage CSS throughout the app. You will not see any inline styles in anything that we've done and we've defined everything into a single style sheet. I think it's important for people to understand what the implications are and how to be able to use those style attributes. And for that I put a link up here to the -- there'll be schools. This is probably the number one hit if you have to Google. What's the right place to go for CSS reference? And the other piece of it is going to be selectors and I think the selector piece is the part that's maybe not extremely well-documented or people like just barely know enough to be able to get by with the finder style sheets. The selectors are really the most powerful piece of it and I think it's extremely important to understand how it is that you make use of that. So between the CSS itself and also with the JQuery stuff which we'll get into I think a little bit later on when we talk about loading and saving. We make use of selectors for being able to query or define both styles to apply to DOM elements as well as to be able to execute JQuery functions with JQuery as well. It's not necessarily a coincidence at all that JQuery made use of the CSS selectors syntax.


So moving on in here a little bit onto the actual style sheets that we've defined. So you notice that for a lot of panels we've defined them using a naming convention of xxx_container. So let's try and get back to the styling piece here. I want to show you that what we usually do is I'll go in here and you can too select a particular element that you want to inspect. You can either right-click and click Inspect Element right there or the other thing that you can do is you can click this little icon right here and then click the item that you want. So now you'll see that the class on here is resource_container.


So just getting back to what I was saying before is the inner style sheet itself we have a generic definition for all the containers which is right here and then we also have something that's specific for the individual containers that tells us, for example, the caller. In case for resource it doesn’t really have a heck of lot. You can Firefox this pretty cool and you can take a look over here and it will tell you what classes and what attributes have been applied or not or have been overwritten for the particular element that you've selected. So right now I'm currently selecting this particular div and it tells me that the way this is and that the padding which is on this particular line in the style sheet is being applied and the rounded borders are applied. Mozilla specific style sheet attributes are applied for being able to give us this nine rounded look to it.


Frank Cohen: I'm sorry for the interruption, Andrew, but you're at the higher screen resolution again. And so for the recording, you're bleeding off the edge of the recording area.


Andrew Zuercher: Sorry about that.


Frank Cohen: No problem.


Andrew Zuercher: My apologies.


Frank Cohen: No sweat, man. I'll edit that out so don’t worry about it.


Andrew Zuercher: Okay. So the interesting thing about all this is you'll see that we're pretty consistent in how it is that we've defined this and it's reusable so you can get these -- these changes will be cascaded throughout the application. Well, we strive to make sure that when we define the content that we use a pretty structured approach to it. So in our case, not only use the container also pretty well-defined but also if you take a look at underneath we used tables to be able to lay out the individual attributes.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


So resource type then is control and there's another column over here. You'll see that we defined all this stuff pretty well in that the -- we have a selector that allows us to build, say, for this particular container the table that's inside of here to be able to put the spacing so to speak and is consistent throughout there as well. So I think just take a look and get used to understanding how to inspect it as a starting point. I usually don’t go and look at the actual style sheet itself. I'll look in Firefox or Firebug to tell me what style sheets are being applied and then they'll help me to get a better understanding for how this power changes out for a particular element. But as we laid out and implement the DOM rendering as well as the style sheet definitions we try to make it pretty consistent.


Frank Cohen: By the way, I was just hearing a usability lab of the editor this morning with one of our customers and she was extremely complimentary about how clean everything looked.


Andrew Zuercher: Excellent. Yeah, it's something we try to strive for initially is sparse and clean. I think that true design elegance comes by simplicity. We'll be back in here to the items I wanted to cover. I covered here how the selectors are applied, something like one of the good places to look for references, how you can use here and your Firefox defines how is it that you can use the plug-in. Once you've got the Firefox plugged in inside then that's a great way to be able to inspect and build value to your application. That's what we do. You can also use Safari and WebKit allow you to build to inspect styling. I think that you can also manipulate the styling as well but I just don’t feel personally that comfortable with it. I like Firefox a little bit better. That's where we're at with that.


Frank Cohen: It looks like the built-in Titanium debugger is basically Firebug but kind of deconstructed.


Andrew Zuercher: It's WebKit underneath. So here I'll show you.


Frank Cohen: You know, don’t spend any time on this but I think recommending Firebug is the best practice.


Andrew Zuercher: Yeah. Now, it's actually WebKit which is the same -- which is basically the same like that core product that Safari is based on as well and that's why you'll see that the styling will look different and Firebug is not much different because they're both -- they're pretty close to each other to be honest. That big one that is completely different that has a big market share, of course, is IE but if I would to do with Titanium we don’t have to worry about that issue which is huge.


Okay. Now, I think the next piece I'm going to do is I'll turn it on over to Ali and let him go over adding a subtemplate. So maybe we can -- can I give control to Ali or do you have to do that, Frank?


Frank Cohen: Yeah, you can.


Ali Faiz: So the subtemplating is built on the template system that we have gone over in some of our postings. The templating is the way of injecting repetitive -- so one of the issues we found was that we wanted to roll through an array and post a list of different elements but they all are the same common elements. So now you know this, of course, the resources or data source or anything near the tabs basically. It's just a repetitive HTML snippet with different elements inserted into it. So that's kind of a background of the templating.


Now, to go into subtemplating where you're inserting templates into templates is where it starts to get a little tricky. That's where the -- the templating is pretty simple but the only thing to -- how you want to -- especially for use cases and that's what we're using in this example. It gets a little bit more tricky and a little bit more complicated but it's pretty simple if you kind of follow this kind of instructions.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


So if you look at the usecases.html file under Resources/content, you'll see there is div class = "usecases_iterator" and that's just a placeholder for what we're going to subtemplate into it and that's the usecasestemplate.html. So if we look at Resources/content, for every HTML file we have a template. So even for the simplest one which says something like DataSources, you have a DataSources template which is really just a subtemplate if you think about it. So in our example, usecases, we have this div class = "usecases_iterator" and the templating is in usecasestemplate. So in usecasestemplate, the HTML here and it's -- you can see there's the -- we have a hidden usecase id value. We have a name the delete button sequence, the things that you find in the usecases tab. So when we do our template injection, we're going to read that usecasestemplate file and append it to the usecases.html and usecases_iterator div for each one in the usecases array. So this is really just the code that we use to actually do that injection and appending. So you can see here we have usecases array and we iterate through it then we have the usecasestemplate and we grab the individually used case and are inserting that information into this usecasestemplate and then appending that to the iterator.


Luis Carlos Lopez: Ali?


Ali Faiz: Yes.


Luis Carlos Lopez: This is Luis Carlos. I got two questions there. The first one is, is this automatically -- I mean first -- you need to write this injection function every time you need to create an iterator or is there a template to create an iterator? And then the second one will be could you show me the interface where this iterator is located so I can see which file?


Ali Faiz: Well, there are sub-posts on our blog and I don’t know if -- Frank, have you forwarded that information to them?


Frank Cohen: No, I haven’t.


Ali Faiz: Okay. Some information there and then there's -- the way that you -- this is all pretty much automated. You didn’t have to create a function to insert values from this usecase and to this template. And the template is really just this right here. It's this file. So when you do an append, it just automatically inserts this object's data into the template then append that to this iterator.


Andrew Zuercher: So maybe I can jump in here a little bit. I'm sure Entourage used the prototype templating mechanism and in our case we used JQuery plug-in for using the templating mechanism.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


The upside for what it is that we have is if you don’t use a templating approach then you have to do direct DOM manipulation and when you do that it's hard to be able to understand what the layout and the design looks like. If you don’t use that then you're probably going to be doing a lot of string manipulation and that's also ugly and tedious as well. We use the approach for using the templating mechanism so that if you look right now to see all these files underneath content that have an underscore in front of them are templates that we use. So what we do is we'll take a model object, just kind of going back here to what Ali was talking about. The code you'll see. When you do an append right here, what it does is it takes the output from the template, take the model object as a parameter, it will bind those together and it will create a new rendered string that is used to be able to append or insert into the DOM.


So from our standpoint, it's very simple to be able to figure out what that point is and which you want to build to have the aggregates show up. In our case, it's in the usecases_iterator right here. So just kind of going back real quick. Going back in here you'll see that the usecases_iterator, this is where we include all the usecases. So at a high level, if you look right here because essentially there's a big DOM element right here which is where we included all these usecases themselves. So I'm not so sure if that helps out or if you still have questions. Does that help answer your question?


Luis Carlos Lopez: That answered my first question. The other one was about the place that points to locator because you have the -- okay, you have the usecases there and you have the template there. But where do you -- what should you have in there? Is there a document there? Is it a portion where you fill that out? And I would like to know, where is that portion in the call?


Frank Cohen: So that the overall structure is that you have an index.html page that the browser loads and then editor.js is the single file with all of the JavaScript in that.


Andrew Zuercher: So based upon the current implementations, line 937, and where it is that we call the template is when we're going to render into the DOM. And so from our standpoint that's whenever we go from the model objects to the DOM, and so the two places that we do that are when we load a file initially or when we transfer from the XML editor back to the forms view. So those are the two places that whenever we're going for the model object to the actual DOM and inside, in this line 937 I have in front of me right now is editor.load_usecases is where this happens. So if you take a look here, that snippet of code that Ali was showing you.


Luis Carlos Lopez: That makes a lot of sense, but one other question. Should you have like the functionality to create an iterator? So the best practice for us will be to -- every time we create an iterator or another functionality that's query related, should we put it there -- here in editor.js?


Andrew Zuercher: I'm sorry. I don’t think I quite understood that.


Frank Cohen: Let me try it. So Andrew, the question is when we want to create additional iterators, should we just toss them into the editor.js file?


Andrew Zuercher: Yeah, absolutely. So it depends on where it is that you want to do that. So if you're -- let's say you're creating a new type of component or something like that then you're probably going to be defining -- you need to know where the insertion point is going to be. In the case for use cases, it goes here, right? And what we do inside that we render this. But we have tests that are inside of use cases. So it's really a two-part piece.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


So kind of getting back to what Ali was saying before is that you need to find where within -- either at the top level. So for our case, usecases_iterator is the top level iterator place where we insert that into the DOM or to being a sublevel which is what I was just showing you before which is here for like the test_iterator. So for each use case we implement this and then we have a test, inside the test you can have stuff inside of that. You need to be able to define inside the HTML so whether it be in a template file or a top level file, you need to find it there and then you also need to implement inside of either -- if it's a top level loading then you need to define it in your editor.js you'll see that we have load_usecases. You need to make sure it gets called appropriately for that or implement as a subchild inside of one of these. Let me point it here. I want to show you that in addition to the dealing with that, once we've loaded a use case, we also load the test for a particular use case. So that's how we chain aggregates and if you take a look at that you'll see that the JavaScript code itself is extremely consistent across all this. It's the same type of approach. Does that make sense? Does that help answer the question?


Luis Carlos Lopez: Yes, that's the answer I was looking for.


Frank Cohen: Yeah. Excellent. Sorry, Ali. I didn’t mean to hijack you there.


Ali Faiz: Okay. So after the append -- I was going to actually cover the subtemplate and how the subtemplate works. So it's very similar. In this code right here you'll see a div class = "tests_iterator" and the usecasestemplate.html and that is going to treat just like we treated the usecases_iterator. So this call to load_tests will do something very similar to what we're doing right here except that's going to use the tests array as opposed to the usecases array. You can see how that interaction displays -- we have this -- we have the usecasestemplate and then we have the tests_template and the even further we have the arguments template inside of that. So that's like an argument. So that's kind of the templating for usecases and how subtemplates works.


So I believe the next one is Andrew's.


Andrew Zuercher: Yep. So the next one here that I'm going to about is I'm going to talk about how to add tabs to the application. This right here is our Ext JS app widget that we're using. I'm going to cover just real quickly how it is that you're going to do that. Let's say you want to add another tab and we'll call it stuff. The first thing you need to do is you need to create a div. So we kind of go through here. We'll try to do this one on a fly. If we look at the index.html, the very bottom here, let's say that we've got divs that are kind of in a hidden way. The reason for that is they need to be top level divs that we're going to move around so that Ext JS moves around inside the documents for it to be able to work.


So I'm going to create a new div. I'm just going to call it stuff and I'm just going to leave everything else. It's kind of consistent. Then we'll go through some of the snippet further on. You can see a tab and all that other stuff. So I create the div here. The next step that I need to do is I need to create the content file for my new tab. So for all the tabs that we have right now, there is a name right here at the top level. So datasources, general, monitoring, options, resources, testnodes all correspond to an individual content file that represents the actual content behind these individual apps. Let's create a new one.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Then the next piece of that is I need to change and I need to wire up Ext JS to be able to know that he has stuff as another tab. So we're going here to editor.js and whatever order I have in here is going to be the order that it's going to show up as far as being able to be rendered. I'm going to give the name or the title of this stuff. Let me just give it the name stuff. Content is going to be stuff. That's an image of the div element that I just created. Here is what the title is going to look like. It's going to be called stuff. So the three different definitions here required me the data that the editor.js uses to do all the stuff. This is the next piece that I need to do. Just going off here is I need to call a load content for my stuff. So I'll show you the init method here.


Do you see how we change here? This is kind of goes back to what I was saying before for lambda expressions. This is the way how you change asynchronous methods altogether. So we're back here. So what I did I just inserted this little content for stuff that's part of the chain. And that's all I need to build to see my new stuff guy. So I'm going to ahead. I'm going to refresh it. So above and beyond outside of that is going to be stuff that's not necessarily Ext JS specific but I just want to give you guys an idea of how you do this to be able to add the tab. The div element is modifying the Ext JS to be able to know about that element and then using our templating mechanism to be able to load the new template that you defined or content file that you defined. It's not really a template.


Frank Cohen: That's nice.


Andrew Zuercher: Yep. The next piece is loading XML to a model and into a form with Ali Faiz.


Ali Faiz: Okay. So the way that we -- there are paths to get to displaying that form editor is we have to load from the XML to this transitionary model which is in all the arrays that we have and then using that model to display in the UI. So we've gone kind of over templates and that's really how we display in the UI but to get to that point we have a piece that we have to get to. So first of all, obviously we read the XML from a file. We didn't really cover that here but just assume that we've read an XML string from a file. So after that file is read the caller function called load_xml and in load_xml we strip the elements we want to use and the way that we do that is we have this $ notation from JQuery that just takes that string and basically objectifies, I guess might be the correct word to use for it. And once we have that object we can use the wonderful JQuery functions like "find" and "each" and "attr."


So first of all, we're going to find the basics and that's just grabbing kind of the scenario name and the default directory from the XML. You can see that going on right here. So first we -- the spacing is a little off but what we're doing is saying that basics, this low local basics variable is equal to $(this) which is coming from this (xml).find('basics').each. So that's just grabbing the basics object, for lack of a better word, from this XML object.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


So right here you can see we do an array lookup. We have this array valueoptions which has basically all of the kind of static options that we need to display in the UI. We populate it with the name data from the basics element and then we also populate the default directory. But really the meat of what I'd like to show today for this section would be testnodes. So the testnodes in the XML -- so the XML for one of the examples that we can look at -- I'll just pick a functional scenario. So you can see again the basics with the name and default directory. For testnodes, you have a node and that node has a name and a location. There's also a possible call that could be under these testnodes. So if we look at what we're doing in this function, so we grab the testnodes element. We set that local variable to the testnodesxml and for that we're going to find each of the nodes that is under that testnodes element.


And for that we're going to do this kind of complicated -- well, not complicated but it's just kind of long. We're going to create this object based on the attributes in that node. So we can grab those attributes by saying (this).attr and pass it that the name of the attribute we want to get. So basically, we populate name, location, and monitor which the example that we have there is not monitor but that's also possible as being there. So that's kind of the quick way that we're able to populate that testnodes array, the data from the XML. We can see we do a similar thing for cloud and this is basically what we do for all the other data types. We have data source, resources, et cetera. There's a little bit more complication depending on if there's levels of children that we have to go through but it all basically boils down to this.


Andrew Zuercher: Let me jump in there real quick. I just want to jump into what Ali was saying and give you a little bit more clarity. This .each lambda expression or caller is something that's defined by JQuery. What JQuery does is it binds that this argument or that this sculpt name into the function callback for you. So that's something that's kind of unique to JavaScript is that you can bind what this means to a functional skill. So that's why there's -- we see here in our definition for the function that he doesn’t have any parameters at all but he does and he automatically tells you that the element that you're iterating through in the .each is going to be bind to this. That's why you see (this) right here it's different than (this) right here is because this is lambda expression for iterating the basics and right now we're iterating the testnodes inside of the basics.


Ali Faiz: So does that make sense?


Frank Cohen: It does to me.


Luis Carlos Lopez: So what you're saying I think is like HashMap from a -- drawing a HashMap to the find the testnodes that HashMap has the names of the use of the nodes and you're getting -- that's using its functions, right?


Andrew Zuercher: Well, it's actually -- it's a collection so it's not really a HashMap.


Luis Carlos Lopez: Okay.


Andrew Zuercher: So the .each can basically -- it has an array or collection. So what we're doing is we're iterating through the XML DOM node and so his .each is iterating through a set of child nodes.


Luis Carlos Lopez: Pretty clear.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Andrew Zuercher: Okay. Excellent.


Ali Faiz: Okay. So after we get the data into the model we have -- there's a load all function that actually calls all the loads. But basically what they do is they load the model to the form in the UI. Since we're talking about testnodes we're going to continue talking about testnodes and again we're using the templating method we previously talked about. So for all of them we basically do these three steps. We iterate through the testnodes array or whatever array. This could be testnodes, data source, resources, whatever array that we're trying to have shown to the form. We populate the templates with the data from that object and then we append that to the iterator div. So I've kind of covered that already and this is a little bit of repetition but you can see more kind of fully how that works. We have the template getting set up here. The editor has nodes template. That's using the template plug-in for JQuery. So this is included in the JQuery kind of API. This is a plug-in that we found and are implementing and that goes back to kind of some of the conversation we had earlier. So we're kind of coming full circle and showing how those different templating mechanisms are used in the full scope of from XML to the UI.


Andrew Zuercher: Yeah. This is a complete rehash but hopefully this helps bring you full circle around to see how it is that the templating gets you from model to the form.


Ali Faiz: So that's pretty much it for this slide.


Andrew Zuercher: Do you guys have any questions about this recipe? Cool.


Frank Cohen: Just to give you guys a time check, we're about 55 minutes into it.


Andrew Zuercher: Yeah. I was afraid of that. Would you like us to pull out and then try to troubleshoot an item or you like us to try to go through the rest of this?


Frank Cohen: Keep going. I'll just hold this for the 15 minutes at the end for troubleshoot.


Andrew Zuercher: Okay. All right. So I'll go ahead and I'll hit the debug stuff. This should be pretty simple, pretty straightforward. So we went through a lot of effort to try to make sure that the application itself runs in both Firefox as well right inside Titanium. And the reason for that is that Firefox as debugging utilities are the best in the business for web applications and it's very, very powerful and it works really well. Because of this, you'll see things that act and behave completely different in Titanium versus Firefox. So if you bring Firefox for the very first time, you'll notice that when we bring it up the toolbar here is at the top and you will notice that three files were automatically loaded. The reason why we do that is because it's not possible to load files from the application when you're in Firefox because you need to talk to a local file system. And outside of that is we have a conditional check at the very beginning of the application to be able to distinguish between running as a Titanium application and running as other web browser applications. So I'm going to show you that real quick here. At the very top you'll see that we have a try/catch here. So we try to do everything that's Titanium specific here. If we can't do that then we cover things that allow us to behave in the okay environment if it's not able to do that.


Frank Cohen: When you're operation the application from the browser context, can you schedule file dropdown menus? I'm sorry. Not file dropdown menus but not but just menus in general. I don’t think you can.


Andrew Zuercher: No. The menuing is gone. You can't do local file system access. Basically, you can't do anything that's Titanium specific. So from our standpoint that's a big differentia between the two though.


Frank Cohen: So that's the reason why when you started up we've got the extra controls which looked all nice and ugly up the top of the editor's window.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Andrew Zuercher: Well, let's do stuff here exactly. But the way, I changed it out so those are default to be hidden as opposed to default to be shown and I showed them if it's the Firefox or other web browser because Titanium they're hidden and we don’t do anything with them. So you won't see that weird kind of flickering or weird behavior anymore.


Frank Cohen: That's good.


Andrew Zuercher: All right. So anyways, moving back on further --


Luis Carlos Lopez: So does the name that the application will be used for testing in Firefox, right?


Frank Cohen: That's right.


Luis Carlos Lopez: The ones we're going to use is just the Titanium one?


Frank Cohen; That's correct. Right now we're going to be deploying the editor as a desktop application using Titanium. There will be a future design for TestMaker 6, for example, that incorporates the use of the editor delivery through a browser interface that will come later.


Luis Carlos Lopez: I just one idea that we'll have at work to like deploy a local file using the web browser will be like -- you can send at the local file to the internet and it is like a really stupid thing that you can't just send in that and he will send this back to you. So that's why you could have a -- open a local. Your file is underneath it. You send into the servers using the destination file and the server will answer that and respond to you with the file and you will be able to process it. And every time you want to save it's like you will save that file.


Frank Cohen: Yeah. That makes sense. That's kind of a kludgy hack. But all we're doing really is using the browser as a debugging environment at this point.


Luis Carlos Lopez: Yeah. From what I have seen, it is interesting. People like Firefox a lot, myself included. People see Firefox as the future for the world.


Frank Cohen: Okay. Well, give me a glass of wine and we can have a nice discussion.


Luis Carlos Lopez: Okay.


Frank Cohen: Okay.


Luis Carlos Lopez: Sorry about that.


Frank Cohen: Keep going, Andrew.


Andrew Zuercher: All right. Okay. So what I want to show you is I want to show you how to debug Firefox. So you have to have the Firebug debugger. In this case what I do is you click this script tag. You make sure it's enabled and then you select editor.js and I've said it, break point through the very beginning. Refresh this and you'll notice that when I refresh I get the break points. So that's pretty cool and you can see what break points that you have and you can take a look at everything that's in your scope for your local stack. And you go ahead and let this run. The other thing that's really cool that you can do with Firefox is say I want to do -- I want to inspect elements that are currently in there. I can hit that and then take a jump over here and now it shows me that complete element. So I can query of states of things. In our case, Editor.currentopenfile is a globally available object you can get a lot of different stuff inside of that pretty easily.


So both of those are pretty cool techniques for being able to use Firebug itself to build through steps. So if you want to, of course, when you set this break point and you hit it, of course, you can step through it. As you can see you step through the application and that gives you an idea to be able to get a trace to figure out where things are. Likewise, say that I'm here, you can see right here it will give you the call stack as you can see here, go up a level here, up a level to here and here we get to anonymous invocation for being able to put a definition. So it's a pretty robust, pretty feature rich debugger and I only need to restart Firefox once an hour or so which is actually not great but it's 10 times better than anything else that's out there right now, their debugging JavaScript applications. So that's one way to be able to debug and that's pretty standard generic stuff that everybody does.


Another thing outside of that is if we are running Titanium itself. I can go in here and do Inspect Element. When I go Inspect Element I can click on scripts here on my dropdown. I go to editor.js. Let's take a look at this here. A break point there. We'll use cases. So I'm going to put a break point there. I add a test case and you can see -- you can do the same thing here that you can do with the other stuff. You can step through things and you can take a look at scope variables and figure out what those values look like.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


This is useful -- the only time I do this is when I have a Titanium specific problem because I can't reproduce or troubleshoot inside the Firefox. That's the only time that I use this. So it's important to know that you have the ability to do that. All right. So those are two big debugging practices that you use. Outside of that the other big piece is going to be logging. So what we've done is we've defined a log obstruction which is the function pointer that's globally available throughout the application. It has two implications. In the case of when you're running inside a Firefox it just can show up in the Firebug console. So in our case, when we look over here, we run this. We hit that and it shows up right here. But there's no reason why you can't, of course, include other properties or states that you want to show when you do the log thing. In the case for Titanium when you do that you'll notice that it's going to show up here in the actual shell itself. So it writes a standard out. So if you look, you'll how our guy is right here as opposed to showing up in the debugger. The reason for that is we find it much easier to deal with debug statements in the actual console in trying to inspect and get into WebKit's console to be able to display the information.


So those are the two key things that you have is opportunities or availability is you can either use logging or you can use debugging and you can use in both platforms. One of the things I'm going to caution to you is if you try to debug on Win32 which I think sounds like you guys out in Costa Rica have a lot of these Windows based machines is that the Titanium or the WebKit debugger doesn’t always work too terribly well which we've seen in the last version of the WebKit that I tried debugging on. And you're probably going to have to fall back to logging only. Any questions? Does that make sense?


Frank Cohen: Okay. Just as a time check, we're at just over an hour.


Andrew Zuercher: Right. Okay. Maybe some of these things maybe we -- like, for example, the menuing stuff, it's pretty straightforward. I think you guys can probably figure that out on your own. The dirty flag stuff -- I'm going to try to scan through it a little bit quicker than we normally would. I don’t think it's really terribly hard. This pretty much explains it all out but this is how you create it. This is how we manipulate it and this is how it shows up. Same thing for the dirty flag. The dirty flag we have three key methods that you can use. See, they get used throughout the application and this is for state, for those as I realized.


Another key thing for here is how we do state transformation. So when we initially wrote the application, we wrote it so that the state transitions were taking advantage of the Entourage State Machine but you really don't need to worry about that at all. At the bottom of our class here for the implementation, we have the editor which is this guy right here and then down at the very bottom there's something we call PushTT and we define these different states right here. And whenever we change -- it's basically just going to be a simple string and these are all top level states. So when we toggle through a different state what we do is we have different selectors that we apply for hiding and showing elements.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


That's particularly useful for understanding when you change from one state to another. So really to be able to match all that stuff and understand how that works you can take a look at -- a lot of them are DOM elements themselves have this state attribute that exists on them so we can use this kind of simple kind of generic selector for hiding and showing elements that aren’t necessarily the same as the one that you're currently working with. The other thing that we have outside of that is understanding how to be able to go to and from the XML state in the forms header state. So if you take a look at that, not too terribly complicated but it's useful to be able to understand how that drives it. The other ones are pretty much based upon the tabs. So I'm not really going into too much detail about it. That's pretty much high-level explanation.


I think this is an important piece to go over is going from the form and again to the XML. So I'm going to let Ali tackled this one. We covered -- I mean the main functionality of this application is going from XML and going into forms and going from the forms and then back into XML. And I think we've covered pretty well how we use templates, the model classes built to do that, and now the important thing is how we fetch from the form and get back into the model objects and into the XML.


Ali Faiz: All right. So going from the form to the model. So again, similar to what we talked about in going from the XML to the form we have kind of two states. We're going from the forms to the model and then from model to the XML. So from the form to the model, there's a function called save_states in the editor. So save_states is in the editor and it basically goes through all the different types of model objects we have and saves their state to that model. So I kind of put a little snippet of the generic call that we have that's pretty easy to go through and that generic method is save_currentstate_selector. And what that gives us the ability to do is to pass in an array, a selector, and a fieldset. So we made it generic enough for most -- well, a good chunk of the different model objects that we have.


So the first one we have and this is continued with the testnodes example. We have a node of testnodes, node_container, and the node fieldset. So in the save_currentstate_selector function you'll see for each of the selectors under node_container, and to give a better idea of what that node_container is we actually have the HTML down here and we also have the fieldsets. You can see our node. So in the testnodes template you'll see how that kind of fits in with the selector in this save_currentstate_selector and the fieldset. So for each we're going to pull out -- first of all, we pull out the hidden id, this hidden id number and whatever presents is in id -- each of the elements in our array has an id that is distinct. So we do a lookup by id, that id we got from the hidden element on the array that was passed in. We're able to grab the object that is there. So once we've got the object, we're going to go and get all the input items that have that fieldset set to node. So as you can see, we have a name, we have a monitor and a location.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


And what we do is we take -- oh, first of all, we check -- we grab the name, the variable, and if that name is equal to id or delete then we ignore it. If not then we set that object's attribute to the value. So for example, we have the monitor, the name is a little too confusing because we have name, name. But anyway, so we grab the name monitor. What that will do is say the object's monitor will equal the value for that element.


Andrew Zuercher: Let me I jump in here. The reason why we use the fieldset approach is the nodes that we don’t have any form tags around our input elements. So it's a way for us to be able to have a grouping of elements for a particular selector. So in our case, what we're looking at in this example that Ali gave is we're looking at all the input elements for a given node. So using this generic type of definition for how it is that we stretch for the HTML which is what you see right here in front of you right now and using that generic approach that well to implement our save_states in a way that's pretty generic across the application for. Now, there is some pretty complex serialization logic that's going on for some of the other special cases but for a lot of really simple ones that's how it's implemented.


Ali Faiz: So yeah, and let's in the bottom that some of the non-generic ones you just kind of have to look at it. But it does use a very similar strategy to what we have here. So continuing on. Now, going from the model to the XML is all pretty much contained in the save_in_xml function. So pretty large function but what we're doing is we're creating a DOM object from the XML and then we're taking that and emptying out pretty much and then building a backup with the information we have in the model. So again, using the testnodes example in save_in_xml we have an XML variable that's representing the DOM objet of the XML. Now, we're taking the current open filexml which is a string and building that into the DOM object using this create_xml_document call. After we do that, we empty out the testscenario information in the XML DOM. So we grab the testscenario and then -- actually I don't include the emptying but I did include in the steps that we take.


So in the code you'll see this kind of dot-dot-dot kind of skims over some little stuff, not really that important to our example for testnodes. So when we want to create these testnodes for the new Array and then for -- this is just a nice little JQuery function that takes the place of a for loop so you just hand in an array and a function and for each one in that array it will perform this task. So for each element in the testnodes, we're going to push a new object that's the DomUtil.create object which is in -- it will easier if I show you the actual DomUtil JavaScript. So we have some pretty handy little DOM manipulation functions. In this case, that's a created function that takes in a node name, an id, class, css, children, attributes, text, whether or not we want ids or not and then a namespace. So it takes quite a few different things but we're able to create a DOM element using this simple function. So we're creating a node and this goes back to what the XML looks like. So we're creating a node XML element to put in the DOM and we are populating it with these attributes.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Now, again, if you remember we saw the JQuery functions that this is just a passed in value from that function, and that's how we create some of these testnodes. Now, it will help if we look at the XML in this case. So we look back at functional scenario. So you have a testnodes, a node, this is all under the testscenario. Now, since testnodes is empty we're not worried about any of these attributes so we're populated for each node. All we are worried about is putting in all these nodes under the testnode element. So you can look here and see that we have a testnodes = and we create another DOM element. There's no attributes but we do pass in the newtestnodes. So if you look, we're doing a -- so that's how we create that testnodes element. Now to put that into the testscenario that we emptied out, we just do an append. And if you look at this function, you'll see that we did something very similar for all the different models and we all do -- and for all of them we do appends to the testscenario DOM object.


So after we're done building up that testscenario again we want to serialize it into an XML string so that we can display it and do all the things that we do in the editor with it. So we have to call a serialize function which -- I didn’t include here because it's all kind of handled in the code. It's not terribly important in what we're doing here. And then we're prettifying it. This formatxml is just we're given -- the XML generated is there's not much spacing. It's kind of ugly to look at so we have a format call that will add all the spacing needed to make it look like what you normally see when you open an XML document. So to reiterate, what's going on in the save_in_xml it creates an XML DOM object, empties out the testscenario, creates the DOM entries for all the arrays, and then it appends those DOM entries into the emptied out testscenario. To that we set the openfiles XML string, you can see that's what's happening here, to the serialize version which is also being prettified. And I'll elaborate a little bit on some of the DomUtil and the prettifying here. Any questions?


Frank Cohen: Well, I have one. So on a regular basis now we're adding new features to TestMaker that impact XML Schema Definition for the testscenario documents. So I know in the editor's design we're not doing any XML validation against the XSD. Are there any tips or hints that you might have about how we can keep maintaining the editor as these XML changes happen, as the XSD changes happen?


Andrew Zuercher: You know what? I think you should try to research it. Probably the best thing that you want to do is if you are not able to find information about how to get validation or deal with different XSDs for the definition of the document that you're importing which is kind of limited to be honest. It's not really -- there isn’t really a lot of validation tools in JavaScript then one thing we'd eventually be looking to doing would be using like a Ruby or a Python or a PHP integration. Ruby and Python both have a little bit more information for being able to different type of schema definitions and be able to figure that stuff out. The only thing you could do is you could do a scan so you could do a scan on the file that's being uploaded, check to see what the XSD defined for. This is a new id that's defined for the given file that you're trying to open. So those are the two things that I would suggest doing.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


I think versioning in this such as to become really challenging, Frank. One of the cool things that we have is we have this elementary model objects which will allow you to potentially import into this model object and then you write custom serializers that target output to different XML documents. I've seen how much possible version consistency that you have between them. Does that make sense?


Frank Cohen: It does. So William and Luis Carlos, do you have any other questions along those lines?


Luis Carlos Lopez: Yeah. That is moving from the file to the do you have -- if the XML is broken, do you have any system to check that out that there is the XML is broken or in general if there is a problem that it does not compile or inspected?


Andrew Zuercher: Unfortunately, there's not a lot that you can do. Our parsing that we have which is -- well, right now what we're -- okay. So it's a little bit different than we just covered. What we just covered is how to save to XML but how to parse or read from XML, if it has a problem loading the document itself, it's going to silently fail. So only the best thing that I would suggest doing is that what he'll do is he'll look for stuff and then when you try to query items from the result you won't get anything. It's also possible for you to have a given document that doesn’t have any elements in it. So the closest thing that I would say would be if you wrote the document and it doesn’t result in any new elements then there's a chance that that document that you wrote is not properly defined but that's a challenge in identifying that. Does that make sense?


Luis Carlos Lopez: Yeah.


Andrew Zuercher: What we do is we query after -- there are some places inside the document that are pretty. So from our standpoint we're looking at basics, we're looking at top level queries. So basics, testnodes, DataSources. You could check to see at the top level of the document itself to see if there is a basics or to see if there's a testnodes and if those items don't exist then you may be dealing with a poorly defined document. That would be the best way that I would suggest doing it. I don’t know what defines necessarily a bad document. I know what defines a bad document, when it doesn’t match to an XSD that's defined but unfortunately we're not really given that from the utilities in JavaScript libraries that we have.


William Pomares: One question. You mentioned -- okay, we can integrate with some other language. So we can use that XML validation kind of send the XML to that XML validation and then get back and throw it to the XML. So for the validation, I guess that that is actually the way to go kind of send it to another tool, another language. But still we do some changes in the schema and we're going to validate that automatically with the other tool then we still need to come here and do these changes in the code. So, for instance, we have another child to testnodes that is not known or cloud is, I don’t know, any other thing, we'll need to add that right?


Andrew Zuercher: Yep. Yeah. Just to make clarifications to all that serialization points inside of the editor.js, the importation would be add a new Array and you have a console to find them in the project files as well so that -- because we use templates for that.


William Pomares: Yeah. Okay.


Frank Cohen: Hey, when you're -- JavaScript can make a call to a Java or Ruby class, right, and instantiate the class call the methods. How do you actually do that in a Titanium context?


Andrew Zuercher: Titanium, well, he knows how to process Ruby files or Ruby code directly in line as script tags.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


We need to find the reference to a particular script. In our case, see our top is text JavaScript. You can also do type = "text/Ruby" and directly to find a whole Ruby document itself. Now, as far as being able to have DataSources to be able to invoke Java, I don’t think that's supported. I don’t think that's currently on the definition right now. I know that Python and Ruby are supported and I know there's work right now for PHP but I don’t know about Java.


Frank Cohen: Okay.


Andrew Zuercher: I would think there is because you can do stuff with Android and I know that they talk about definitions for doing that but I have never done it myself so...


Frank Cohen: Yeah.


Andrew Zuercher: The cool thing too is I would -- if it's not there I would think that they're working on it. The cool think about this whole thing is once you've defined it's basically creating JavaScript wrapper for you and it knows how to be able to discover not only the object and its attributes but also its methods that it has so you can write stuff in multiple different languages and blend them all together in Titanium. Now, one of the downsides, if you do stuff in Java is you got to be careful about how that -- what that means to you for being able to -- you don’t want to break the Firefox stuff too. Maybe that functionality doesn’t work in the same way that we cut out open in the menuing and isolated that too.


Frank Cohen: Okay. So I'm looking at the clock. We're about an hour and 30 minutes. I think we have budged in another half an hour, another 25 minutes at most. So do you think we can do a little bit of debugging?


Andrew Zuercher: Sure.


Frank Cohen: Okay. Andrew, did you have anything else you wanted to present in terms of the REST-based?


Andrew Zuercher: No, no, that's it. We're good.


Frank Cohen: I sent out four items on the to-do list and it looks like three of them you guys solved this morning. So it's very efficient and hopefully we'll be just as efficient when we're maintaining a code. The fourth one was the resource popup menus and the use case and the DataSources tabs need to show the shortened name of the resource because the current technique shows the entire path and that causes the popup menu to be very wide, sometimes even wider than the screen. So I guess the way I'd like to do this is to see if Luis Carlos and William would like to look at the code and see if they could tell you where they think they would start and what their approach would be. And then Andrew and Ali, maybe you could give them some guidance on how to implement it.


Andrew Zuercher: Sure. Maybe before we -- so you want to take this number 4 right here, right, the resource tab that needs to show the shortened name of the resource.


Frank Cohen: That's right.


Andrew Zuercher: Maybe you can show me in the application or tell me where to go inside the application where that would be.


Frank Cohen: Sure. Go to the Resources tab and choose -- browse a particular file -- well, actually, again, I'm sorry. Choose under Resource Type data and then browse for a particular file and you just want to make sure that the file is down enough on the path somewhere that it's going to have a long path.


Andrew Zuercher: Okay. All right.


Frank Cohen: Like where is Resources located in relationship to the root?


Andrew Zuercher: Yeah, it's pretty good.


Frank Cohen: Okay. So select any of those guys. And now, go over to the DataSources tab. Add a DPL and see how wide that is.


Andrew Zuercher: Yep, I see what you mean.


Frank Cohen: So the thought is how do you display a shortened version of that resource name?


Andrew Zuercher: Yep. We got it. Okay. We'll do that.


Frank Cohen: So William and Luis Carlos, where would you begin? I just love putting people on the spot.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Luis Carlos Lopez: Okay. Begin in changing the data. I will also add verified scenario option like in the general tab when it's going to read the -- check the, for example, the proportions of these instances I see that is 100 and so that tell you, okay, this is verified or there is a problem somewhere there.


Frank Cohen: Okay. Well, that's a good start but that's different than these problems set which is specifically had to show a shortened name in the Resource.


William Pomares: Well, actually, we need to create a new content. Obviously, we will need the full resource name that is the full path. So we will need to shorten it a name probably using. I don’t know if there is in the JavaScript a function that does that. I know that there are some libraries in other languages that you pass a long path or a long string and they shorten it using ellipsis.


Frank Cohen: Okay. So that's a good first question. So Andrew and Ali, I've seen you guys use shortened names in other parts of the application. Is there a function that you've written that gives you a shortened name of a path?


Andrew Zuercher: Yep.


Frank Cohen: What's it called and how would you find it?


Andrew Zuercher: Yeah, clip_filename. This is a good one. We have another one. All right. Here you go. So you see clip_filename is one place where we've done it. We could generalize this so that's general between everything to be honest. So there's a couple of different ways to go. One way is we can actually clip what gets displayed so it's smaller. Another thing we could do is we could do the styling thing where we just restrict what gets displayed. So right now I think when you have a dropdown like this you can make it so that what gets selected or what gets displayed when you click on it what is the available values are can be different than what's the case. Add resource and let's call this data. For path, say, on the high level. Now, if I go back here --


William Pomares: One question. The resource name, is the resource name that is optional in the resources, right?


Frank Cohen: No, it's not in the XML so it's not in the application.


William Pomares: Yeah, but I mean that that name that is optional is the one that is used in the dropdown in the resources?


Andrew Zuercher: So just kind of going over this right now. Another way that we could do is I think you can style this. So you see there's a max width it's like only to here but then when you put the flag you use it to full width. So you see how this kind of does this stuff differently than it does for right here? So I think that we could potentially make this a styling opportunity. So let's try above the solutions, shall we? Clipping as well as the styling.


Frank Cohen: Okay. Let me just ask William. What was the question that you were asking?


William Pomares: Yeah, because in the dropdown I'm seeing the full path but the full path is actually the Name (optional) in the Resources tab, right? So what if the user actually names that with a shorter name?


Frank Cohen: Oh, under DataSources, the name would be the name of the DPL that you're creating, right?


William Pomares: Yeah, in this case, well, it says name (optional), data/Applications, blah, blah, blah. If I name that to something more -- I don’t know, shorter or just a name that I want or something.


Andrew Zuercher: I don’t think that you can rename it in this case in the UI. If it's a path you can't, can you?


Ali Faiz: Well, this is one of those issues that I think -- I mean if you -- this is a little bit of the design issues but I think we just never really sat down and really discussed about it. It could be minor but the fact that you want a name that's generated from the resource type and path doesn’t really lend to being manipulated. If you want it to be generated, the resource type and path, overwriting that has a little bit more kind of complexity than we really kind of put in there. So --



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Frank Cohen: There are a couple of things -- there are a couple of responses that I have for that, Ali. So we discussed this at one point where the design flaw was within the XSD of that XML document. The DataSources DPL definition was trying to use positional references to the resources and that's just bad. So the solution was to add a name element to the resources section so that we could name the individual resources and that's coming up in the next version of TestMaker. As I work around though I believe that you did get it to work with positional XML representation of those resources. Then the other issue is to William's question which is why -- let's see. If you can click back to the DataSources tab for a second, I think that -- no, no, I mean within the editor itself.


Andrew Zuercher: You mean here?


Frank Cohen: Yeah, there. Click back to the form view. Yeah. So selecting the resource name identifies positionally which resource is going to be used by that HashDPL. Does that make sense, William?


William Pomares: Yeah, right. My question was if those are the same names that are being generated as optional in the resources tab.


Frank Cohen: I don’t know. Ali, do you know the answer to that?


Ali Faiz: I'm sorry. What was the question again?


William Pomares: Okay. Do you see that resource name?


Ali Faiz: Mm-hmm.


William Pomares: Okay. That is a select that is coming from the DataSource that is being populated in the Resources tab, is that correct?


Ali Faiz: Right. The Resources tab to those names, those are being reflected in that DataSources dropdown.


William Pomares: Okay. So we have two options there. We are creating because those are being created automatically. We can create them using shorter names, right? So it will fix the DataSources problem and surely we will have short names in the resources, right, frank?


Frank Cohen: Yes.


Ali Faiz: No, it can't work like that. The best option is just displaying shorter names. The thing is if you're going to -- you can't shorten a name in the Resources tab because that's an absolute path.


William Pomares: That name in the resources is used by -- for something else or for instance, I don’t know. Is that used for accessing the data or seeing the data path in someplace?


Ali Faiz: No, I saw the name isn’t stored in the XML at all.


William Pomares: It's used locally?


Ali Faiz: Yeah, it's only used locally.


William Pomares: Okay. So if you say this and you open it up again you will recalculate the name using the data on the top?


Ali Faiz: Exactly.


William Pomares: Okay.


Andrew Zuercher: Shall we try to do a fix here?


Frank Cohen: Yeah, go for it. You're talking about using a CSS fix?


Andrew Zuercher: I'll give you a CSS fix. So first, I'm going to look at the DataSources. So this is our guy right here. It's select and if you look the name is this. So what I'm going to do I'm going to go in here.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


I would normally test this in Firefox but we saw that we can't really have a heck a lot because after opening up a file I have to get it here. You know what I'm saying?


Frank Cohen: Yeah.


Andrew Zuercher: Now, if you want I can also tell you how simple . Let's say I -- I think that's really the answer that you want right here. I could also show you how to clip it if you like. That can involve how does we load, our load function happens for DataSources. So I'll show you that as well?


Frank Cohen: That's fine so the clipping in the JavaScript then would populate the select with the clip names and then have some mechanism for letting those back to what the real resource name is when they're selected?


Andrew Zuercher: Yeah.


Frank Cohen: Okay.


Andrew Zuercher: So I'm going to comment this out and now I'm going to do the clip. I'm going to do the clip implementation as we go in here, the editor. Here we go.


Frank Cohen: Excellent.


Andrew Zuercher: So those are the two alternative ways. Do you guys follow what I just did right there?


Frank Cohen: Do you mind giving us a brief summary?



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast


Andrew Zuercher: Sure. All right. So the first solution was obviously using the style sheet. The second was I was inside here. This is where we populate it and I know that that is in the editor. That's in the load_datasources, right?


Frank Cohen: Right.


Andrew Zuercher: So if you look at load_datasources, this is where he actually populates that select, that's a generic function that we have. So we'll look inside our generic -- all right. This is where we define our options for the individual guys inside there. So that's right here. He just basically -- we made it so that the name that we use to display just not the value. It's just going to be to display should be the clip_filename.


Frank Cohen: Okay. And the value is where in there?


Andrew Zuercher: I'm sorry?


Frank Cohen: The value as opposed to the clip name, where is that in this? Oh, there it is.


Andrew Zuercher: This is a cool JQuery stuff. So the idea is whenever you call a method on JQuery, so in this case the $ wrapper basically he gives you an array or collection with some utility methods on it and one of those methods is attribute. So whenever you invoke any of these objects on top of the object, he gives you the object wrapper back. So what we're doing is we're creating -- what this is saying is I'm going to create an option element. So what I'm going to do I'm going to set the value on that to the name. Then what I'm going to do is I'm going to set the text on that option element to whatever. So if you look at the option element it has a value in text and the text is what gets displayed and the value of the actual value when you select it.


Frank Cohen: Cool. That's excellent. Louis Carlos and William, do you have any comment or thoughts on this?


William Pomares: No.


Frank Cohen: Okay. Great. So Andrew and Ali, did you want to add anything to this? Because I think we're pretty much at the end.


Andrew Zuercher: I think we are at the end. You know what? I know that -- some of the things that we kind of skimmed over pretty quick here just kind of going back at me. This is -- I think this covers a lot of main topics. I feel pretty comfortable that we've give you is some pretty solid stuff. I think that it should be a good foundation for you. One thing I would kind of say is that some of the selectors and things that we did we used id attributes to a lot of places for our templates and I think going forward there's this notion of a scope select. So in JQuery you can have a select statement but you could also give it a context. So what he'll do is he'll only apply that selection for anything that's below a particular starting node. I think that we did that and probably cleaned it up but at the same time I don’t think it's necessary worth going through and rewriting it. It would simplify things a little bit more for you. But I think that from a high level standpoint this has been extremely enjoyable project to work on just to think that tools are great. JQuery is the fantastic JavaScript library to work with and I think it's pretty robust. So I've been pretty happy for the most part with Titanium and the container itself and how it is that it loads and how it behaves. So that's really pretty much it. I hope that what we've given you here is -- when we did this cookbook and these recipes we did it with a mind of what is it that we'd want from somebody if somebody were going to grant the transition to us. So we hope that the content is useful for you.


Frank Cohen: That's good. Well, I mean PushToTest is going to distribute this cookbook, all of the code, and also the Screencast under GPL license. So I'm thinking that it will be useful for a bunch of different applications even outside of TestMaker.


Ali, on behalf of PushToTest and Andrew, on behalf of PushToTest, I'd like to thank you for your participation in the project. It's been awesome.


Andrew Zuercher: Excellent. Well, thank you. We certainly appreciate it.


Frank Cohen: Great. All right. Thanks and good luck, guys. And thanks for everybody's participation on the call today.



Download TestMaker and Run Selenium Tests  Watch the Tutorial Screencast

33


While The Screencast Loads Consider Joining...

Join the PushToTest social network of testers, developers, business managers, and architects for these free services:

- 6 Free Webinars on Testing Best Practices Each Month
- 4 Free How-To Articles Each Month
- New Improvements To The Open Source Test Tools Every Week

Join 22,100 subscribers today. Complete this form. You may unregister (opt-out) at any time.