Building The Next Generation Record/Playback Tool
PushToTest funded a new open source project to deliver a modern Web
application test record/playback system. We named the project TestMaker
Object Designer (TOD.) Our hope is to move Selenium IDE and other
record/playback test tools into the era of modern Web and Rich Internet
Applications (RIA, using Ajax, Flex, Flash.) The work on this new tool
started in March 2010. Watch a special briefing meeting with the
PushToTest community to show our progress on the project.
Building The Next Generation Record/Playback Tool
Frank Cohen: Hi, everybody. This is Frank Cohen with PushToTest. I want to thank you for taking your time out of your day to participate in this briefing. We've been working for the past five months on an improved record/playback tool for recording web applications and rich internet applications, and this is a briefing to kind of show you what we've done so far and get your feedback and criticisms and ideas. PushToTest is an open source company and everything that we're going to see today will be part of our open source distribution. We probably packaged up into TestMaker although we also we have a conversation going with the Selenium team and also with the Sahi team to make this work part of their packages as well although that's just a conjecture at this point.
What I wanted to do is introduce you to the presenters for this briefing. I'm Frank Cohen. I'm the CEO and founder at PushToTest. We're a small software test automation company offering test authoring, test management, and test orchestration solutions mostly for web applications, business process management, and for anything else that requires kind of a network protocol. I'd also like to introduce you to Narayan Raman who is the founder at Tyto Software. Narayan is also the inventor of the Sahi test tool. And then also we're joined by Venky who is the senior engineer at Tyto. Most of what you're going to see in terms of demonstration is a code that Venky has created. So you've got the team here.
The agenda for today's briefing is to go over the project goals first and I've got like three slides that have to do that, then to spend the bulk of the time on a demonstration of what we've created and then to talk about kind of what the next steps are in terms of issues that we still need to solve and then also an estimate for the schedule. Keep in mind though this is a briefing of something that's not even alpha quality yet. You're going to see something that looks pretty good but I just want to remind everybody that everything you see today may change before we're done with it.
So by way of introduction, let me talk a bit about what TestMaker is and kind of what our goals are. So our goals are pretty simple. We want to provide an open source solution for doing test authoring, test orchestration, and test management. For test authoring, the whole idea here is to create objects or components of software that interact with web application, with a rich internet application that includes Flex and Flash and AJAX apps. We want in test authoring to be able to develop a test workflow that implements essentially user behaviors but we want to implement them in a unit testing fashion so they basically fail on exceptions as the unit tests are operating or they pass through on completion. There needs to be data inputs to provide operational test data from a variety of different data sources as well as an ability to do assertions and validations. Of course, the whole idea of the internet is we've got millions of different protocols in use now so we need to provide a standard way for an organization to adopt a custom protocol. And then the whole idea here is to build reusable test components that can be treated like software and that will reduce the cost of operating these tests over time.
In terms of test orchestration, what we mean there is, hey, if you've already gone through the effort of authoring these test components there should be an easy way to kind of orchestrate the components sent to a set of use cases very easily. This also should be pluggable into a continuously integration environment so that things like scheduling your tests and dealing with a whole bunch of tests operating in the same time, that should be easy. The deployment should be enabled through a grid or cloud environment and there should be a number of ways to provide these tests with data either from like a comma-separated value file or relational database or data generating objects.
So TestMaker 5.5 which actually ships this week provides you with the test authoring and test orchestration capability. What we're working towards next is the test management capability.
Under test management, you will be able to policy definition like, for example, you might say, "Okay. Well, nothing gets released into staging until it's executed these tests and passed." We also want to be able to do requirements mapping where you can say, "Here are the requirements for my new application and then to see an overlay of that to see how many tests cover all of the requirements. It will have a centralized versioning and repository system so that you can enable a collaborative team environment. And of course, they will be roles-based security so you can then designate various different groups to have the ability to run different tests.
So the way this maps out into a product roadmap is that TestMaker 5.4 which shipped last year introduced this idea of scriptless test development and introduced essentially a graphical editor to do everything. And then by then Selenium project have achieved Selenium IDE 1.0 and so we started shipping 1.0. TestMaker 5.5 has been in development for the past year. We've gone through six weeks of release candidates and this week we'll be launching TestMaker 5.5 for final. The 5.5 features grid testing where you're able to have TestMaker automatically select which TestNodes will run the test from a grid of operation TestNodes. We've include .NET and Visual Basic support. There is now a coordinated data provisioning system where you can provide unique data to all of the virtual users. And then we upgraded to Selenium IDE 1.0.5. Actually, we're now on 1.0.7. TestMaker 5.6 is next up. We're going to refactor the TestNodes to improve the test operation speed and that work is already underway.
We're going to introduce JMeter ScriptRunner which -- actually, that's already done and then the big effort will be on delivering the Test Object Designer, TOD for short, and this is the record/playback tool that you're about to see. And then TestMaker 6 will be all about the test management capability. So what we're hoping for is that TestMaker 5.6 will be ready kind of for -- well, it will be functionally complete by like, say, August and at that point you'll be able to use the Test Object Designer for building tests of your own applications. Well, we're hoping that TestMaker 6 is kind of like a winter 2010, spring 2011 kind of release.
Leslie posted a question, "Frank, would you please restate the schedule?" Okay. So TestMaker 5.4, it's been out for a year. TestMaker 5.5 this week. TestMaker 5.6, we're hoping that in August we'll be able to release kind of an alpha or an early beta version of the TestMaker Object Designer. What you'll see today is actually in our SPN repository ready and there are many pieces of it that already work but it's probably going to be another -- it will probably be August before the Test Object Designer is really in good shape to be used. And then TestMaker 6 is probably like a winter 2010 or a spring 2011 release.
So the TestMaker Object Designer goals are pretty simple. We're in a position where when we look at the record/playback tools that are out there like Selenium IDE, even the Selenium project kind of has a problem with it in that the Selenium project team members especially the core commanders would much recommend that Selenium users write Selenium tests in a high-level language like Java or Ruby or Groovy or any of the other supported languages and I even recommend the same thing. For me record/playback is kind of a dead end in that eventually you get to a point where you say, "Well, if I need like conditionals or looping or branching or complicated data structures, those are all provided in a language like Java. So like why am I trying to beat my head against the wall to make a language like a record/playback tools language work at the same level that a full-fledged language like Java or Ruby or any of the others would do?"
But we know that there are ton of testers out there whose introduction to testing was through products like HP's QuickTest Pro product where everything was kind of guaranteed for them. I would just click here and click there and we'll take care of the complexity of writing the test for you. That's always been kind of a fallacy. It's never really been true. But there should be kind of stepping stones to take a tester who's used to a record/playback tool and migrate them so that they are really proficient at writing test script in a high-level language.
Unfortunately, most of the record/playback tools out there that we see including Selenium IDE really isn’t designed or wasn't built originally to do that. Well, our goal here is to create a next generation record/playback tool that works for modern web applications namely Web 1.0 apps and also rich internet applications. By rich internet applications, we mean apps that are using AJAX, Flex, and Flash.
The second issue is the many organizations have mandated or standardized around different browsers so Internet Explorer, for example, Firefox, Chrome, Safari. The record/playback tool that we deliver must be able to support all those different environments. The third thing is that the recording technology has improved over the years. If you look at what Sahi has done in terms of understanding frame spaced applications, understanding how JavaScript is used in a very modern way, Sahi technology is really kind of head and shoulders above the rest and so we believe that a combination of kind of Selenium technology and Sahi technology makes the best sense for delivering a modernized recording technology. What we've also seen is that Adobe itself has come out with their own Flex testing API that includes a Selenium-like language and we would like to support Adobe's standard. The biggest goal for this project is to create a compelling open source alternative for HP QTP and HP VUGen Users. Our hope is that the Selenium project sees the work that we're doing and maybe even adopts this as the next generation selenium IDE tool. But there are no guarantees on that.
So the way that TestMaker currently works is that you install it as a Java desktop application. You start TestMaker, you identify that you want to run a test, and so it opens a TestScenario Controller. The controller is a client a web service called a TestNode. The TestNode has the script runners in it to run tests written in Java or Ruby or Groovy or any of the other supported languages. The script runners also exist for running Selenium test natively in a selenese table format, and also the TestNode includes operational data provisioning system called a Data Production Library and that can automatically inject operational test data into your test scripts at test runtime. So the TestScenario Controller takes all of the orchestration instructions that you've set up and runs the test. If you click on the edit button here then it brings up an editor. The editor itself has many different tabs up on the top to control the orchestration of that test so you can define under the general tab, for example, that this is a load test and then under the use cases tab you can identify which test you want to run. Those tests could be a Selenium test. It's soon to be Sahi test. There could be a soapUI test. There's about 20 different script runners built in.
So what we're talking about now is basically adding another component to the TestMaker environment where these tests that you've orchestrated you can author individual test objects which will interact with the web application using the Test Object editor and that's what we're going to show the demo of in just a minute. So the environment for authoring test in a record/playback setting would be that you orchestrate within the TestMaker Editor. You use the TestMaker Object Editor to define scripts and those scripts interact with the actual web application. The interaction is live so you're able to see the test scripts operate within the live browser.
So the TestMaker system itself will contain a controller that's kind of a starting point. The controller would run the TestScenarios. The TestScenario Editor would let you orchestrate the test objects into use cases. You can even do things like define the parameters for the test and data-enable the test. All of these top three things exist today. The Test Object Editor is what we're talking about coming next and then there's a browser viewer so that you can view the test object operation in a variety of different browsers.
For deployment, you are able to deploy these tests into your own grid of machines so these TestNodes may be running within your own test lab. Test grid automatically picks which TestNode is available and runs the test and then makes that TestNode available for the next test or you can deploy this test into a cloud testing environment and we've created an on-demand network where we partnered up with Amazon, GoGrid, CollabNet, or Rackspace. So built-in TestMaker is the client to these partners. So TestMaker, when you press the start button would provision machine instances within the Amazon cloud to run these TestNodes and return the results and then you can even tell TestMaker to take down these machine instances.
So that's kind of briefing on like what TestMaker is and how the Test Object Designer will plug into this environment. We'd like to next show you a demonstration by first giving you a summary of the user interface, showing you an example of recording a test, debugging that test, and setting break points, even data enabling tests. And then show you the dialect support that exist today namely you're able to record this test into your Selenium or into Sahi.
So I'm going to step out of these slides for a moment and then make Narayan Raman, our panelist today, the presenter.
Narayan Raman: The TestMaker Designer is actually built over Sahi technology and that Sahi actually runs as a proxy server and once the browsers are configured to use Sahi as its proxy. Sahi injects some javas code into the web pages and that lets us control the web page so we can record and playback on any browser. Sahi basically usually did not have support for Selenium base locator builders so we added them recently and with the Object Designer we should be able to actually record and playback in both Selenium and Sahi. This application is built using Titanium. I know a lot of the application. Sahi needs to be started as a proxy and Sahi is actually checking into the source code of PushToTest. So you should just be able to check it out and navigate the user data bin. So this helps the proxy server and this is on quote 9999.
From this point on, I would like -- once you configure the browser all requests will go through the Sahi proxy. This is a PushToTest Designer so we're going to create a new test case. We'll have a Google demo. I will click on the record button, I'm bringing up Internet Explorer. I've set aside the start URL as Google.com. As I have said, we can see the navigation statement, as recorded. We'll search for PushToTest and click on Google Search. So you see that like in seconds I got it here. We'll assert that Download TestMaker 5.4 is visible here. So we click on the Check Points window and we press the Ctrl key and over whichever link we want and in this case Download TestMaker 5.4. So it shows up here in this assertExists and in the link and in the value. So I'll just check for the existence of this link. I'll click on Add. So we see that all these 4 lines have been recorded. Now, these, as we can see, have been recorded in the script type of Sahi but you can actually change this from here and see what it is like in Selenium. So both of them will be recorded simultaneously and you can switch between these two at any point of time. Let us save this file as -- and we'll end recording here and play it back.
So we can play it back on any browser right now. Let's play it back on Internet Explorer. So it has executed the four statements and the logs show that all four have been executed. You can do the same thing with Selenium dialect. We can play it again. Done. We can also play it back in Firefox. Done. So basically, we saw that we can actually record this in both scripts. It can switch between Selenium or Sahi and it can record on any of the browsers that we want. We can also export this as a Sahi script or a Selenium script. This is actually the table format but we'll soon add support for the other format.
The next thing we'll do is a slightly more complicated example. We'll have a new test case. I will call it Data Driven and we'll start recording. We're recording through internet explorer again. This is a small website that we use for our training purposes. It basically shows a few books that are available in a shop and you just like specify the number of books you want of each one of those. You can add. It shows you a card and there it shows you the total amount that you need to pay. We will assert that the grand total is 1150 so we click on Check Points again and then press the Ctrl key and hover over this. It shows us that after assert we have like multiple assertions we will choose the assert equal that the total is 1150 and then add this. That’s added here and we'll hover over this. Now, let me save this. Now, I'm just going to play this back once to check that it's all working correctly. Actually, I forgot to stop the recording on the last one. I should have closed it up.
So now, the thing is we have hard coded values of 211 and 1150. We would sometimes like to drive it through data source. So there is the ability to actually open a CSV file there. We'll also add support for databases. So I'm opening a simple CSV file which has that data. There's like Java, Ruby, Python and these are the different books and the quantity of each one of them and the total along with that. So we want to verify that like for all these three rows in this particular CSV file and this test is run and verified. So what I'm going to do now is click on any of the Java rows and drag it over to line 5 drop it, drag Ruby over to line 6, and drag Python over to line 7, and then the total to line 9. So given the CSV file, we can actually just drag and drop it here so that the columns are correctly mapped. I'll save this.
Now, one other thing that you'll see is like once you have dragged these things whether you are in the Sahi mode or the Selenium mode, it's actually displays it correctly that has been parameterized. Now, let us go back there. There is a panel for Data Driven Testing where it specifies what CSV file needs to be used and right now we are choosing a random row to execute it, ok and lets execute it. Done. So you can see in the log it show you like what values I used. I used 211 and 1150. So let us run it again to see if it randomly picks another row. So I choose random row. That's 311 you can see that like there's 311 and then 1450.
Now, you could also have looked at it by adding a break point at this point. So we add a break point by double clicking on any line and we run it again. Now, you see that it has stopped at the foot line so we can accept now. Let us click and then we – lets do it one by one from 0 to 2 and then clicking on it and we'll verify that the value is 1150. So yeah, we can record and playback on IE and Firefox. Actually, you can do it on Chrome and Safari also. We can actually show the script as Sahi or Selenium script and not only that all the -- we can also like actually change any of these accessors at any point of time whenever you want to modify it. So if you feel like there are accessors which are better and in the sense that we don’t want to use user but actually want to use like document or login form, we could use that if you wanted. These values are always showed in the XML file that's like a data source of all the accessors that are available so that you can change them anytime you want. Yeah, that kind of summarizes like what the.
Frank Cohen: Narayan, that's a wonderful demo. Thank you very much. And I'll tell you, when I see this actually functioning I have an ear-to-ear grin going. Let's see from Daniel, he asks, "What does it mean to view tests running in HtmlUnit?" The purpose of TestMaker is to enable test to be repurposed, to be functional test, load test, or production monitors. When you're doing functional testing instantiating the real browser like Firefox or IE makes sense, but when you're doing load testing we found that it's better to operate the test using HtmlUnit as the headless web browser. We're able to instantiate a couple of hundred instances of HtmlUnit in a small machine whereas we could probably only get maybe three or four copies of Internet Explorer running in that same machine.
So when you're in a test, record/playback environment like the PushToTest Designer, we want to enable you to see what HtmlUnit is seeing your application doing. Since HtmlUnit is a headless browser we've now created essentially an HtmlUnit viewer so that at any time in your test scripts operation you can see what HtmlUnit's view of the application is.
Carla asked the question in, "Will a designer run with portable versions of Firefox and Chrome? Narayan, do you know the answer to that?
Frank Cohen: Yeah, they should. As far as I know they should because the only dependency that Sahi has is that you use a proxy of Sahi. That's it. So if we can actually change the proxy on those portable versions, it should just work.
Frank Cohen: Okay. Thank you. Michael asked the question, "Does the test case automatically close the browser?"
Narayan Raman: Yeah, it does in this case, but they can stop that from doing that.
Frank Cohen: Like setting an option, that kind of thing?
Narayan Raman: I mean it's technically possible. It depends on how the user interface is going to let people interact with it so based on the design, they can either close the browser or not close the browser.
Frank Cohen: Okay. So Michael, I'm taking it that you want an option to be able to set your test cases so that they'll automatically close a browser and I'll take that as something for us to enhance the user interface with.
Daniel asked the question, "Will exporting the Selenium 2.0 language is to be supported? How will these scripts be reusable bridging to reusable test each of these page objects?"
Let me try first and then you can go, Narayan.
Narayan Raman: Sure.
Frank Cohen: So we're currently targeting what Selenium IDE 1.0 or 1.x gives you. We're still unsure exactly about how selenium 2.0 will kind of play out, but we are actively involved with the Selenium 2.0 project. So it's probably too soon to tell like how this test will be supporting page objects. The way that we've architected the PushToTest Designer is to make it extensible so that we could support a bunch of different dialects and one of those dialects would certainly be Selenium 2.0 Page Objects.
Narayan, did you have any answer too?
Narayan Raman; Yes. The thing is whatever the Selenium IDE can do with the.. on Firefox right it's all JavaScript mostly except for some things. So it is like fairly reproducible by using the same locator strategy and the same code to get the UIE object implementation also on that. So we kind of think that if – whatever new that things will come up and the recorder technology of Selenium we should be able to replicate it here and because it kind of -- it's similar in the way things work.
Frank Cohen: Okay. That's good. Daniel is asking the question, "Are there fallback accessors like name = PTNG which may become obsolete but text = Google Search may be more stable. So the question is, are there a fallback accessors?
Narayan Raman: It's not available right now but it's possible because we actually have all the accessors available in the script. So with at least the TMID script the designer script has all the accessors so it may be possible to actually fall back on other accessors.
Frank Cohen: Okay. Daniel, I'd be interested if you want to send me an e-mail kind of describing how you'd like the fallback accessors to be established within a test or if they're just like an options panel or something like that. Just send me an e-mail. I'd be happy to consider it. Or even better, Daniel, if you want to take a look at the source code and approve it yourself, you're welcome to. All of this is under an open source license and it's currently published in our SVN repository.
Okay. Daniel asked the question, "How expressive are values from the data? For example, could I enter $Java+$Python for an assertion?" So he's wondering if we can do like compound strings. So I think I can answer that question. The values from the data are simple keyword search and replace strings. So you could enter $Java$Python and then the number 7 and then those would get replaced automatically by the literal values in the data file.
Narayan Raman: Yeah. Basically, if somebody wants to actually modify that value in some way concatenate anything to it like they can just do it because this is all.. there's going to be translated into simple either JavaScript or Java so it should be easily possible.
Frank Cohen: Right. Okay. So Adam asked the question, "What are the plans for third-party extensibility such as the Selenium IDE API?" Adam, considering you're the author of that, I would say that it's up to you. We'd love to have you participate in the project and to add the third-party extensibility APIs to the designer.
I think that there is probably two or three projects that would make this designer really an ideal tool for the Selenium IDE community. So I'd invite you to participate. And what you'll find, Adam, is that the way that we built this thing, 0:35:18 make it very easy for the third-party extensibility designed for Selenium IDE to work.
So Carla asked the question -- well, she said, "Very nice. I like the multiple browsers and the data feature." Thank you, Carla.
Let's see. Tarum asked the question, "Has PushToTest overcome any of Selenium weaknesses like dealing with JavaScript alerts, file uploads in IE, and other non-Firefox browsers?" There are plenty of entries that Selenium IDE has -- or not Selenium IDE but just Selenium in general, but some of them are kind of more overblown than others. For example, I have myself been stopped from writing a Selenium script that deals with JavaScript alerts. There is plenty of command support within the selenium language for alerts. File uploads and IE and the other non-Firefox browsers, they're published ways of kind of working around those upload issues.
Narayan, does Sahi work with file uploads and IE and the other non-Firefox browsers?
Narayan Raman: Sahi does it through the topics 11.8961when you actually say that you want to set the file for a form submit the file is read by the proxy and sent across, instead of the browser doing it. So the end server actually sees it as if -- and the request contained the file but the browser will not know that the file was added. If there are Java Scripts check around the file upload and then it takes a little more like tricker to actually get it working but if it's just a regular plain file upload, it works fine out of the box.
Frank Cohen: Okay. That's great. I don’t mean to say that there aren’t issues in Selenium term but it seems like most of them, the big ones have been kind of solved already or worked around.
So Michael asked the question, "Is the log window the only 'log'? Can the logs be saved to a file or database maybe to a web window in like HTML form?" So when you're playing back this test in the PushToTest Designer, the log panel that you see is the only log. But when you run the test in the TestMaker TestNode environment then the TestNode can log to a relational database, to local file, to an XML file, or you can add in your own custom loggers too. We don’t have this ability to like log to a web page like an HTML format of page, but when you run the test in TestMaker in the TestNode then the results analysis engine that's built in a TestMaker can give you an HTML report of any of the results.
Narayan, did you want to add anything to that?
Narayan Raman: No, I'm fine.
Frank Cohen: Okay. Great. So let's see. Carla asked the question, "If this access a proxy, how do you use your own proxy settings like if you're behind a corporate network?"
Narayan, do you want to answer that?
Narayan Raman: Yes. So basically, you can configure Sahi to use your corporate proxy so you can change the proxies. Sahi works with all corporate proxies. You can now even use authentication that is needed with proxies. It can do Windows authentication. It can do NTML authentication. So it works with any proxy that you need.
Frank Cohen: So overall what we're shooting for is a Test Object Designer that has the following features. We showed being able to record and playback in Internet Explorer and Safari. But this also works just fine on a Macintosh system using Safari or the Windows version of Safari. We've got the Integrated Data Editor which right now reads from CSV files that will shortly also read from relational databases so you can make like a SQL query to and a data source and then use that data within the test. The goal of the designer is to create reusable test objects and those objects can then be orchestrated into a test use case using the TestMaker Editor. And let's see, we have user transaction definition so that you can do kind of user specific logging of any of the steps within the test. What we haven't shown yet because it isn’t working yet is the ability to record and playback Flex and Flash unit test.
What we're planning to do is to use the Adobe Flex Automation UI APIs to be able to record a Flex test script and then you can play it back in the TestMaker Designer environment. The designer environment will bring up essentially a Flex running component. It's kind of like a mini-browser and it will play back the test. By doing that then you'll be able to play back these tests as functional test, load test, or service monitors. We're also working with the HtmlUnit team to do a visual playback so that you'd be able to see your test operate in the -- I guess you'll have kind of a graphical view of what HtmlUnit is viewing, your application doing and that will be available in the coming weeks. Of course, we have a standard reporting logging schema and also a schema published for the native file format for the output of the designer. The TestScenario support being able to do multiple test use cases is coming shortly as we enhance the TestMaker Editor. And then we're also going to be doing things like adding Cascading Style Sheet Selector Support.
The way that this is going to play out in terms of being available as an open source project is that we'll be pursuing a hybrid pricing model. So the source code for all of this will be licensed under a GPL v2 license and the cost for using this source code if you're going to build it yourself from the source is free. The Selenium team really objects to the GPL. They would much rather have us use the Apache license which is in line with what the Selenium project current uses. And so I would imagine that there's going to be some negotiation going on if I can convince the Selenium team members to adopt this designer as the next generation of the Selenium IDE tool. If so it might be that the TestMaker Object Designer would be in Apache license and the rest of TestMaker would be under GPL version too. I tell you my biggest concern is that company like HP or IBM would use an Apache license TestMaker to create a competitor to us and they are literally doing billions of dollars of sales of their tools. I'd rather them invest their own money and create their own designer rather than having us assist them.
We also make two versions of the TestMaker product available. TestMaker community is licensed under a commercial license but it is free to use up to 50 users, 50 virtual users in a load test. TestMaker Enterprise is our commercial product. It's in use now at Pepsi Co., Ford, Deloitte, about 25 large organizations and we provide all sorts of service and support and enhancements and features that you don’t get in the community version. The cost for that depends on how many virtual users are in a load test, how many service monitors you might be running, but an average is between $30,000 and $50,000 per year on a subscription.
We have information at the pushtotest.com website, of course. You can download TestMaker from pushtotest.com and like I said you've got your choice of free to a support agreement. What we'd also ask you to do is to post your feedback and comments and ideas and criticisms to this URL here in our forums. We'd also encourage you to attend the open Source Test Workshop. This is a free webinar that's -- it's live and at the Open Source Test Workshop it's basically meant for managers, developers, testers to get together to share ideas and best practices on testing and it shows off demonstrations of all of the open source test tools that I follow and that PushToTest follows. If any of this peaks your curiosity enough to ask for price proposal in terms of licenses, training, support, and consulting then I'd ask you to contact Troy Amyett. Troy is our director of sales. He is based in our Austin, Texas sales office. He can be reached at 512-750-8769. His e-mail address is troy@pushtotest.
I'd like to thank everybody for their participation in today's briefing. We're going to organize another one of these briefings for august where we'll show you kind of the latest technology that we've added to the designer and also state probably what the release schedule is going to look like in much more detail.
Thank you very much for the demonstration. And I'd also like to thank Venky for his support and all the hard work for the last couple of weeks to get us to this briefing. So thank you guys both for your great support.
Narayan Raman: That's fine.
Frank Cohen: Okay. Well, that's about it. And thank you, everybody, for participating in the briefing. So long.



